Home | History | Annotate | Download | only in compat
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 package com.android.tts.compat;
     17 
     18 import android.database.Cursor;
     19 import android.net.Uri;
     20 import android.speech.tts.SynthesisCallback;
     21 import android.speech.tts.SynthesisRequest;
     22 import android.speech.tts.TextToSpeech;
     23 import android.speech.tts.TextToSpeechService;
     24 import android.util.Log;
     25 
     26 import java.io.File;
     27 
     28 public abstract class CompatTtsService extends TextToSpeechService {
     29 
     30     private static final boolean DBG = false;
     31     private static final String TAG = "CompatTtsService";
     32 
     33     private SynthProxy mNativeSynth = null;
     34 
     35     protected abstract String getSoFilename();
     36 
     37     @Override
     38     public void onCreate() {
     39         if (DBG) Log.d(TAG, "onCreate()");
     40         super.onCreate();
     41 
     42         String soFilename = getSoFilename();
     43 
     44         File f = new File(soFilename);
     45         if (!f.exists()) {
     46             Log.e(TAG, "Invalid TTS Binary: " + soFilename);
     47             return;
     48         }
     49 
     50         if (mNativeSynth != null) {
     51             mNativeSynth.stopSync();
     52             mNativeSynth.shutdown();
     53             mNativeSynth = null;
     54         }
     55 
     56         // Load the engineConfig from the plugin if it has any special configuration
     57         // to be loaded. By convention, if an engine wants the TTS framework to pass
     58         // in any configuration, it must put it into its content provider which has the URI:
     59         // content://<packageName>.providers.SettingsProvider
     60         // That content provider must provide a Cursor which returns the String that
     61         // is to be passed back to the native .so file for the plugin when getString(0) is
     62         // called on it.
     63         // Note that the TTS framework does not care what this String data is: it is something
     64         // that comes from the engine plugin and is consumed only by the engine plugin itself.
     65         String engineConfig = "";
     66         Cursor c = getContentResolver().query(Uri.parse("content://" + getPackageName()
     67                 + ".providers.SettingsProvider"), null, null, null, null);
     68         if (c != null){
     69             c.moveToFirst();
     70             engineConfig = c.getString(0);
     71             c.close();
     72         }
     73         mNativeSynth = new SynthProxy(soFilename, engineConfig);
     74     }
     75 
     76     @Override
     77     public void onDestroy() {
     78         if (DBG) Log.d(TAG, "onDestroy()");
     79         super.onDestroy();
     80 
     81         if (mNativeSynth != null) {
     82             mNativeSynth.shutdown();
     83         }
     84         mNativeSynth = null;
     85     }
     86 
     87     @Override
     88     protected String[] onGetLanguage() {
     89         if (mNativeSynth == null) return null;
     90         return mNativeSynth.getLanguage();
     91     }
     92 
     93     @Override
     94     protected int onIsLanguageAvailable(String lang, String country, String variant) {
     95         if (DBG) Log.d(TAG, "onIsLanguageAvailable(" + lang + "," + country + "," + variant + ")");
     96         if (mNativeSynth == null) return TextToSpeech.ERROR;
     97         return mNativeSynth.isLanguageAvailable(lang, country, variant);
     98     }
     99 
    100     @Override
    101     protected int onLoadLanguage(String lang, String country, String variant) {
    102         if (DBG) Log.d(TAG, "onLoadLanguage(" + lang + "," + country + "," + variant + ")");
    103         int result = onIsLanguageAvailable(lang, country, variant);
    104         // TODO: actually load language
    105         return result;
    106     }
    107 
    108     @Override
    109     protected void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback) {
    110         if (mNativeSynth == null) {
    111             callback.error();
    112             return;
    113         }
    114 
    115         // Set language
    116         String lang = request.getLanguage();
    117         String country = request.getCountry();
    118         String variant = request.getVariant();
    119         if (mNativeSynth.setLanguage(lang, country, variant) != TextToSpeech.SUCCESS) {
    120             Log.e(TAG, "setLanguage(" + lang + "," + country + "," + variant + ") failed");
    121             callback.error();
    122             return;
    123         }
    124 
    125         // Set speech rate
    126         int speechRate = request.getSpeechRate();
    127         if (mNativeSynth.setSpeechRate(speechRate) != TextToSpeech.SUCCESS) {
    128             Log.e(TAG, "setSpeechRate(" + speechRate + ") failed");
    129             callback.error();
    130             return;
    131         }
    132 
    133         // Set speech
    134         int pitch = request.getPitch();
    135         if (mNativeSynth.setPitch(pitch) != TextToSpeech.SUCCESS) {
    136             Log.e(TAG, "setPitch(" + pitch + ") failed");
    137             callback.error();
    138             return;
    139         }
    140 
    141         // Synthesize
    142         if (mNativeSynth.speak(request, callback) != TextToSpeech.SUCCESS) {
    143             callback.error();
    144             return;
    145         }
    146     }
    147 
    148     @Override
    149     protected void onStop() {
    150         if (DBG) Log.d(TAG, "onStop()");
    151         if (mNativeSynth == null) return;
    152         mNativeSynth.stop();
    153     }
    154 
    155 }
    156