Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 067a21b2 authored by Przemyslaw Szczepaniak's avatar Przemyslaw Szczepaniak
Browse files

TTS Connection callbacks are called on main thread.

After experimenting with the new TTS API I found out that receiving
ConnectionCallbacks#onEngineStatusChange and #onServiceDisconnected
callbacks on non-main thread are problematic. They are very rare and
overhead of dealing with them in separate thread is high - in most
cases user just wants to process those callbacks in the main thread
context. This change should make new API usage easier.

+ Fixed default values of speech speed in voices from v1->v2 wrapper.

Change-Id: I76d3b607b3b931b7eb10aa180775fd3607c43bd9
parent 574ed553
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -25,7 +25,10 @@ import android.content.ServiceConnection;
import android.media.AudioManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.speech.tts.ITextToSpeechCallback;
@@ -86,6 +89,8 @@ public class TextToSpeechClient {
    private HashMap<String, Pair<UtteranceId, RequestCallbacks>> mCallbacks;
    // Guarded by mLock

    private InternalHandler mMainHandler = new InternalHandler();

    /** Common voices parameters */
    public static final class Params {
        private Params() {}
@@ -300,6 +305,8 @@ public class TextToSpeechClient {
    /**
     * Interface definition of callbacks that are called when the client is
     * connected or disconnected from the TTS service.
     *
     * The callbacks specified in this method will be called on the UI thread.
     */
    public static interface ConnectionCallbacks {
        /**
@@ -325,6 +332,9 @@ public class TextToSpeechClient {
         * with the speech service (e.g. a crash or resource problem causes it to be killed by the
         * system). When called, all requests have been canceled and no outstanding listeners will
         * be executed. Applications should disable UI components that require the service.
         *
         * When the service is working again, the client will receive a callback to the
         * {@link #onConnectionSuccess()} method.
         */
        public void onServiceDisconnected();

@@ -688,7 +698,8 @@ public class TextToSpeechClient {
                synchronized (mLock) {
                    mEngineStatus = new EngineStatus(mServiceConnection.getEngineName(),
                            voicesInfo);
                    mConnectionCallbacks.onEngineStatusChange(mEngineStatus);
                    mMainHandler.obtainMessage(InternalHandler.WHAT_ENGINE_STATUS_CHANGED,
                            mEngineStatus).sendToTarget();
                }
            }
        };
@@ -753,9 +764,11 @@ public class TextToSpeechClient {
            Log.i(TAG, "Asked to disconnect from " + name);

            synchronized(mLock) {
                mEstablished = false;
                mService = null;
                stopSetupConnectionTask();
            }
            mConnectionCallbacks.onServiceDisconnected();
            mMainHandler.obtainMessage(InternalHandler.WHAT_SERVICE_DISCONNECTED).sendToTarget();
        }

        private void startSetupConnectionTask(ComponentName name) {
@@ -830,9 +843,11 @@ public class TextToSpeechClient {
    private boolean runAction(Action action) {
        synchronized (mLock) {
            if (mServiceConnection == null) {
                Log.w(TAG, action.getName() + " failed: not bound to TTS engine");
                return false;
            }
            if (!mServiceConnection.isEstablished()) {
                Log.w(TAG, action.getName() + " failed: not fully bound to TTS engine");
                return false;
            }
            mServiceConnection.runAction(action);
@@ -1044,4 +1059,21 @@ public class TextToSpeechClient {
            }
        });
    }

    class InternalHandler extends Handler {
        final static int WHAT_ENGINE_STATUS_CHANGED = 1;
        final static int WHAT_SERVICE_DISCONNECTED = 2;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WHAT_ENGINE_STATUS_CHANGED:
                    mConnectionCallbacks.onEngineStatusChange((EngineStatus) msg.obj);
                    return;
                case WHAT_SERVICE_DISCONNECTED:
                    mConnectionCallbacks.onServiceDisconnected();
                    return;
            }
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -255,7 +255,8 @@ public abstract class TextToSpeechService extends Service {
        // V2 to V1 interface adapter. This allows using V2 client interface on V1-only services.
        Bundle defaultParams = new Bundle();
        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_PITCH, 1.0f);
        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED, -1.0f);
        // Speech speed <= 0 makes it use a system wide setting
        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED, 0.0f);

        // Enumerate all locales and check if they are available
        ArrayList<VoiceInfo> voicesInfo = new ArrayList<VoiceInfo>();