diff options
4 files changed, 51 insertions, 15 deletions
diff --git a/TestMediaApp/assets/media_items/simple_leaves.json b/TestMediaApp/assets/media_items/simple_leaves.json index dc6b0a3..dbe65b7 100644 --- a/TestMediaApp/assets/media_items/simple_leaves.json +++ b/TestMediaApp/assets/media_items/simple_leaves.json @@ -10,14 +10,6 @@ { "FLAGS": "playable", "METADATA": { - "MEDIA_ID": "simple_leaves normal 10s song", - "DISPLAY_TITLE": "A normal 10s song with a long title. A normal 10s song with a long title. A normal 10s song with a long title. ", - "DURATION": 10000 - } - }, - { - "FLAGS": "playable", - "METADATA": { "MEDIA_ID": "simple_leaves normal 1H song", "DISPLAY_TITLE": "A normal 1H song", "ARTIST": "Artist", @@ -28,6 +20,14 @@ { "FLAGS": "playable", "METADATA": { + "MEDIA_ID": "simple_leaves normal 10s song", + "DISPLAY_TITLE": "A normal 10s song with a long title. A normal 10s song with a long title. A normal 10s song with a long title. ", + "DURATION": 10000 + } + }, + { + "FLAGS": "playable", + "METADATA": { "MEDIA_ID": "simple_leaves slow connection", "DISPLAY_TITLE": "Connects and buffers for 4s each", "DISPLAY_SUBTITLE": "A very long subtitle. A very long subtitle. A very long subtitle. A very long subtitle. A very long subtitle. A very long subtitle. ", diff --git a/TestMediaApp/src/com/android/car/media/testmediaapp/TmaPlayer.java b/TestMediaApp/src/com/android/car/media/testmediaapp/TmaPlayer.java index e75d028..24e12d9 100644 --- a/TestMediaApp/src/com/android/car/media/testmediaapp/TmaPlayer.java +++ b/TestMediaApp/src/com/android/car/media/testmediaapp/TmaPlayer.java @@ -17,6 +17,9 @@ package com.android.car.media.testmediaapp; import static android.media.AudioManager.AUDIOFOCUS_GAIN; +import static android.media.AudioManager.AUDIOFOCUS_LOSS; +import static android.media.AudioManager.AUDIOFOCUS_LOSS_TRANSIENT; +import static android.media.AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK; import static android.media.AudioManager.AUDIOFOCUS_REQUEST_GRANTED; import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PAUSE; import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY; @@ -29,6 +32,7 @@ import static android.support.v4.media.session.PlaybackStateCompat.ACTION_SKIP_T import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_APP_ERROR; import static android.support.v4.media.session.PlaybackStateCompat.STATE_ERROR; +import android.media.AudioManager.OnAudioFocusChangeListener; import androidx.annotation.Nullable; import android.app.PendingIntent; @@ -77,6 +81,7 @@ public class TmaPlayer extends MediaSessionCompat.Callback { @Nullable private TmaMediaItem mActiveItem; private int mNextEventIndex = -1; + private boolean mResumeOnFocusGain; TmaPlayer(TmaBrowser browser, TmaLibrary library, AudioManager audioManager, Handler handler, MediaSessionCompat session) { @@ -87,8 +92,9 @@ public class TmaPlayer extends MediaSessionCompat.Callback { mHandler = handler; mSession = session; - // TODO add focus listener ? - mAudioFocusRequest = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN).build(); + mAudioFocusRequest = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN) + .setOnAudioFocusChangeListener(this::onAudioFocusChange, mHandler) + .build(); } /** Updates the state in the media session based on the given {@link TmaMediaEvent}. */ @@ -366,4 +372,29 @@ public class TmaPlayer extends MediaSessionCompat.Callback { return actions; } + + private void onAudioFocusChange(int focusChange) { + // Adapted from samples at https://developer.android.com/guide/topics/media-apps/audio-focus + // Android Auto emulator tests rely on the app pausing and resuming in response to focus + // transient loss and focus gain, respectively. + switch (focusChange) { + case AUDIOFOCUS_GAIN: + if (mResumeOnFocusGain) { + mResumeOnFocusGain = false; + startPlayBack(/* requestAudioFocus= */ false); + } + break; + case AUDIOFOCUS_LOSS: + mResumeOnFocusGain = false; + pausePlayback(); + break; + case AUDIOFOCUS_LOSS_TRANSIENT: + case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: + mResumeOnFocusGain = mIsPlaying; + pausePlayback(); + break; + default: + Log.w(TAG, "Unknown audio focus change " + focusChange); + } + } } diff --git a/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaEnumPrefs.java b/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaEnumPrefs.java index 3702929..1ee7d73 100644 --- a/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaEnumPrefs.java +++ b/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaEnumPrefs.java @@ -29,9 +29,9 @@ public class TmaEnumPrefs { } public enum TmaAccountType implements EnumPrefValue { - NONE("None", "none"), FREE("Free", "free"), - PAID("Paid", "paid"); + PAID("Paid", "paid"), + NONE("None", "none"); private final PrefValueImpl mPrefValue; @@ -81,11 +81,11 @@ public class TmaEnumPrefs { public enum TmaBrowseNodeType implements EnumPrefValue { + NODE_CHILDREN("Only browse-able content", "nodes"), NULL("Null (error)", "null"), EMPTY("Empty", "empty"), QUEUE_ONLY("Queue only", "queue-only"), SINGLE_TAB("Single browse-able tab", "single-tab"), - NODE_CHILDREN("Only browse-able content", "nodes"), LEAF_CHILDREN("Only playable content (basic working and error cases)", "leaves"), MIXED_CHILDREN("Mixed content (apps are not supposed to do that)", "mixed"), UNTAGGED("Untagged media items (not playable or browsable)", "untagged"); diff --git a/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaPrefs.java b/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaPrefs.java index dd08cd2..fd52697 100644 --- a/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaPrefs.java +++ b/TestMediaApp/src/com/android/car/media/testmediaapp/prefs/TmaPrefs.java @@ -130,11 +130,16 @@ public class TmaPrefs { private TmaPrefs(Context context) { mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); + // Note: Android Auto emulator tests depend on a default account type which permits access + // to the browse tree (e.g. FREE), and the default root node type NODE_CHILDREN. + // Also, they assert on the titles of each root child of NODE_CHILDREN as well as the first + // track under the first root child ("Basic Songs"), i.e. "A normal 1H song". + mAccountType = new EnumPrefEntry<>(TmaPrefKey.ACCOUNT_TYPE_KEY, - TmaAccountType.values(), TmaAccountType.NONE); + TmaAccountType.values(), TmaAccountType.FREE); mRootNodeType = new EnumPrefEntry<>(TmaPrefKey.ROOT_NODE_TYPE_KEY, - TmaBrowseNodeType.values(), TmaBrowseNodeType.NULL); + TmaBrowseNodeType.values(), TmaBrowseNodeType.NODE_CHILDREN); mRootReplyDelay = new EnumPrefEntry<>(TmaPrefKey.ROOT_REPLY_DELAY_KEY, TmaReplyDelay.values(), TmaReplyDelay.NONE); |