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<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,
    140                    LeakySingletonTraits<TtsPlatformImplAndroid> >::get();
    141 }
    142 
    143 // static
    144 bool TtsPlatformImplAndroid::Register(JNIEnv* env) {
    145   return RegisterNativesImpl(env);
    146 }
    147