1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.car.ndo; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.eq; 23 import static org.mockito.ArgumentMatchers.isNull; 24 import static org.mockito.Mockito.mock; 25 import static org.mockito.Mockito.spy; 26 import static org.mockito.Mockito.times; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.app.INotificationManager; 31 import android.app.Notification; 32 import android.media.session.MediaController; 33 import android.media.session.MediaSessionManager; 34 import android.media.session.PlaybackState; 35 import android.os.Bundle; 36 import android.os.UserHandle; 37 import android.service.notification.StatusBarNotification; 38 import android.testing.AndroidTestingRunner; 39 import android.testing.TestableLooper; 40 41 import androidx.test.filters.SmallTest; 42 43 import com.android.systemui.CarSysuiTestCase; 44 import com.android.systemui.car.CarSystemUiTest; 45 import com.android.systemui.lifecycle.InstantTaskExecutorRule; 46 47 import org.junit.Before; 48 import org.junit.Rule; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 54 import java.util.ArrayList; 55 import java.util.List; 56 57 @CarSystemUiTest 58 @RunWith(AndroidTestingRunner.class) 59 @TestableLooper.RunWithLooper 60 @SmallTest 61 public class MediaSessionHelperTest extends CarSysuiTestCase { 62 63 private MediaSessionHelper mMediaSessionHelper; 64 private final UserHandle mUserHandle = UserHandle.CURRENT; 65 private MediaController mActiveMediaController; 66 private MediaController mInactiveMediaController; 67 68 @Rule 69 public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule(); 70 71 @Mock 72 private MediaSessionManager mMediaSessionManager; 73 @Mock 74 private INotificationManager mINotificationManager; 75 @Mock 76 private StatusBarNotification mStatusBarNotification; 77 @Mock 78 private Notification mNotification; 79 80 @Before setup()81 public void setup() throws Exception { 82 MockitoAnnotations.initMocks(/* testClass= */ this); 83 mContext = spy(mContext); 84 when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mMediaSessionManager); 85 86 StatusBarNotification[] statusBarNotifications = { mStatusBarNotification }; 87 when(mINotificationManager.getActiveNotificationsWithAttribution( 88 eq(mContext.getPackageName()), isNull())).thenReturn(statusBarNotifications); 89 when(mStatusBarNotification.getNotification()).thenReturn(mNotification); 90 mNotification.extras = new Bundle(); 91 92 mActiveMediaController = mock(MediaController.class); 93 PlaybackState activePlaybackState = mock(PlaybackState.class); 94 when(mActiveMediaController.getPlaybackState()).thenReturn(activePlaybackState); 95 when(activePlaybackState.isActive()).thenReturn(true); 96 97 mInactiveMediaController = mock(MediaController.class); 98 PlaybackState inActivePlaybackState = mock(PlaybackState.class); 99 when(mInactiveMediaController.getPlaybackState()).thenReturn(inActivePlaybackState); 100 when(inActivePlaybackState.isActive()).thenReturn(false); 101 102 List<MediaController> mediaControllers = new ArrayList<>(); 103 mediaControllers.add(mActiveMediaController); 104 mediaControllers.add(mInactiveMediaController); 105 when(mMediaSessionManager.getActiveSessionsForUser(isNull(), eq(mUserHandle))) 106 .thenReturn(mediaControllers); 107 108 mMediaSessionHelper = new MediaSessionHelper(mContext, mINotificationManager); 109 mMediaSessionHelper.init(mUserHandle); 110 } 111 112 @Test onCreate_setsInitialValue()113 public void onCreate_setsInitialValue() { 114 assertThat(mMediaSessionHelper.getActiveMediaSessions().getValue().size()) 115 .isEqualTo(0); 116 assertThat(mMediaSessionHelper.mMediaControllersList.size()).isEqualTo(2); 117 } 118 119 @Test onActivePlaybackStateChanged_hasMediaNotification_queriesNewMediaSessions()120 public void onActivePlaybackStateChanged_hasMediaNotification_queriesNewMediaSessions() { 121 PlaybackState playbackState = mock(PlaybackState.class); 122 when(playbackState.isActive()).thenReturn(true); 123 when(mNotification.isMediaNotification()).thenReturn(true); 124 125 mMediaSessionHelper.onPlaybackStateChanged(playbackState); 126 127 assertThat(mMediaSessionHelper.getActiveMediaSessions().getValue().size()) 128 .isEqualTo(1); 129 assertThat(mMediaSessionHelper.getActiveMediaSessions().getValue().getFirst()) 130 .isEqualTo(mActiveMediaController); 131 assertThat(mMediaSessionHelper.mMediaControllersList.size()).isEqualTo(1); 132 assertThat(mMediaSessionHelper.mMediaControllersList.getFirst()) 133 .isEqualTo(mInactiveMediaController); 134 } 135 136 @Test onActivePlaybackStateChanged_noMediaNotification_queriesNewMediaSessions()137 public void onActivePlaybackStateChanged_noMediaNotification_queriesNewMediaSessions() { 138 PlaybackState playbackState = mock(PlaybackState.class); 139 when(playbackState.isActive()).thenReturn(true); 140 when(mNotification.isMediaNotification()).thenReturn(false); 141 142 mMediaSessionHelper.onPlaybackStateChanged(playbackState); 143 144 assertThat(mMediaSessionHelper.getActiveMediaSessions().getValue().size()) 145 .isEqualTo(0); 146 assertThat(mMediaSessionHelper.mMediaControllersList.size()).isEqualTo(2); 147 } 148 149 @Test onInactivePlaybackStateChanged_doesNothing()150 public void onInactivePlaybackStateChanged_doesNothing() { 151 PlaybackState playbackState = mock(PlaybackState.class); 152 when(playbackState.isActive()).thenReturn(false); 153 when(mNotification.isMediaNotification()).thenReturn(true); 154 155 mMediaSessionHelper.onPlaybackStateChanged(playbackState); 156 157 // One time from initialization 158 verify(mMediaSessionManager, times(1)).getActiveSessionsForUser(isNull(), eq(mUserHandle)); 159 } 160 161 @Test onCleanup_removesListeners()162 public void onCleanup_removesListeners() { 163 mMediaSessionHelper.mMediaControllersList.add(mock(MediaController.class)); 164 165 mMediaSessionHelper.cleanup(); 166 167 assertThat(mMediaSessionHelper.mMediaControllersList.isEmpty()).isTrue(); 168 verify(mMediaSessionManager).removeOnActiveSessionsChangedListener(any()); 169 } 170 } 171