diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-03-13 20:35:25 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-03-13 20:35:25 +0000 |
commit | 72af0679d01410e765325c05dbf000df5d722018 (patch) | |
tree | 64602c98fd67ad03f022f098f877a720164c46cc | |
parent | 03545310fc4b7fad503ce5c032affc00de8dc498 (diff) | |
parent | 07306b21ea40b3f7c2bcfb539368ee5f59bd2dda (diff) | |
download | Media-mirror-car-apps-aosp-release.tar.gz |
Snap for 11566466 from 07306b21ea40b3f7c2bcfb539368ee5f59bd2dda to car-apps-aosp-releaseub-automotive-master-20240314mirror-car-apps-aosp-release
Change-Id: I0e1243a639bd4e04d4b151e19a5d0feaee42feb5
-rw-r--r-- | build.gradle | 2 | ||||
-rw-r--r-- | src/com/android/car/media/MediaActivity.java | 51 | ||||
-rw-r--r-- | src/com/android/car/media/browse/BrowseViewHolder.java | 14 | ||||
-rw-r--r-- | src/com/android/car/media/service/MediaConnectorService.java | 24 | ||||
-rw-r--r-- | tests/unittests/src/com/android/car/media/service/MediaConnectorServiceTests.java (renamed from tests/unittests/src/com/android/car/media/MediaConnectorServiceTests.java) | 31 |
5 files changed, 63 insertions, 59 deletions
diff --git a/build.gradle b/build.gradle index 740798b..141cd7a 100644 --- a/build.gradle +++ b/build.gradle @@ -138,7 +138,7 @@ dependencies { testImplementation 'com.google.truth:truth:1.1.3' testImplementation 'androidx.test.ext:junit:1.1.3' testImplementation 'junit:junit:4.12' - testImplementation 'org.robolectric:robolectric:4.10.3' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation "org.mockito:mockito-core:2.19.0" testImplementation 'androidx.test:runner:1.4.0' testImplementation 'androidx.test:rules:1.4.0' diff --git a/src/com/android/car/media/MediaActivity.java b/src/com/android/car/media/MediaActivity.java index 7076daa..76524bf 100644 --- a/src/com/android/car/media/MediaActivity.java +++ b/src/com/android/car/media/MediaActivity.java @@ -64,7 +64,6 @@ import androidx.annotation.Nullable; import androidx.annotation.OptIn; import androidx.core.view.GestureDetectorCompat; import androidx.fragment.app.FragmentActivity; -import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModelProvider; @@ -83,11 +82,10 @@ import com.android.car.media.common.playback.PlaybackViewModel; import com.android.car.media.common.source.MediaModels; import com.android.car.media.common.source.MediaSource; import com.android.car.media.common.source.MediaSourceViewModel; +import com.android.car.media.common.ui.MediaWidgetViewModel; import com.android.car.ui.AlertDialogBuilder; import com.android.car.ui.utils.CarUxRestrictionsUtil; -import java.util.HashMap; -import java.util.Map; import java.util.Objects; /** @@ -772,21 +770,18 @@ public class MediaActivity extends FragmentActivity implements MediaActivityCont return new ViewModelProvider(this).get(MediaActivity.ViewModel.class); } - public static class ViewModel extends AndroidViewModel { + /** State tracking ViewModel for the MediaActivity */ + public static class ViewModel extends MediaWidgetViewModel { - static class MediaServiceState { - Mode mMode = Mode.BROWSING; - BrowseStack mBrowseStack = new BrowseStack(); - String mSearchQuery; - boolean mQueueVisible = false; - boolean mHasPlayableItem = false; - } + private Mode mMode = Mode.BROWSING; + private BrowseStack mBrowseStack = new BrowseStack(); + private String mSearchQuery; + private boolean mHasPlayableItem = false; private boolean mNeedsInitialization = true; private MediaModels[] mModels; private final MutableLiveData<FutureData<MediaSource>> mBrowsedMediaSource = dataOf(FutureData.newLoadingData()); - private final Map<MediaSource, MediaServiceState> mStates = new HashMap<>(); private final MutableLiveData<Boolean> mIsMiniControlsVisible = new MutableLiveData<>(); public ViewModel(@NonNull Application application) { @@ -836,30 +831,12 @@ public class MediaActivity extends FragmentActivity implements MediaActivityCont .getValue(); } - MediaServiceState getSavedState() { - MediaSource source = getMediaSourceValue(); - MediaServiceState state = mStates.get(source); - if (state == null) { - state = new MediaServiceState(); - mStates.put(source, state); - } - return state; - } - void saveMode(Mode mode) { - getSavedState().mMode = mode; + mMode = mode; } Mode getSavedMode() { - return getSavedState().mMode; - } - - void setQueueVisible(boolean visible) { - getSavedState().mQueueVisible = visible; - } - - boolean getQueueVisible() { - return getSavedState().mQueueVisible; + return mMode; } void saveBrowsedMediaSource(MediaSource mediaSource) { @@ -880,23 +857,23 @@ public class MediaActivity extends FragmentActivity implements MediaActivityCont } @NonNull BrowseStack getBrowseStack() { - return getSavedState().mBrowseStack; + return mBrowseStack; } String getSearchQuery() { - return getSavedState().mSearchQuery; + return mSearchQuery; } void setSearchQuery(String searchQuery) { - getSavedState().mSearchQuery = searchQuery; + mSearchQuery = searchQuery; } void setHasPlayableItem(boolean hasPlayableItem) { - getSavedState().mHasPlayableItem = hasPlayableItem; + mHasPlayableItem = hasPlayableItem; } boolean hasPlayableItem() { - return getSavedState().mHasPlayableItem; + return mHasPlayableItem; } } diff --git a/src/com/android/car/media/browse/BrowseViewHolder.java b/src/com/android/car/media/browse/BrowseViewHolder.java index 9df2e58..1247258 100644 --- a/src/com/android/car/media/browse/BrowseViewHolder.java +++ b/src/com/android/car/media/browse/BrowseViewHolder.java @@ -18,6 +18,7 @@ package com.android.car.media.browse; import android.content.Context; import android.text.TextUtils; +import android.util.Log; import android.util.Size; import android.view.LayoutInflater; import android.view.View; @@ -44,6 +45,9 @@ import java.util.stream.Collectors; * Generic {@link RecyclerView.ViewHolder} to use for all views in the {@link BrowseAdapter} */ public class BrowseViewHolder extends RecyclerView.ViewHolder { + + public static final String TAG = "BrowseViewHolder"; + private final TextView mTitle; private final TextView mSubtitle; private final ImageView mAlbumArt; @@ -191,11 +195,19 @@ public class BrowseViewHolder extends RecyclerView.ViewHolder { } private void bindBrowseCustomActions(Context context, BrowseViewData browseViewData) { + int maxVisibleActions = context.getResources().getInteger(R.integer.max_visible_actions); + + if (mCustomActionsContainer == null) { + if (maxVisibleActions > 0) { + Log.e(TAG, "Custom action container null when max actions > 0"); + } + return; //We have nothing to bind to. + } + mCustomActionsContainer.removeAllViews(); mBrowseActionIcons.forEach((it) -> it.maybeCancelLoading(context)); mBrowseActionIcons.clear(); - int maxVisibleActions = context.getResources().getInteger(R.integer.max_visible_actions); int numActions = browseViewData.mCustomBrowseActions.size(); boolean willOverflow = numActions > maxVisibleActions; int actionsToShow = willOverflow ? Math.max(0, maxVisibleActions - 1) : maxVisibleActions; diff --git a/src/com/android/car/media/service/MediaConnectorService.java b/src/com/android/car/media/service/MediaConnectorService.java index c13ae3c..da8c581 100644 --- a/src/com/android/car/media/service/MediaConnectorService.java +++ b/src/com/android/car/media/service/MediaConnectorService.java @@ -209,6 +209,21 @@ public class MediaConnectorService extends LifecycleService { public int onStartCommand(Intent intent, int flags, int startId) { super.onStartCommand(intent, flags, startId); + prepareToStartService(intent, startId); + + // Since this service is started from CarMediaService (which runs in background), we need + // to call startForeground to prevent the system from stopping this service and ANRing. + Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) + .setSmallIcon(R.drawable.ic_music) + .setContentTitle(getResources().getString(R.string.service_notification_title)) + .build(); + startForeground(FOREGROUND_NOTIFICATION_ID, notification); + return START_NOT_STICKY; + } + + /** Setup to perform before the service is started. */ + @VisibleForTesting + void prepareToStartService(Intent intent, int startId) { boolean autoPlay = intent.getBooleanExtra(EXTRA_AUTOPLAY, false); ComponentName mediaComp = getMediaComponentFromIntent(intent); @@ -222,15 +237,6 @@ public class MediaConnectorService extends LifecycleService { // must take precedence, so just create and assign a new TaskInfo. mCurrentTask = new TaskInfo(startId, mediaComp, autoPlay); mPlaybackStateListener.onChanged(mPlaybackLiveData.getValue()); - - // Since this service is started from CarMediaService (which runs in background), we need - // to call startForeground to prevent the system from stopping this service and ANRing. - Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) - .setSmallIcon(R.drawable.ic_music) - .setContentTitle(getResources().getString(R.string.service_notification_title)) - .build(); - startForeground(FOREGROUND_NOTIFICATION_ID, notification); - return START_NOT_STICKY; } private void stopTask() { diff --git a/tests/unittests/src/com/android/car/media/MediaConnectorServiceTests.java b/tests/unittests/src/com/android/car/media/service/MediaConnectorServiceTests.java index 81b0844..bf275fd 100644 --- a/tests/unittests/src/com/android/car/media/MediaConnectorServiceTests.java +++ b/tests/unittests/src/com/android/car/media/service/MediaConnectorServiceTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.car.media; +package com.android.car.media.service; import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY; import static android.support.v4.media.session.PlaybackStateCompat.ACTION_PREPARE; @@ -38,13 +38,14 @@ import android.support.v4.media.session.PlaybackStateCompat; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.MutableLiveData; +import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import com.android.car.apps.common.IconCropper; +import com.android.car.media.BaseMockitoTest; import com.android.car.media.common.playback.PlaybackViewModel.PlaybackStateWrapper; import com.android.car.media.common.source.MediaSource; -import com.android.car.media.service.MediaConnectorService; import org.junit.Before; import org.junit.Test; @@ -68,6 +69,7 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { @Mock private PlaybackStateCompat mState; @Mock MediaControllerCompat.TransportControls mControls; + @UiThreadTest @Before public void setup() { mPlaybackLiveData = dataOf(null); @@ -83,7 +85,7 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { String displayName = browseService.getClassName(); Drawable icon = new ColorDrawable(); IconCropper iconCropper = new IconCropper(new Path()); - return new MediaSource(browseService, displayName, icon, iconCropper); + return new MediaSource(browseService, null, displayName, icon, iconCropper); } private void sendCommand(@Nullable ComponentName source, boolean autoPlay) { @@ -92,7 +94,7 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { if (source != null) { intent.putExtra(CarMediaIntents.EXTRA_MEDIA_COMPONENT, source.flattenToString()); } - mService.onStartCommand(intent, 0, 0); + mService.prepareToStartService(intent, /* startId= */ 0); } private PlaybackStateWrapper newState(ComponentName comp) { @@ -107,15 +109,18 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { PlaybackStateWrapper state = newState(COMP_1_1); - mPlaybackLiveData.setValue(state); + mPlaybackLiveData.postValue(state); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(0)).prepare(); verify(mControls, times(0)).play(); - mPlaybackLiveData.setValue(state); + mPlaybackLiveData.postValue(state); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(1)).prepare(); verify(mControls, times(0)).play(); - mPlaybackLiveData.setValue(state); + mPlaybackLiveData.postValue(state); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(1)).prepare(); verify(mControls, times(1)).play(); } @@ -124,7 +129,8 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { public void onlyPrepareWhenPlayNotEnabled() { when(mState.getActions()).thenReturn(ACTION_PREPARE); sendCommand(COMP_1_1, true); - mPlaybackLiveData.setValue(newState(COMP_1_1)); + mPlaybackLiveData.postValue(newState(COMP_1_1)); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(1)).prepare(); verify(mControls, times(0)).play(); } @@ -133,7 +139,8 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { public void onlyPrepareWhenPlayNotRequested() { when(mState.getActions()).thenReturn(ACTION_PREPARE | ACTION_PLAY); sendCommand(COMP_1_1, false); - mPlaybackLiveData.setValue(newState(COMP_1_1)); + mPlaybackLiveData.postValue(newState(COMP_1_1)); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(1)).prepare(); verify(mControls, times(0)).play(); } @@ -143,11 +150,13 @@ public class MediaConnectorServiceTests extends BaseMockitoTest { when(mState.getActions()).thenReturn(ACTION_PREPARE | ACTION_PLAY); sendCommand(COMP_1_2, true); - mPlaybackLiveData.setValue(newState(COMP_1_1)); + mPlaybackLiveData.postValue(newState(COMP_1_1)); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(0)).prepare(); verify(mControls, times(0)).play(); - mPlaybackLiveData.setValue(newState(COMP_1_2)); + mPlaybackLiveData.postValue(newState(COMP_1_2)); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mControls, times(1)).prepare(); verify(mControls, times(1)).play(); } |