/* * Copyright (C) 2019 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.panel; import static com.android.settings.media.MediaOutputSlice.MEDIA_PACKAGE_NAME; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.media.MediaDescription; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.net.Uri; import com.android.settings.R; import com.android.settings.slices.CustomSliceRegistry; import com.android.settingslib.media.InfoMediaDevice; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.PhoneMediaDevice; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) public class MediaOutputPanelTest { private static final String TEST_PACKAGENAME = "com.test.packagename"; private static final String TEST_PACKAGENAME2 = "com.test.packagename2"; private static final String TEST_ARTIST = "test_artist"; private static final String TEST_SONG = "test_song"; @Mock private MediaSessionManager mMediaSessionManager; @Mock private MediaController mMediaController; @Mock private MediaMetadata mMediaMetadata; @Mock private LocalMediaManager mLocalMediaManager; @Mock private PanelContentCallback mCallback; @Mock private PlaybackState mPlaybackState; private MediaOutputPanel mPanel; private Context mContext; private List mMediaControllers = new ArrayList<>(); private ArgumentCaptor mControllerCbs = ArgumentCaptor.forClass(MediaController.Callback.class); private MediaDescription mMediaDescription; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); mMediaControllers.add(mMediaController); when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGENAME); when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers); when(mContext.getApplicationContext()).thenReturn(mContext); when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mMediaSessionManager); MediaDescription.Builder builder = new MediaDescription.Builder(); builder.setTitle(TEST_SONG); builder.setSubtitle(TEST_ARTIST); mMediaDescription = builder.build(); when(mMediaMetadata.getDescription()).thenReturn(mMediaDescription); mPanel = MediaOutputPanel.create(mContext, TEST_PACKAGENAME); mPanel.mLocalMediaManager = mLocalMediaManager; mPanel.registerCallback(mCallback); } @Test public void getSlices_containsNecessarySlices() { final List uris = mPanel.getSlices(); assertThat(uris).containsExactly(CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI); } @Test public void getSlices_verifyPackageName_isEqual() { final List uris = mPanel.getSlices(); assertThat(uris.get(0).getQueryParameter(MEDIA_PACKAGE_NAME)).isEqualTo(TEST_PACKAGENAME); } @Test public void getSeeMoreIntent_isNull() { assertThat(mPanel.getSeeMoreIntent()).isNull(); } @Test public void onStart_shouldRegisterCallback() { mPanel.onStart(); verify(mMediaController).registerCallback(any()); verify(mLocalMediaManager).registerCallback(any()); verify(mLocalMediaManager).startScan(); } @Test public void onStart_activeSession_verifyOnHeaderChanged() { mPanel.onStart(); verify(mCallback).onHeaderChanged(); } @Test public void onStart_noMatchedActiveSession_verifyNeverOnHeaderChanged() { when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGENAME2); mPanel.onStart(); verify(mCallback, never()).onHeaderChanged(); } @Test public void onStop_shouldUnregisterCallback() { mPanel.onStop(); verify(mLocalMediaManager).unregisterCallback(any()); verify(mLocalMediaManager).stopScan(); } @Test public void onSelectedDeviceStateChanged_shouldDispatchCustomButtonStateChanged() { mPanel.onSelectedDeviceStateChanged(null, 0); verify(mCallback).onCustomizedButtonStateChanged(); } @Test public void onDeviceListUpdate_shouldDispatchCustomButtonStateChanged() { mPanel.onDeviceListUpdate(null); verify(mCallback).onCustomizedButtonStateChanged(); } @Test public void onDeviceAttributesChanged_shouldDispatchCustomButtonStateChanged() { mPanel.onDeviceAttributesChanged(); verify(mCallback).onCustomizedButtonStateChanged(); } @Test public void currentConnectDeviceIsInfoDevice_useCustomButtonIsTrue() { final InfoMediaDevice infoMediaDevice = mock(InfoMediaDevice.class); when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(infoMediaDevice); mPanel.onDeviceAttributesChanged(); assertThat(mPanel.isCustomizedButtonUsed()).isTrue(); } @Test public void currentConnectDeviceIsNotInfoDevice_useCustomButtonIsFalse() { final PhoneMediaDevice phoneMediaDevice = mock(PhoneMediaDevice.class); when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(phoneMediaDevice); mPanel.onDeviceAttributesChanged(); assertThat(mPanel.isCustomizedButtonUsed()).isFalse(); } @Test public void getTitle_withMetadata_returnSongName() { mPanel.onStart(); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); assertThat(mPanel.getTitle()).isEqualTo(TEST_SONG); } @Test public void getTitle_noMetadata_returnDefaultString() { when(mMediaController.getMetadata()).thenReturn(null); assertThat(mPanel.getTitle()).isEqualTo(mContext.getText(R.string.media_volume_title)); } @Test public void getTitle_noPackageName_returnDefaultString() { mPanel = MediaOutputPanel.create(mContext, null); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); assertThat(mPanel.getTitle()).isEqualTo(mContext.getText(R.string.media_volume_title)); } @Test public void getTitle_noController_defaultString() { mMediaControllers.clear(); when(mMediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST)).thenReturn(TEST_ARTIST); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); mPanel = MediaOutputPanel.create(mContext, TEST_PACKAGENAME); assertThat(mPanel.getTitle()).isEqualTo(mContext.getText(R.string.media_volume_title)); } @Test public void getSubTitle_withMetadata_returnArtistName() { mPanel.onStart(); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); assertThat(mPanel.getSubTitle()).isEqualTo(TEST_ARTIST); } @Test public void getSubTitle_noMetadata_returnDefault() { when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGENAME); when(mMediaController.getMetadata()).thenReturn(null); assertThat(mPanel.getSubTitle()).isEqualTo(mContext.getText( R.string.media_output_panel_title)); } @Test public void getSubTitle_noPackageName_returnDefault() { mPanel = MediaOutputPanel.create(mContext, null); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); assertThat(mPanel.getSubTitle()).isEqualTo(mContext.getText( R.string.media_output_panel_title)); } @Test public void getSubTitle_noController_returnDefault() { mMediaControllers.clear(); mPanel = MediaOutputPanel.create(mContext, TEST_PACKAGENAME); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); assertThat(mPanel.getSubTitle()).isEqualTo(mContext.getText( R.string.media_output_panel_title)); } @Test public void onClickCustomizedButton_shouldReleaseSession() { mPanel.onClickCustomizedButton(); verify(mLocalMediaManager).releaseSession(); } @Test public void onMetadataChanged_verifyCallOnHeaderChanged() { mPanel.onStart(); verify(mCallback).onHeaderChanged(); verify(mMediaController).registerCallback(mControllerCbs.capture()); final MediaController.Callback controllerCallbacks = mControllerCbs.getValue(); controllerCallbacks.onMetadataChanged(mMediaMetadata); verify(mCallback, times(2)).onHeaderChanged(); } @Test public void onPlaybackStateChanged_stateFromPlayingToStopped_verifyCallForceClose() { mPanel.onStart(); verify(mMediaController).registerCallback(mControllerCbs.capture()); final MediaController.Callback controllerCallbacks = mControllerCbs.getValue(); when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING); controllerCallbacks.onPlaybackStateChanged(mPlaybackState); verify(mCallback, never()).forceClose(); when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_STOPPED); controllerCallbacks.onPlaybackStateChanged(mPlaybackState); verify(mCallback).forceClose(); } @Test public void onPlaybackStateChanged_stateFromPlayingToPaused_verifyCallForceClose() { mPanel.onStart(); verify(mMediaController).registerCallback(mControllerCbs.capture()); final MediaController.Callback controllerCallbacks = mControllerCbs.getValue(); when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING); controllerCallbacks.onPlaybackStateChanged(mPlaybackState); verify(mCallback, never()).forceClose(); when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PAUSED); controllerCallbacks.onPlaybackStateChanged(mPlaybackState); verify(mCallback).forceClose(); } @Test public void getViewType_checkType() { assertThat(mPanel.getViewType()).isEqualTo(PanelContent.VIEW_TYPE_SLIDER_LARGE_ICON); } }