summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/com/android/car/messenger/MapMessageMonitor.java53
-rw-r--r--src/com/android/car/messenger/PlayMessageActivity.java5
-rw-r--r--src/com/android/car/messenger/tts/AndroidTTSEngine.java5
-rw-r--r--src/com/android/car/messenger/tts/FakeTTSEngine.java5
-rw-r--r--src/com/android/car/messenger/tts/TTSEngine.java5
-rw-r--r--src/com/android/car/messenger/tts/TTSHelper.java38
-rw-r--r--tests/robotests/src/com/android/car/messenger/tts/TTSHelperTest.java6
7 files changed, 79 insertions, 38 deletions
diff --git a/src/com/android/car/messenger/MapMessageMonitor.java b/src/com/android/car/messenger/MapMessageMonitor.java
index b191e4b..3c427dd 100644
--- a/src/com/android/car/messenger/MapMessageMonitor.java
+++ b/src/com/android/car/messenger/MapMessageMonitor.java
@@ -35,7 +35,6 @@ import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
-import android.media.AudioManager;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -49,7 +48,6 @@ import androidx.annotation.Nullable;
import com.android.car.apps.common.LetterTileDrawable;
import com.android.car.messenger.tts.TTSHelper;
-
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
@@ -94,8 +92,6 @@ class MapMessageMonitor {
private final Map<SenderKey, NotificationInfo> mNotificationInfos = new HashMap<>();
private final TTSHelper mTTSHelper;
private final HashMap<String, Boolean> mReplyFeatureMap = new HashMap<>();
- private final AudioManager mAudioManager;
- private final AudioManager.OnAudioFocusChangeListener mNoOpAFChangeListener = (f) -> {};
MapMessageMonitor(Context context) {
mContext = context;
@@ -104,8 +100,6 @@ class MapMessageMonitor {
mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mTTSHelper = new TTSHelper(mContext);
-
- mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
}
public boolean isPlaying() {
@@ -348,34 +342,29 @@ class MapMessageMonitor {
ttsMessages.add(mContext.getString(R.string.tts_sender_says, notificationInfo.mSenderName));
ttsMessages.add(ttsMessage);
- int result = mAudioManager.requestAudioFocus(mNoOpAFChangeListener,
- // Use the music stream.
- AudioManager.STREAM_MUSIC,
- // Request permanent focus.
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
- if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- mTTSHelper.requestPlay(ttsMessages,
- new TTSHelper.Listener() {
- @Override
- public void onTTSStarted() {
- Intent intent = new Intent(ACTION_MESSAGE_PLAY_START);
- mContext.sendBroadcast(intent);
- }
+ mTTSHelper.requestPlay(ttsMessages,
+ new TTSHelper.Listener() {
+ @Override
+ public void onTTSStarted() {
+ Intent intent = new Intent(ACTION_MESSAGE_PLAY_START);
+ mContext.sendBroadcast(intent);
+ }
- @Override
- public void onTTSStopped(boolean error) {
- mAudioManager.abandonAudioFocus(mNoOpAFChangeListener);
- Intent intent = new Intent(ACTION_MESSAGE_PLAY_STOP);
- mContext.sendBroadcast(intent);
- if (error) {
- Toast.makeText(mContext, R.string.tts_failed_toast,
- Toast.LENGTH_SHORT).show();
- }
+ @Override
+ public void onTTSStopped(boolean error) {
+ Intent intent = new Intent(ACTION_MESSAGE_PLAY_STOP);
+ mContext.sendBroadcast(intent);
+ if (error) {
+ Toast.makeText(mContext, R.string.tts_failed_toast,
+ Toast.LENGTH_SHORT).show();
}
- });
- } else {
- Log.w(TAG, "failed to require audio focus.");
- }
+ }
+
+ @Override
+ public void onAudioFocusFailed() {
+ Log.w(TAG, "failed to require audio focus.");
+ }
+ });
}
void stopPlayout() {
diff --git a/src/com/android/car/messenger/PlayMessageActivity.java b/src/com/android/car/messenger/PlayMessageActivity.java
index 90dcf29..7bfc5f9 100644
--- a/src/com/android/car/messenger/PlayMessageActivity.java
+++ b/src/com/android/car/messenger/PlayMessageActivity.java
@@ -159,6 +159,11 @@ public class PlayMessageActivity extends Activity {
}
finish();
}
+
+ @Override
+ public void onAudioFocusFailed() {
+ Log.w(TAG, "failed to require audio focus.");
+ }
});
}
diff --git a/src/com/android/car/messenger/tts/AndroidTTSEngine.java b/src/com/android/car/messenger/tts/AndroidTTSEngine.java
index b6a7988..70d0aff 100644
--- a/src/com/android/car/messenger/tts/AndroidTTSEngine.java
+++ b/src/com/android/car/messenger/tts/AndroidTTSEngine.java
@@ -54,4 +54,9 @@ class AndroidTTSEngine implements TTSEngine {
mTextToSpeech.shutdown();
mTextToSpeech = null;
}
+
+ @Override
+ public int getStream() {
+ return TextToSpeech.Engine.DEFAULT_STREAM;
+ }
}
diff --git a/src/com/android/car/messenger/tts/FakeTTSEngine.java b/src/com/android/car/messenger/tts/FakeTTSEngine.java
index 0870379..6af64e4 100644
--- a/src/com/android/car/messenger/tts/FakeTTSEngine.java
+++ b/src/com/android/car/messenger/tts/FakeTTSEngine.java
@@ -53,6 +53,11 @@ class FakeTTSEngine implements TTSEngine {
mOnInitListener = null;
}
+ @Override
+ public int getStream() {
+ return TextToSpeech.Engine.DEFAULT_STREAM;
+ }
+
void startRequest(String utteranceId) {
mProgressListener.onStart(utteranceId);
}
diff --git a/src/com/android/car/messenger/tts/TTSEngine.java b/src/com/android/car/messenger/tts/TTSEngine.java
index ed1313f..e789327 100644
--- a/src/com/android/car/messenger/tts/TTSEngine.java
+++ b/src/com/android/car/messenger/tts/TTSEngine.java
@@ -48,4 +48,9 @@ public interface TTSEngine {
* using this engine.
*/
void shutdown();
+
+ /**
+ * Returns the stream used by this TTS engine.
+ */
+ int getStream();
}
diff --git a/src/com/android/car/messenger/tts/TTSHelper.java b/src/com/android/car/messenger/tts/TTSHelper.java
index 8ad132e..aef20d7 100644
--- a/src/com/android/car/messenger/tts/TTSHelper.java
+++ b/src/com/android/car/messenger/tts/TTSHelper.java
@@ -17,6 +17,7 @@
package com.android.car.messenger.tts;
import android.content.Context;
+import android.media.AudioManager;
import android.os.Handler;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
@@ -57,6 +58,12 @@ public class TTSHelper {
* not considered an error.
*/
void onTTSStopped(boolean error);
+
+ /**
+ * Called when request to get audio focus failed. This happens before the requested TTS
+ * is played.
+ */
+ void onAudioFocusFailed();
}
private static final String TAG = "Messenger.TTSHelper";
@@ -67,6 +74,8 @@ public class TTSHelper {
private final Handler mHandler = new Handler();
private final Context mContext;
+ private final AudioManager mAudioManager;
+ private final AudioManager.OnAudioFocusChangeListener mNoOpAFChangeListener = (f) -> {};
private final long mShutdownDelayMillis;
private TTSEngine mTTSEngine;
private int mInitStatus;
@@ -84,6 +93,7 @@ public class TTSHelper {
@VisibleForTesting
TTSHelper(Context context, TTSEngine ttsEngine, long shutdownDelayMillis) {
mContext = context;
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mTTSEngine = ttsEngine;
mShutdownDelayMillis = shutdownDelayMillis;
// OnInitListener will only set to SUCCESS/ERROR. So we initialize to STOPPED.
@@ -130,6 +140,7 @@ public class TTSHelper {
* until then. Only one batch is supported at a time; If a previous batch is waiting engine
* setup, that batch is dropped. If a previous batch is playing, the play-out is stopped and
* next one is passed to the TTS Engine. Callbacks are issued on the provided {@code listener}.
+ * Will request audio focus first, failure will trigger onAudioFocusFailed in listener.
*
* NOTE: Underlying engine may have limit on length of text in each element of the batch; it
* will reject anything longer. See {@link TextToSpeech#getMaxSpeechInputLength()}.
@@ -138,16 +149,23 @@ public class TTSHelper {
* @param listener Observer that will receive callbacks about play-out progress.
*/
public void requestPlay(List<CharSequence> textToSpeak, Listener listener) {
- if (textToSpeak == null || textToSpeak.size() < 1) {
+ if (textToSpeak == null || textToSpeak.isEmpty()) {
throw new IllegalArgumentException("Empty/null textToSpeak");
}
+ int result = mAudioManager.requestAudioFocus(mNoOpAFChangeListener,
+ getStream(),
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+ if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+ listener.onAudioFocusFailed();
+ return;
+ }
initMaybeAndKeepAlive();
// Check if its still initializing.
if (mInitStatus == TextToSpeech.STOPPED) {
// Squash any already queued request.
if (mPendingRequest != null) {
- mPendingRequest.mListener.onTTSStopped(false /* error */);
+ onTtsStopped(mPendingRequest.mListener, false /* error */);
}
mPendingRequest = new SpeechRequest(textToSpeak, listener);
} else {
@@ -164,10 +182,16 @@ public class TTSHelper {
return mTTSEngine.isSpeaking();
}
+ // wrap call back to listener.onTTSStopped with adandonAudioFocus.
+ private void onTtsStopped(Listener listener, boolean error) {
+ mAudioManager.abandonAudioFocus(mNoOpAFChangeListener);
+ mHandler.post(() -> listener.onTTSStopped(error));
+ }
+
private void playInternal(List<CharSequence> textToSpeak, Listener listener) {
if (mInitStatus == TextToSpeech.ERROR) {
Log.e(TAG, "TTS setup failed!");
- mHandler.post(() -> listener.onTTSStopped(true /* error */));
+ onTtsStopped(listener, true /* error */);
return;
}
@@ -189,7 +213,7 @@ public class TTSHelper {
mTTSEngine.stop();
currentBatchId = null;
Log.e(TAG, "Queuing text failed!");
- mHandler.post(() -> listener.onTTSStopped(true /* error */));
+ onTtsStopped(listener, true /* error */);
return;
}
index--;
@@ -207,6 +231,10 @@ public class TTSHelper {
shutdownEngine();
}
+ public int getStream() {
+ return mTTSEngine.getStream();
+ }
+
private void shutdownEngine() {
if (mTTSEngine.isInitialized()) {
if (DBG) {
@@ -325,7 +353,7 @@ public class TTSHelper {
// Handles terminal callbacks for the batch. We invoke stopped and remove ourselves.
// No further callbacks will be handled for the batch.
private void handleBatchFinished(Pair<String, Integer> parsedId, boolean error) {
- mListener.onTTSStopped(error);
+ onTtsStopped(mListener, error);
mListeners.remove(parsedId.first);
}
}
diff --git a/tests/robotests/src/com/android/car/messenger/tts/TTSHelperTest.java b/tests/robotests/src/com/android/car/messenger/tts/TTSHelperTest.java
index f9745f4..dbbb5e4 100644
--- a/tests/robotests/src/com/android/car/messenger/tts/TTSHelperTest.java
+++ b/tests/robotests/src/com/android/car/messenger/tts/TTSHelperTest.java
@@ -156,5 +156,9 @@ public class TTSHelperTest {
mStopped = true;
mError = error;
}
+
+ @Override
+ public void onAudioFocusFailed() {
+ }
}
-} \ No newline at end of file
+}