Home | History | Annotate | Download | only in speech
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/speech/tts_android.h"
      6 
      7 #include <string>
      8 
      9 #include "base/android/jni_string.h"
     10 #include "base/memory/singleton.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/browser/speech/tts_controller.h"
     13 #include "jni/TtsPlatformImpl_jni.h"
     14 
     15 using base::android::AttachCurrentThread;
     16 
     17 // static
     18 TtsPlatformImpl* TtsPlatformImpl::GetInstance() {
     19   return TtsPlatformImplAndroid::GetInstance();
     20 }
     21 
     22 TtsPlatformImplAndroid::TtsPlatformImplAndroid()
     23     : utterance_id_(0) {
     24   JNIEnv* env = AttachCurrentThread();
     25   java_ref_.Reset(
     26       Java_TtsPlatformImpl_create(env,
     27                                   reinterpret_cast<jint>(this),
     28                                   base::android::GetApplicationContext()));
     29 }
     30 
     31 TtsPlatformImplAndroid::~TtsPlatformImplAndroid() {
     32   JNIEnv* env = AttachCurrentThread();
     33   Java_TtsPlatformImpl_destroy(env, java_ref_.obj());
     34 }
     35 
     36 bool TtsPlatformImplAndroid::PlatformImplAvailable() {
     37   return true;
     38 }
     39 
     40 bool TtsPlatformImplAndroid::Speak(
     41     int utterance_id,
     42     const std::string& utterance,
     43     const std::string& lang,
     44     const VoiceData& voice,
     45     const UtteranceContinuousParameters& params) {
     46   JNIEnv* env = AttachCurrentThread();
     47   if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_.obj()))
     48     return false;
     49 
     50   jboolean success = Java_TtsPlatformImpl_speak(
     51       env, java_ref_.obj(),
     52       utterance_id,
     53       base::android::ConvertUTF8ToJavaString(env, utterance).Release(),
     54       base::android::ConvertUTF8ToJavaString(env, lang).Release(),
     55       params.rate, params.pitch, params.volume);
     56   if (!success)
     57     return false;
     58 
     59   utterance_ = utterance;
     60   utterance_id_ = utterance_id;
     61   return true;
     62 }
     63 
     64 bool TtsPlatformImplAndroid::StopSpeaking() {
     65   JNIEnv* env = AttachCurrentThread();
     66   Java_TtsPlatformImpl_stop(env, java_ref_.obj());
     67   utterance_id_ = 0;
     68   utterance_.clear();
     69   return true;
     70 }
     71 
     72 void TtsPlatformImplAndroid::Pause() {
     73   StopSpeaking();
     74 }
     75 
     76 void TtsPlatformImplAndroid::Resume() {
     77 }
     78 
     79 bool TtsPlatformImplAndroid::IsSpeaking() {
     80   return (utterance_id_ != 0);
     81 }
     82 
     83 void TtsPlatformImplAndroid::GetVoices(
     84     std::vector<VoiceData>* out_voices) {
     85   JNIEnv* env = AttachCurrentThread();
     86   if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_.obj()))
     87     return;
     88 
     89   int count = Java_TtsPlatformImpl_getVoiceCount(env, java_ref_.obj());
     90   for (int i = 0; i < count; ++i) {
     91     out_voices->push_back(VoiceData());
     92     VoiceData& data = out_voices->back();
     93     data.native = true;
     94     data.name = base::android::ConvertJavaStringToUTF8(
     95         Java_TtsPlatformImpl_getVoiceName(env, java_ref_.obj(), i));
     96     data.lang = base::android::ConvertJavaStringToUTF8(
     97         Java_TtsPlatformImpl_getVoiceLanguage(env, java_ref_.obj(), i));
     98     data.gender = TTS_GENDER_NONE;
     99     data.events.insert(TTS_EVENT_START);
    100     data.events.insert(TTS_EVENT_END);
    101     data.events.insert(TTS_EVENT_ERROR);
    102   }
    103 }
    104 
    105 void TtsPlatformImplAndroid::VoicesChanged(JNIEnv* env, jobject obj) {
    106   TtsController::GetInstance()->VoicesChanged();
    107 }
    108 
    109 void TtsPlatformImplAndroid::OnEndEvent(
    110     JNIEnv* env, jobject obj, jint utterance_id) {
    111   SendFinalTtsEvent(utterance_id, TTS_EVENT_END,
    112                     static_cast<int>(utterance_.size()));
    113 }
    114 
    115 void TtsPlatformImplAndroid::OnErrorEvent(
    116     JNIEnv* env, jobject obj, jint utterance_id) {
    117   SendFinalTtsEvent(utterance_id, TTS_EVENT_ERROR, 0);
    118 }
    119 
    120 void TtsPlatformImplAndroid::OnStartEvent(
    121     JNIEnv* env, jobject obj, jint utterance_id) {
    122   if (utterance_id != utterance_id_)
    123     return;
    124 
    125   TtsController::GetInstance()->OnTtsEvent(
    126       utterance_id_, TTS_EVENT_START, 0, std::string());
    127 }
    128 
    129 void TtsPlatformImplAndroid::SendFinalTtsEvent(
    130     int utterance_id, TtsEventType event_type, int char_index) {
    131   if (utterance_id != utterance_id_)
    132     return;
    133 
    134   TtsController::GetInstance()->OnTtsEvent(
    135       utterance_id_, event_type, char_index, std::string());
    136   utterance_id_ = 0;
    137   utterance_.clear();
    138 }
    139 
    140 // static
    141 TtsPlatformImplAndroid* TtsPlatformImplAndroid::GetInstance() {
    142   return Singleton<TtsPlatformImplAndroid>::get();
    143 }
    144 
    145 // static
    146 bool TtsPlatformImplAndroid::Register(JNIEnv* env) {
    147   return RegisterNativesImpl(env);
    148 }
    149