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<intptr_t>(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 jboolean success = Java_TtsPlatformImpl_speak( 48 env, java_ref_.obj(), 49 utterance_id, 50 base::android::ConvertUTF8ToJavaString(env, utterance).Release(), 51 base::android::ConvertUTF8ToJavaString(env, lang).Release(), 52 params.rate, params.pitch, params.volume); 53 if (!success) 54 return false; 55 56 utterance_ = utterance; 57 utterance_id_ = utterance_id; 58 return true; 59 } 60 61 bool TtsPlatformImplAndroid::StopSpeaking() { 62 JNIEnv* env = AttachCurrentThread(); 63 Java_TtsPlatformImpl_stop(env, java_ref_.obj()); 64 utterance_id_ = 0; 65 utterance_.clear(); 66 return true; 67 } 68 69 void TtsPlatformImplAndroid::Pause() { 70 StopSpeaking(); 71 } 72 73 void TtsPlatformImplAndroid::Resume() { 74 } 75 76 bool TtsPlatformImplAndroid::IsSpeaking() { 77 return (utterance_id_ != 0); 78 } 79 80 void TtsPlatformImplAndroid::GetVoices( 81 std::vector<VoiceData>* out_voices) { 82 JNIEnv* env = AttachCurrentThread(); 83 if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_.obj())) 84 return; 85 86 int count = Java_TtsPlatformImpl_getVoiceCount(env, java_ref_.obj()); 87 for (int i = 0; i < count; ++i) { 88 out_voices->push_back(VoiceData()); 89 VoiceData& data = out_voices->back(); 90 data.native = true; 91 data.name = base::android::ConvertJavaStringToUTF8( 92 Java_TtsPlatformImpl_getVoiceName(env, java_ref_.obj(), i)); 93 data.lang = base::android::ConvertJavaStringToUTF8( 94 Java_TtsPlatformImpl_getVoiceLanguage(env, java_ref_.obj(), i)); 95 data.gender = TTS_GENDER_NONE; 96 data.events.insert(TTS_EVENT_START); 97 data.events.insert(TTS_EVENT_END); 98 data.events.insert(TTS_EVENT_ERROR); 99 } 100 } 101 102 void TtsPlatformImplAndroid::VoicesChanged(JNIEnv* env, jobject obj) { 103 TtsController::GetInstance()->VoicesChanged(); 104 } 105 106 void TtsPlatformImplAndroid::OnEndEvent( 107 JNIEnv* env, jobject obj, jint utterance_id) { 108 SendFinalTtsEvent(utterance_id, TTS_EVENT_END, 109 static_cast<int>(utterance_.size())); 110 } 111 112 void TtsPlatformImplAndroid::OnErrorEvent( 113 JNIEnv* env, jobject obj, jint utterance_id) { 114 SendFinalTtsEvent(utterance_id, TTS_EVENT_ERROR, 0); 115 } 116 117 void TtsPlatformImplAndroid::OnStartEvent( 118 JNIEnv* env, jobject obj, jint utterance_id) { 119 if (utterance_id != utterance_id_) 120 return; 121 122 TtsController::GetInstance()->OnTtsEvent( 123 utterance_id_, TTS_EVENT_START, 0, std::string()); 124 } 125 126 void TtsPlatformImplAndroid::SendFinalTtsEvent( 127 int utterance_id, TtsEventType event_type, int char_index) { 128 if (utterance_id != utterance_id_) 129 return; 130 131 TtsController::GetInstance()->OnTtsEvent( 132 utterance_id_, event_type, char_index, std::string()); 133 utterance_id_ = 0; 134 utterance_.clear(); 135 } 136 137 // static 138 TtsPlatformImplAndroid* TtsPlatformImplAndroid::GetInstance() { 139 return Singleton<TtsPlatformImplAndroid>::get(); 140 } 141 142 // static 143 bool TtsPlatformImplAndroid::Register(JNIEnv* env) { 144 return RegisterNativesImpl(env); 145 } 146