Remove deprecated classes
Test: manual
Test: make -j64 RunCarMediaCommonRoboTests
test: make -j64 RunCarArchCommonRoboTests
Change-Id: Ia4cc454e2e97e8b14387df9c57f30a3fd8c8d688
diff --git a/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java b/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java
deleted file mode 100644
index cc27067..0000000
--- a/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2018 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.car.media.common.source;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.media.session.MediaController;
-import android.media.session.MediaSessionManager;
-import android.os.RemoteException;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.lifecycle.LiveData;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * This is an abstractions over {@link MediaSessionManager} that provides information about the
- * currently active media sessions.
- * <p>
- * This requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL permission to be held by the
- * calling app.
- *
- * @deprecated To be removed with b/121270620
- */
-@Deprecated
-class ActiveMediaControllersLiveData extends LiveData<List<MediaControllerCompat>> {
-
- private static final String TAG = "ActiveMedia";
- private final MediaSessionManager mMediaSessionManager;
-
- // TODO(b/121270620) Clean up MediaController fetching logic, remove this LiveData if not needed
- private final MediaSessionUpdater mMediaSessionUpdater = new MediaSessionUpdater();
- private Context mContext;
-
- /**
- * Temporary work-around to bug b/76017849. MediaSessionManager is not notifying media session
- * priority changes. As a work-around we subscribe to playback state changes on all controllers
- * to detect potential priority changes. This might cause a few unnecessary checks, but
- * selecting the top-most controller is a cheap operation.
- */
- private class MediaSessionUpdater {
- private List<MediaControllerCompat> mControllers = new ArrayList<>();
-
- private MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
- @Override
- public void onPlaybackStateChanged(@Nullable PlaybackStateCompat state) {
- List<MediaController> activeSessions =
- mMediaSessionManager.getActiveSessions(null);
- update(activeSessions);
- }
-
- @Override
- public void onSessionDestroyed() {
- List<MediaController> activeSessions =
- mMediaSessionManager.getActiveSessions(null);
- update(activeSessions);
- }
- };
-
- private void registerCallbacks(List<MediaControllerCompat> newControllers) {
- for (MediaControllerCompat oldController : mControllers) {
- oldController.unregisterCallback(mCallback);
- }
- for (MediaControllerCompat newController : newControllers) {
- newController.registerCallback(mCallback);
- }
- mControllers.clear();
- mControllers.addAll(newControllers);
- }
- }
-
- private MediaSessionManager.OnActiveSessionsChangedListener mSessionChangeListener =
- controllers -> setValue(convertCompat(controllers));
-
- ActiveMediaControllersLiveData(Context context) {
- this(Objects.requireNonNull(context.getSystemService(MediaSessionManager.class)));
- mContext = context;
- }
-
- @VisibleForTesting
- ActiveMediaControllersLiveData(@NonNull MediaSessionManager mediaSessionManager) {
- mMediaSessionManager = mediaSessionManager;
- }
-
- private void update(List<MediaController> activeSessions) {
- List<MediaControllerCompat> activeSessionsCompat = convertCompat(activeSessions);
- setValue(activeSessionsCompat);
- mMediaSessionUpdater.registerCallbacks(activeSessionsCompat);
- }
-
- @Override
- protected void onActive() {
- mMediaSessionManager.addOnActiveSessionsChangedListener(mSessionChangeListener, null);
- update(mMediaSessionManager.getActiveSessions(null));
- }
-
- @Override
- protected void onInactive() {
- mMediaSessionUpdater.registerCallbacks(new ArrayList<>());
- mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionChangeListener);
- }
-
- private List<MediaControllerCompat> convertCompat(List<MediaController> mediaControllers) {
- return mediaControllers.stream().map(
- controller -> fromMediaController(controller))
- .collect(Collectors.toList());
- }
-
- @VisibleForTesting
- MediaControllerCompat fromMediaController(MediaController mediaController) {
- // TODO(b/112161702): cache active MediaControllers
- MediaSessionCompat.Token token =
- MediaSessionCompat.Token.fromToken(mediaController.getSessionToken());
- MediaControllerCompat controllerCompat = null;
- try {
- controllerCompat = new MediaControllerCompat(mContext, token);
- } catch (RemoteException e) {
- Log.e(TAG, "Couldn't get MediaController", e);
- }
- return controllerCompat;
- }
-}
diff --git a/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java b/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java
deleted file mode 100644
index 8af62fa..0000000
--- a/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2018 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.car.media.common.source;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.media.session.MediaSessionManager;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.car.media.common.playback.PlaybackStateAnnotations;
-
-import java.util.List;
-
-/**
- * Provides functions for selecting a {@link MediaControllerCompat} from a list of controllers.
- */
-class ActiveMediaSelector {
- private static final String TAG = "ActiveSourceManager";
-
- private static final String PLAYBACK_MODEL_SHARED_PREFS =
- "com.android.car.media.PLAYBACK_MODEL";
- private static final String PLAYBACK_MODEL_ACTIVE_PACKAGE_NAME_KEY =
- "active_packagename";
-
- private final SharedPreferences mSharedPreferences;
-
- ActiveMediaSelector(Context context) {
- this(context.getSharedPreferences(PLAYBACK_MODEL_SHARED_PREFS, Context.MODE_PRIVATE));
- }
-
- @VisibleForTesting
- ActiveMediaSelector(@NonNull SharedPreferences preferences) {
- mSharedPreferences = preferences;
- }
-
- /**
- * Searches through {@code controllers} to find the MediaControllerCompat with the same package
- * name as {@code mediaSource}.
- *
- * @param controllers The List of MediaControllers to search through.
- * @param mediaSource The MediaSource to match.
- * @return The MediaControllerCompat whose package name matches or {@code null} if no match is
- * found.
- */
- @Nullable
- MediaControllerCompat getControllerForSource(@NonNull List<MediaControllerCompat> controllers,
- MediaSource mediaSource) {
- if (mediaSource != null) {
- return getControllerForPackage(controllers, mediaSource.getPackageName());
- }
- return null;
- }
-
- /**
- * Searches through {@code controllers} to find the MediaController with the specified {@code
- * packageName}
- *
- * @param controllers The List of MediaControllers to search through.
- * @param packageName The package name to find.
- * @return The MediaController whose package name matches or {@code null} if no match is found.
- */
- @Nullable
- MediaControllerCompat getControllerForPackage(@NonNull List<MediaControllerCompat> controllers,
- @NonNull String packageName) {
- for (MediaControllerCompat controller : controllers) {
- if (controller != null && packageName.equals(controller.getPackageName())) {
- return controller;
- }
- }
- return null;
- }
-
- /**
- * Returns one of the provided controllers as the "currently playing" one. If {@code previous}
- * is equivalent, will return that instance.
- */
- MediaControllerCompat getTopMostMediaController(
- @NonNull List<MediaControllerCompat> controllers,
- @Nullable MediaControllerCompat previous) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- dump("Selecting a media controller from: ", controllers);
- }
- MediaControllerCompat topMostController = pickTopMostController(controllers);
- if ((topMostController == null && previous == null)
- || (topMostController != null && previous != null
- && topMostController.getPackageName().equals(previous.getPackageName()))) {
- // If no change, do nothing.
- return previous;
- }
- setLastKnownActivePackageName(
- topMostController == null ? null : topMostController.getPackageName());
- return topMostController;
- }
-
- private void dump(@SuppressWarnings("SameParameterValue") String title,
- List<MediaControllerCompat> controllers) {
- Log.d(TAG, title + " (total: " + controllers.size() + ")");
- for (MediaControllerCompat controller : controllers) {
- String stateName = getStateName(controller.getPlaybackState() != null
- ? controller.getPlaybackState().getState()
- : PlaybackStateCompat.STATE_NONE);
- Log.d(TAG, String.format("\t%s: %s",
- controller.getPackageName(),
- stateName));
- }
- }
-
- private String getStateName(@PlaybackStateAnnotations.State int state) {
- switch (state) {
- case PlaybackStateCompat.STATE_NONE:
- return "NONE";
- case PlaybackStateCompat.STATE_STOPPED:
- return "STOPPED";
- case PlaybackStateCompat.STATE_PAUSED:
- return "PAUSED";
- case PlaybackStateCompat.STATE_PLAYING:
- return "PLAYING";
- case PlaybackStateCompat.STATE_FAST_FORWARDING:
- return "FORWARDING";
- case PlaybackStateCompat.STATE_REWINDING:
- return "REWINDING";
- case PlaybackStateCompat.STATE_BUFFERING:
- return "BUFFERING";
- case PlaybackStateCompat.STATE_ERROR:
- return "ERROR";
- case PlaybackStateCompat.STATE_CONNECTING:
- return "CONNECTING";
- case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS:
- return "SKIPPING_TO_PREVIOUS";
- case PlaybackStateCompat.STATE_SKIPPING_TO_NEXT:
- return "SKIPPING_TO_NEXT";
- case PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM:
- return "SKIPPING_TO_QUEUE_ITEM";
- default:
- return "UNKNOWN";
- }
- }
-
- /**
- * Returns the controller most likely to be the currently active one, out of the list of active
- * controllers reported by {@link MediaSessionManager}. It does so by picking the first one (in
- * order of priority) with an active state as reported by
- * {@link MediaControllerCompat#getPlaybackState()}
- */
- @Nullable
- private MediaControllerCompat pickTopMostController(List<MediaControllerCompat> controllers) {
- if (controllers != null && controllers.size() > 0) {
- for (MediaControllerCompat candidate : controllers) {
- @PlaybackStateAnnotations.State int state = candidate.getPlaybackState() != null
- ? candidate.getPlaybackState().getState()
- : PlaybackStateCompat.STATE_NONE;
- if (state == PlaybackStateCompat.STATE_BUFFERING
- || state == PlaybackStateCompat.STATE_CONNECTING
- || state == PlaybackStateCompat.STATE_FAST_FORWARDING
- || state == PlaybackStateCompat.STATE_PLAYING
- || state == PlaybackStateCompat.STATE_REWINDING
- || state == PlaybackStateCompat.STATE_SKIPPING_TO_NEXT
- || state == PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS
- || state == PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM) {
- return candidate;
- }
- }
- // If no source is active, we go for the last known source
- String packageName = getLastKnownActivePackageName();
- if (packageName != null) {
- for (MediaControllerCompat candidate : controllers) {
- if (candidate.getPackageName().equals(packageName)) {
- return candidate;
- }
- }
- }
- return controllers.get(0);
- }
- return null;
- }
-
- private String getLastKnownActivePackageName() {
- return mSharedPreferences.getString(PLAYBACK_MODEL_ACTIVE_PACKAGE_NAME_KEY, null);
- }
-
- private void setLastKnownActivePackageName(String packageName) {
- mSharedPreferences.edit()
- .putString(PLAYBACK_MODEL_ACTIVE_PACKAGE_NAME_KEY, packageName)
- .apply();
- }
-
-}
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java b/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
index f9596f3..45081b5 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
@@ -19,20 +19,20 @@
import static androidx.lifecycle.Transformations.map;
import static androidx.lifecycle.Transformations.switchMap;
-import static com.android.car.arch.common.LiveDataFunctions.coalesceNull;
-import static com.android.car.arch.common.LiveDataFunctions.combine;
import static com.android.car.arch.common.LiveDataFunctions.dataOf;
-import static com.android.car.arch.common.LiveDataFunctions.mapNonNull;
import static com.android.car.arch.common.LiveDataFunctions.nullLiveData;
+import static com.android.car.arch.common.LiveDataFunctions.pair;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Application;
import android.content.ComponentName;
import android.content.ContentValues;
+import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
import android.os.Handler;
import android.os.RemoteException;
import android.support.v4.media.MediaBrowserCompat;
@@ -53,8 +53,8 @@
import com.android.car.media.common.source.MediaBrowserConnector.MediaBrowserState;
import java.util.List;
-import java.util.Objects;
import java.util.function.BiFunction;
+import java.util.stream.Collectors;
/**
* Contains observable data needed for displaying playback and browse UI
@@ -69,11 +69,6 @@
// Media controller for selected media source.
private final LiveData<MediaControllerCompat> mMediaController;
- // Media controller for active media source, may not be the same as selected media source.
- private final LiveData<MediaControllerCompat> mTopActiveMediaController;
-
- private final LiveData<Boolean> mIsCurrentMediaSourcePlaying;
-
/**
* Factory for creating dependencies. Can be swapped out for testing.
*/
@@ -82,9 +77,7 @@
LiveData<MediaBrowserState> createMediaBrowserConnector(
@NonNull ComponentName browseService);
- ActiveMediaSelector createActiveMediaSelector();
-
- LiveData<List<MediaControllerCompat>> createActiveMediaControllerData();
+ List<MediaControllerCompat> getActiveMediaControllers();
MediaControllerCompat getControllerForSession(@Nullable MediaSessionCompat.Token session);
@@ -104,6 +97,9 @@
public MediaSourceViewModel(@NonNull Application application) {
this(application, new InputFactory() {
+ private final MediaSessionManager mMediaSessionManager =
+ application.getSystemService(MediaSessionManager.class);
+
@Override
public LiveData<MediaBrowserState> createMediaBrowserConnector(
@NonNull ComponentName browseService) {
@@ -111,13 +107,8 @@
}
@Override
- public LiveData<List<MediaControllerCompat>> createActiveMediaControllerData() {
- return new ActiveMediaControllersLiveData(application);
- }
-
- @Override
- public ActiveMediaSelector createActiveMediaSelector() {
- return new ActiveMediaSelector(application);
+ public List<MediaControllerCompat> getActiveMediaControllers() {
+ return toCompatList(mMediaSessionManager.getActiveSessions(null), application);
}
@Override
@@ -154,12 +145,6 @@
MediaSourceViewModel(@NonNull Application application, @NonNull InputFactory inputFactory) {
super(application);
- LiveData<List<MediaControllerCompat>> activeMediaControllers =
- inputFactory.createActiveMediaControllerData();
- ActiveMediaSelector mediaSelector = inputFactory.createActiveMediaSelector();
- mTopActiveMediaController = map(activeMediaControllers,
- new LoopbackFunction<>(mediaSelector::getTopMostMediaController));
-
mPrimaryMediaSource.setValue(inputFactory.getSelectedSourceFromContentProvider());
application.getContentResolver().registerContentObserver(
MediaConstants.URI_MEDIA_SOURCE, false,
@@ -186,21 +171,49 @@
state -> state != null && (state.mConnectionState == ConnectionState.CONNECTED)
? state.mMediaBrowser : null);
- LiveData<MediaControllerCompat> controllerFromActiveList =
- combine(activeMediaControllers, mPrimaryMediaSource,
- mediaSelector::getControllerForSource);
- LiveData<MediaControllerCompat> controllerFromMediaBrowser =
- mapNonNull(mConnectedMediaBrowser,
- browser -> inputFactory.getControllerForSession(browser.getSessionToken()));
- // Prefer fetching MediaController from MediaSessionManager's active controller
- // list. Otherwise use controller from MediaBrowser (which requires connecting to it).
- mMediaController = coalesceNull(controllerFromActiveList, controllerFromMediaBrowser);
+ mMediaController = map(pair(mPrimaryMediaSource, mConnectedMediaBrowser),
+ (pair) -> {
+ MediaSource mediaSource = pair.first;
+ MediaBrowserCompat browser = pair.second;
- mIsCurrentMediaSourcePlaying = combine(mTopActiveMediaController, mPrimaryMediaSource,
- (mediaController, mediaSource) ->
- mediaController != null && mediaSource != null
- && Objects.equals(mediaController.getPackageName(),
- mediaSource.getPackageName()));
+ // Prefer fetching MediaController from MediaSessionManager's active controller
+ // list. Otherwise use controller from MediaBrowser (which requires connecting
+ // to it).
+ if (mediaSource != null) {
+ List<MediaControllerCompat> controllers =
+ inputFactory.getActiveMediaControllers();
+ String packageName = mediaSource.getPackageName();
+ for (MediaControllerCompat controller : controllers) {
+ if (controller != null && packageName.equals(
+ controller.getPackageName())) {
+ return controller;
+ }
+ }
+ }
+ if (browser != null) {
+ return inputFactory.getControllerForSession(browser.getSessionToken());
+ }
+ return null;
+ });
+ }
+
+ private static List<MediaControllerCompat> toCompatList(List<MediaController> mediaControllers,
+ Context context) {
+ return mediaControllers.stream().map(
+ controller -> toCompatController(controller, context)).collect(Collectors.toList());
+ }
+
+ private static MediaControllerCompat toCompatController(MediaController mediaController,
+ Context context) {
+ MediaSessionCompat.Token token =
+ MediaSessionCompat.Token.fromToken(mediaController.getSessionToken());
+ MediaControllerCompat controllerCompat = null;
+ try {
+ controllerCompat = new MediaControllerCompat(context, token);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't get MediaController", e);
+ }
+ return controllerCompat;
}
/**
@@ -239,21 +252,6 @@
return mMediaController;
}
- /**
- * Returns a LiveData that emits a {@link MediaController} for the primary active media source.
- * Note that this may not be from the selected media source.
- */
- public LiveData<MediaControllerCompat> getTopActiveMediaController() {
- return mTopActiveMediaController;
- }
-
- /**
- * Emits {@code true} iff the selected media source is the active media source
- */
- public LiveData<Boolean> isCurrentMediaSourcePlaying() {
- return mIsCurrentMediaSourcePlaying;
- }
-
private static class LoopbackFunction<P, V> implements Function<P, V> {
private final BiFunction<P, V, V> mFunction;
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java
deleted file mode 100644
index c4ad2aa..0000000
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2018 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.car.media.common.source;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.media.session.MediaController;
-import android.media.session.MediaSessionManager;
-import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
-import android.support.v4.media.session.MediaControllerCompat;
-
-import androidx.lifecycle.Lifecycle;
-
-import com.android.car.arch.common.testing.CaptureObserver;
-import com.android.car.arch.common.testing.InstantTaskExecutorRule;
-import com.android.car.arch.common.testing.TestLifecycleOwner;
-import com.android.car.media.common.TestConfig;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class ActiveMediaControllersLiveDataTest {
-
- @Rule
- public final MockitoRule mMockitoRule = MockitoJUnit.rule();
- @Rule
- public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
- @Rule
- public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
-
- @Mock
- public MediaSessionManager mMediaSessionManager;
- @Mock
- public MediaController mFirstMediaController;
- @Mock
- public MediaController mSecondMediaController;
- @Mock
- public MediaControllerCompat mFirstMediaControllerCompat;
- @Mock
- public MediaControllerCompat mSecondMediaControllerCompat;
- @Captor
- public ArgumentCaptor<OnActiveSessionsChangedListener> mSessionChangeListenerCaptor;
- @Captor
- public ArgumentCaptor<MediaControllerCompat.Callback> mFirstControllerCallbackCaptor;
-
- private List<MediaController> mMediaControllerList;
-
- private ActiveMediaControllersLiveData mLiveData;
-
- @Before
- public void setUp() {
- mMediaControllerList = new ArrayList<>();
- mMediaControllerList.add(mFirstMediaController);
- mMediaControllerList.add(mSecondMediaController);
-
- doNothing().when(mFirstMediaControllerCompat)
- .registerCallback(mFirstControllerCallbackCaptor.capture());
- doNothing().when(mMediaSessionManager).addOnActiveSessionsChangedListener(
- mSessionChangeListenerCaptor.capture(), any());
- doAnswer(invocation -> {
- OnActiveSessionsChangedListener argument = invocation.getArgument(0);
- if (argument == mSessionChangeListenerCaptor.getValue()) {
- mSessionChangeListenerCaptor =
- ArgumentCaptor.forClass(OnActiveSessionsChangedListener.class);
- }
- return null;
- }).when(mMediaSessionManager).removeOnActiveSessionsChangedListener(any());
-
-
- when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllerList);
-
- mLiveData = new ActiveMediaControllersLiveData(mMediaSessionManager) {
- @Override
- protected MediaControllerCompat fromMediaController(MediaController mediaController) {
- if (mediaController == mFirstMediaController) {
- return mFirstMediaControllerCompat;
- } else if (mediaController == mSecondMediaController) {
- return mSecondMediaControllerCompat;
- }
- return null;
- }
- };
- }
-
- @Test
- public void testFetchOnActive() {
- CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
-
- mLiveData.observe(mLifecycleOwner, observer);
-
- assertThat(observer.hasBeenNotified()).isTrue();
- List<MediaControllerCompat> mediaControllerCompatList = new ArrayList<>();
- mediaControllerCompatList.add(mFirstMediaControllerCompat);
- mediaControllerCompatList.add(mSecondMediaControllerCompat);
- assertThat(observer.getObservedValue()).isEqualTo(mediaControllerCompatList);
- }
-
-
- @Test
- public void testPlaybackStateChangedTriggersUpdate() {
- CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
- mLiveData.observe(mLifecycleOwner, observer);
- observer.reset();
-
- mFirstControllerCallbackCaptor.getValue()
- .onPlaybackStateChanged(mFirstMediaControllerCompat.getPlaybackState());
-
- assertThat(observer.hasBeenNotified()).isTrue();
- }
-
- @Test
- public void testSessionDestroyedTriggersUpdate() {
- CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
- mLiveData.observe(mLifecycleOwner, observer);
- observer.reset();
-
- mFirstControllerCallbackCaptor.getValue().onSessionDestroyed();
-
- assertThat(observer.hasBeenNotified()).isTrue();
- }
-
- @Test
- public void testUnregisterOnInactive() {
- CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
- mLiveData.observe(mLifecycleOwner, observer);
- observer.reset();
-
- // Need to hold reference to captor since it will be swapped out when listener is
- // unregistered.
- ArgumentCaptor<OnActiveSessionsChangedListener> oldArgumentCaptor =
- mSessionChangeListenerCaptor;
- mLifecycleOwner.markState(Lifecycle.State.DESTROYED);
-
- verify(mMediaSessionManager)
- .removeOnActiveSessionsChangedListener(oldArgumentCaptor.getValue());
- }
-}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java
deleted file mode 100644
index 6b85cc3..0000000
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2018 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.car.media.common.source;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-import static org.robolectric.RuntimeEnvironment.application;
-
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.support.v4.media.session.MediaControllerCompat;
-import android.support.v4.media.session.PlaybackStateCompat;
-
-import androidx.annotation.Nullable;
-
-import com.android.car.arch.common.testing.InstantTaskExecutorRule;
-import com.android.car.arch.common.testing.TestLifecycleOwner;
-import com.android.car.media.common.TestConfig;
-import com.android.car.media.common.playback.PlaybackStateAnnotations;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class ActiveMediaSelectorTest {
-
- private static final String TEST_PACKAGE_1 = "package1";
- private static final String TEST_PACKAGE_2 = "package2";
- @Rule
- public final MockitoRule mMockitoRule = MockitoJUnit.rule();
- @Rule
- public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
- @Rule
- public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
-
- @Mock
- public MediaControllerCompat mFirstMediaController;
- @Mock
- public MediaControllerCompat mSecondMediaController;
-
- private List<MediaControllerCompat> mMediaControllerList;
- private SharedPreferences mSharedPreferences;
- private ActiveMediaSelector mSelector;
-
-
- @Before
- public void setUp() {
- mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(
- application);
- mSharedPreferences.edit().clear().apply();
-
- mMediaControllerList = new ArrayList<>();
- mMediaControllerList.add(mFirstMediaController);
- mMediaControllerList.add(mSecondMediaController);
-
- setControllerState(mFirstMediaController, PlaybackStateCompat.STATE_PLAYING);
- when(mFirstMediaController.getPackageName()).thenReturn(TEST_PACKAGE_1);
- setControllerState(mSecondMediaController, PlaybackStateCompat.STATE_PLAYING);
- when(mSecondMediaController.getPackageName()).thenReturn(TEST_PACKAGE_2);
-
-
- mSelector = new ActiveMediaSelector(mSharedPreferences);
- }
-
- @Test
- public void testChooseFirstController() {
- assertThat(mSelector.getTopMostMediaController(mMediaControllerList, null))
- .isSameAs(mFirstMediaController);
- }
-
- @Test
- public void testPickPlayingController() {
- setControllerState(mFirstMediaController, PlaybackStateCompat.STATE_PAUSED);
-
- assertThat(mSelector.getTopMostMediaController(mMediaControllerList, null))
- .isSameAs(mSecondMediaController);
- }
-
- @Test
- public void testUsedLastWhenAllPaused() {
- setControllerState(mFirstMediaController, PlaybackStateCompat.STATE_PAUSED);
- setControllerState(mSecondMediaController, PlaybackStateCompat.STATE_PAUSED);
- setLastObservedController(mSecondMediaController);
-
- assertThat(mSelector.getTopMostMediaController(mMediaControllerList, null))
- .isSameAs(mSecondMediaController);
- }
-
- @Test
- public void testGetControllerForPackage() {
- assertThat(mSelector.getControllerForPackage(mMediaControllerList, TEST_PACKAGE_2))
- .isSameAs(mSecondMediaController);
- }
-
- @Test
- public void testGetControllerForPackage_noMatch() {
- assertThat(mSelector.getControllerForPackage(mMediaControllerList, "")).isNull();
- }
-
- private void setLastObservedController(@Nullable MediaControllerCompat mediaController) {
- List<MediaControllerCompat> mediaControllers =
- mediaController == null ? Collections.emptyList()
- : Collections.singletonList(mediaController);
-
- // Use another instance of ActiveMediaControllerLiveData (not the one under test) to
- // inject the desired value into SharedPreferences.
- ActiveMediaSelector injectorData =
- new ActiveMediaSelector(mSharedPreferences);
-
- injectorData.getTopMostMediaController(mediaControllers, null);
- }
-
- private void setControllerState(MediaControllerCompat mediaController,
- @PlaybackStateAnnotations.State int state) {
- when(mediaController.getPlaybackState())
- .thenReturn(
- new PlaybackStateCompat.Builder().setState(state, 0, 0).build());
- }
-}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
index 9ff04b2..157c0d5 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
@@ -18,7 +18,6 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
@@ -48,7 +47,7 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@@ -69,15 +68,12 @@
@Mock
public MediaBrowserCompat mMediaBrowser;
@Mock
- public ActiveMediaSelector mActiveMediaSelector;
- @Mock
public MediaControllerCompat mMediaControllerFromBrowser;
@Mock
public MediaControllerCompat mMediaControllerFromSessionManager;
private final MutableLiveData<MediaBrowserState> mMediaBrowserState = new MutableLiveData<>();
- private final MutableLiveData<List<MediaControllerCompat>> mActiveMediaControllers =
- new MutableLiveData<>();
+ private final List<MediaControllerCompat> mActiveMediaControllers = new ArrayList<>(1);
private MediaSourceViewModel mViewModel;
@@ -90,11 +86,7 @@
when(mMediaControllerFromSessionManager.getPackageName())
.thenReturn(SESSION_MANAGER_CONTROLLER_PACKAGE_NAME);
- mActiveMediaControllers.setValue(
- Collections.singletonList(mMediaControllerFromSessionManager));
- when(mActiveMediaSelector.getTopMostMediaController(any(), any()))
- .thenReturn(mMediaControllerFromSessionManager);
-
+ mActiveMediaControllers.add(mMediaControllerFromSessionManager);
mRequestedBrowseService = null;
mViewModel = new MediaSourceViewModel(application, new MediaSourceViewModel.InputFactory() {
@@ -107,12 +99,7 @@
}
@Override
- public ActiveMediaSelector createActiveMediaSelector() {
- return mActiveMediaSelector;
- }
-
- @Override
- public LiveData<List<MediaControllerCompat>> createActiveMediaControllerData() {
+ public List<MediaControllerCompat> getActiveMediaControllers() {
return mActiveMediaControllers;
}
@@ -141,8 +128,8 @@
@Test
public void testGetMediaController_fromSessionManager() {
CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
- when(mActiveMediaSelector.getControllerForSource(any(), any()))
- .thenReturn(mMediaControllerFromSessionManager);
+ when(mMediaSource.getPackageName())
+ .thenReturn(SESSION_MANAGER_CONTROLLER_PACKAGE_NAME);
mViewModel.getMediaController().observe(mLifecycleOwner, observer);
@@ -153,7 +140,7 @@
@Test
public void testGetMediaController_noActiveSession() {
CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
- mMediaControllerFromSessionManager = null;
+ mActiveMediaControllers.clear();
ComponentName testComponent = new ComponentName("test", "test");
when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
mMediaBrowserState.setValue(new MediaBrowserState(mMediaBrowser,
@@ -168,7 +155,7 @@
@Test
public void testGetMediaController_noActiveSession_noBrowseService() {
CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
- mMediaControllerFromSessionManager = null;
+ mActiveMediaControllers.clear();
when(mMediaSource.getBrowseServiceComponentName()).thenReturn(null);
mMediaBrowserState.setValue(new MediaBrowserState(mMediaBrowser,
MediaBrowserConnector.ConnectionState.CONNECTED));
@@ -183,7 +170,7 @@
@Test
public void testGetMediaController_noActiveSession_notConnected() {
CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
- mMediaControllerFromSessionManager = null;
+ mActiveMediaControllers.clear();
ComponentName testComponent = new ComponentName("test", "test");
when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
mMediaBrowserState.setValue(new MediaBrowserState(mMediaBrowser,
@@ -195,36 +182,4 @@
assertThat(observer.getObservedValue()).isNull();
assertThat(mRequestedBrowseService).isEqualTo(testComponent);
}
-
- @Test
- public void testGetActiveMediaController() {
- when(mActiveMediaSelector.getTopMostMediaController(any(), any()))
- .thenReturn(mMediaControllerFromBrowser);
- CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
-
- mViewModel.getTopActiveMediaController().observe(mLifecycleOwner, observer);
-
- assertThat(observer.getObservedValue()).isSameAs(mMediaControllerFromBrowser);
- }
-
- @Test
- public void testIsCurrentMediaSourcePlaying() {
- CaptureObserver<Boolean> observer = new CaptureObserver<>();
- ComponentName testComponent = new ComponentName("test", "test");
- when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
- when(mMediaSource.getPackageName()).thenReturn(BROWSER_CONTROLLER_PACKAGE_NAME);
- when(mActiveMediaSelector.getTopMostMediaController(any(), any()))
- .thenReturn(mMediaControllerFromBrowser);
-
- mViewModel.isCurrentMediaSourcePlaying().observe(mLifecycleOwner, observer);
-
- assertThat(observer.getObservedValue()).isTrue();
-
- // make
- when(mActiveMediaSelector.getTopMostMediaController(any(), any()))
- .thenReturn(mMediaControllerFromSessionManager);
- mActiveMediaControllers.setValue(mActiveMediaControllers.getValue());
-
- assertThat(observer.getObservedValue()).isFalse();
- }
}