// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/speech/tts_android.h" #include <string> #include "base/android/jni_string.h" #include "base/memory/singleton.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/speech/tts_controller.h" #include "jni/TtsPlatformImpl_jni.h" using base::android::AttachCurrentThread; // static TtsPlatformImpl* TtsPlatformImpl::GetInstance() { return TtsPlatformImplAndroid::GetInstance(); } TtsPlatformImplAndroid::TtsPlatformImplAndroid() : utterance_id_(0) { JNIEnv* env = AttachCurrentThread(); java_ref_.Reset( Java_TtsPlatformImpl_create(env, reinterpret_cast<intptr_t>(this), base::android::GetApplicationContext())); } TtsPlatformImplAndroid::~TtsPlatformImplAndroid() { JNIEnv* env = AttachCurrentThread(); Java_TtsPlatformImpl_destroy(env, java_ref_.obj()); } bool TtsPlatformImplAndroid::PlatformImplAvailable() { return true; } bool TtsPlatformImplAndroid::Speak( int utterance_id, const std::string& utterance, const std::string& lang, const VoiceData& voice, const UtteranceContinuousParameters& params) { JNIEnv* env = AttachCurrentThread(); if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_.obj())) return false; jboolean success = Java_TtsPlatformImpl_speak( env, java_ref_.obj(), utterance_id, base::android::ConvertUTF8ToJavaString(env, utterance).Release(), base::android::ConvertUTF8ToJavaString(env, lang).Release(), params.rate, params.pitch, params.volume); if (!success) return false; utterance_ = utterance; utterance_id_ = utterance_id; return true; } bool TtsPlatformImplAndroid::StopSpeaking() { JNIEnv* env = AttachCurrentThread(); Java_TtsPlatformImpl_stop(env, java_ref_.obj()); utterance_id_ = 0; utterance_.clear(); return true; } void TtsPlatformImplAndroid::Pause() { StopSpeaking(); } void TtsPlatformImplAndroid::Resume() { } bool TtsPlatformImplAndroid::IsSpeaking() { return (utterance_id_ != 0); } void TtsPlatformImplAndroid::GetVoices( std::vector<VoiceData>* out_voices) { JNIEnv* env = AttachCurrentThread(); if (!Java_TtsPlatformImpl_isInitialized(env, java_ref_.obj())) return; int count = Java_TtsPlatformImpl_getVoiceCount(env, java_ref_.obj()); for (int i = 0; i < count; ++i) { out_voices->push_back(VoiceData()); VoiceData& data = out_voices->back(); data.native = true; data.name = base::android::ConvertJavaStringToUTF8( Java_TtsPlatformImpl_getVoiceName(env, java_ref_.obj(), i)); data.lang = base::android::ConvertJavaStringToUTF8( Java_TtsPlatformImpl_getVoiceLanguage(env, java_ref_.obj(), i)); data.gender = TTS_GENDER_NONE; data.events.insert(TTS_EVENT_START); data.events.insert(TTS_EVENT_END); data.events.insert(TTS_EVENT_ERROR); } } void TtsPlatformImplAndroid::VoicesChanged(JNIEnv* env, jobject obj) { TtsController::GetInstance()->VoicesChanged(); } void TtsPlatformImplAndroid::OnEndEvent( JNIEnv* env, jobject obj, jint utterance_id) { SendFinalTtsEvent(utterance_id, TTS_EVENT_END, static_cast<int>(utterance_.size())); } void TtsPlatformImplAndroid::OnErrorEvent( JNIEnv* env, jobject obj, jint utterance_id) { SendFinalTtsEvent(utterance_id, TTS_EVENT_ERROR, 0); } void TtsPlatformImplAndroid::OnStartEvent( JNIEnv* env, jobject obj, jint utterance_id) { if (utterance_id != utterance_id_) return; TtsController::GetInstance()->OnTtsEvent( utterance_id_, TTS_EVENT_START, 0, std::string()); } void TtsPlatformImplAndroid::SendFinalTtsEvent( int utterance_id, TtsEventType event_type, int char_index) { if (utterance_id != utterance_id_) return; TtsController::GetInstance()->OnTtsEvent( utterance_id_, event_type, char_index, std::string()); utterance_id_ = 0; utterance_.clear(); } // static TtsPlatformImplAndroid* TtsPlatformImplAndroid::GetInstance() { return Singleton<TtsPlatformImplAndroid>::get(); } // static bool TtsPlatformImplAndroid::Register(JNIEnv* env) { return RegisterNativesImpl(env); }