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

Commit 764e05dd authored by Joshua Imbriani's avatar Joshua Imbriani Committed by Android (Google) Code Review
Browse files

Merge "Fixing TTS Settings crash on rotation caused by using deprecated API."

parents 2d7264eb e77e22e2
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.util.Log;
import android.util.Pair;

import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProviders;
import androidx.preference.ListPreference;
import androidx.preference.Preference;

@@ -205,13 +206,18 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
            mLocalePreference.setEnabled(entries.length > 0);
        }

        mTts = new TextToSpeech(getActivity().getApplicationContext(), mInitListener);
        final TextToSpeechViewModel ttsViewModel =
                ViewModelProviders.of(this).get(TextToSpeechViewModel.class);
        Pair<TextToSpeech, Boolean> ttsAndNew = ttsViewModel.getTtsAndWhetherNew(mInitListener);
        mTts = ttsAndNew.first;
        // If the TTS object is not newly created, we need to run the setup on the settings side to
        // ensure that we can use the TTS object.
        if (!ttsAndNew.second) {
            successSetup();
        }

        setTtsUtteranceProgressListener();
        initSettings();

        // Prevent restarting the TTS connection on rotation
        setRetainInstance(true);
    }

    @Override
@@ -227,13 +233,21 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
            return;
        }
        if (!mTts.getDefaultEngine().equals(mTts.getCurrentEngine())) {
            final TextToSpeechViewModel ttsViewModel =
                    ViewModelProviders.of(this).get(TextToSpeechViewModel.class);
            try {
                mTts.shutdown();
                mTts = null;
                // If the current engine isn't the default engine shut down the current engine in
                // preparation for creating the new engine.
                ttsViewModel.shutdownTts();
            } catch (Exception e) {
                Log.e(TAG, "Error shutting down TTS engine" + e);
            }
            mTts = new TextToSpeech(getActivity().getApplicationContext(), mInitListener);
            final Pair<TextToSpeech, Boolean> ttsAndNew =
                    ttsViewModel.getTtsAndWhetherNew(mInitListener);
            mTts = ttsAndNew.first;
            if (!ttsAndNew.second) {
                successSetup();
            }
            setTtsUtteranceProgressListener();
            initSettings();
        } else {
@@ -276,15 +290,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mTts != null) {
            mTts.shutdown();
            mTts = null;
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
@@ -375,8 +380,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
    public void onInitEngine(int status) {
        if (status == TextToSpeech.SUCCESS) {
            if (DBG) Log.d(TAG, "TTS engine for settings screen initialized.");
            checkDefaultLocale();
            getActivity().runOnUiThread(() -> mLocalePreference.setEnabled(true));
            successSetup();
        } else {
            if (DBG) {
                Log.d(TAG,
@@ -386,6 +390,12 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment
        }
    }

    /** Initialize TTS Settings on successful engine init. */
    private void successSetup() {
        checkDefaultLocale();
        getActivity().runOnUiThread(() -> mLocalePreference.setEnabled(true));
    }

    private void checkDefaultLocale() {
        Locale defaultLocale = mTts.getDefaultLanguage();
        if (defaultLocale == null) {
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.settings.tts;

import android.app.Application;
import android.speech.tts.TextToSpeech;
import android.util.Pair;

import androidx.lifecycle.AndroidViewModel;

/**
 * A helper view model to protect the TTS object from being destroyed and
 * recreated on orientation change.
*/
public class TextToSpeechViewModel extends AndroidViewModel {
    private TextToSpeech mTts;

    // Save the application so we can use it as the TTS context
    private final Application mApplication;

    public TextToSpeechViewModel(Application application) {
        super(application);

        mApplication = application;
    }

    /*
     * Since the view model now controls the TTS object, we need to handle shutting it down
     * ourselves.
     */
    @Override
    protected void onCleared() {
        shutdownTts();
    }

    protected void shutdownTts() {
        mTts.shutdown();
        mTts = null;
    }

    /*
     * An accessor method to get the TTS object. Returns a pair of the TTS object and a boolean
     * indicating whether the TTS object was newly created or not.
     */
    protected Pair<TextToSpeech, Boolean> getTtsAndWhetherNew(
            TextToSpeech.OnInitListener listener) {
        boolean ttsCreated = false;
        if (mTts == null) {
            mTts = new TextToSpeech(this.mApplication, listener);
            ttsCreated = true;
        }

        return Pair.create(mTts, ttsCreated);
    }

}