Loading src/com/android/settings/tts/TextToSpeechSettings.java +28 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 { Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -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) { Loading src/com/android/settings/tts/TextToSpeechViewModel.java 0 → 100644 +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); } } Loading
src/com/android/settings/tts/TextToSpeechSettings.java +28 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 { Loading Loading @@ -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); Loading Loading @@ -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, Loading @@ -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) { Loading
src/com/android/settings/tts/TextToSpeechViewModel.java 0 → 100644 +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); } }