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