blob: af65ba411ce37da6484c2a7123ccdcc06159339f [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.tts.compat;
import android.database.Cursor;
import android.net.Uri;
import android.speech.tts.SynthesisCallback;
import android.speech.tts.SynthesisRequest;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeechService;
import android.util.Log;
import java.io.File;
public abstract class CompatTtsService extends TextToSpeechService {
private static final boolean DBG = false;
private static final String TAG = "CompatTtsService";
private SynthProxy mNativeSynth = null;
protected abstract String getSoFilename();
@Override
public void onCreate() {
if (DBG) Log.d(TAG, "onCreate()");
super.onCreate();
String soFilename = getSoFilename();
File f = new File(soFilename);
if (!f.exists()) {
Log.e(TAG, "Invalid TTS Binary: " + soFilename);
return;
}
if (mNativeSynth != null) {
mNativeSynth.stopSync();
mNativeSynth.shutdown();
mNativeSynth = null;
}
// Load the engineConfig from the plugin if it has any special configuration
// to be loaded. By convention, if an engine wants the TTS framework to pass
// in any configuration, it must put it into its content provider which has the URI:
// content://<packageName>.providers.SettingsProvider
// That content provider must provide a Cursor which returns the String that
// is to be passed back to the native .so file for the plugin when getString(0) is
// called on it.
// Note that the TTS framework does not care what this String data is: it is something
// that comes from the engine plugin and is consumed only by the engine plugin itself.
String engineConfig = "";
Cursor c = getContentResolver().query(Uri.parse("content://" + getPackageName()
+ ".providers.SettingsProvider"), null, null, null, null);
if (c != null){
c.moveToFirst();
engineConfig = c.getString(0);
c.close();
}
mNativeSynth = new SynthProxy(soFilename, engineConfig);
}
@Override
public void onDestroy() {
if (DBG) Log.d(TAG, "onDestroy()");
super.onDestroy();
if (mNativeSynth != null) {
mNativeSynth.shutdown();
}
mNativeSynth = null;
}
@Override
protected String[] onGetLanguage() {
if (mNativeSynth == null) return null;
return mNativeSynth.getLanguage();
}
@Override
protected int onIsLanguageAvailable(String lang, String country, String variant) {
if (DBG) Log.d(TAG, "onIsLanguageAvailable(" + lang + "," + country + "," + variant + ")");
if (mNativeSynth == null) return TextToSpeech.ERROR;
return mNativeSynth.isLanguageAvailable(lang, country, variant);
}
@Override
protected int onLoadLanguage(String lang, String country, String variant) {
if (DBG) Log.d(TAG, "onLoadLanguage(" + lang + "," + country + "," + variant + ")");
int result = onIsLanguageAvailable(lang, country, variant);
// TODO: actually load language
return result;
}
@Override
protected void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback) {
if (mNativeSynth == null) {
callback.error();
return;
}
// Set language
String lang = request.getLanguage();
String country = request.getCountry();
String variant = request.getVariant();
if (mNativeSynth.setLanguage(lang, country, variant) != TextToSpeech.SUCCESS) {
Log.e(TAG, "setLanguage(" + lang + "," + country + "," + variant + ") failed");
callback.error();
return;
}
// Set speech rate
int speechRate = request.getSpeechRate();
if (mNativeSynth.setSpeechRate(speechRate) != TextToSpeech.SUCCESS) {
Log.e(TAG, "setSpeechRate(" + speechRate + ") failed");
callback.error();
return;
}
// Set speech
int pitch = request.getPitch();
if (mNativeSynth.setPitch(pitch) != TextToSpeech.SUCCESS) {
Log.e(TAG, "setPitch(" + pitch + ") failed");
callback.error();
return;
}
// Synthesize
if (mNativeSynth.speak(request, callback) != TextToSpeech.SUCCESS) {
callback.error();
return;
}
}
@Override
protected void onStop() {
if (DBG) Log.d(TAG, "onStop()");
if (mNativeSynth == null) return;
mNativeSynth.stop();
}
}