1 /* 2 * Copyright (C) 2023 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 android.car.media; 18 19 import static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.anyString; 21 import static org.mockito.ArgumentMatchers.eq; 22 import static org.mockito.Mockito.doAnswer; 23 import static org.mockito.Mockito.doThrow; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.when; 26 27 import android.car.test.AbstractExpectableTestCase; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.os.IBinder; 31 import android.os.RemoteException; 32 import android.os.UserHandle; 33 import android.platform.test.ravenwood.RavenwoodRule; 34 35 import com.android.car.internal.ICarBase; 36 37 import org.junit.Before; 38 import org.junit.Rule; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.mockito.ArgumentCaptor; 42 import org.mockito.Mock; 43 import org.mockito.junit.MockitoJUnitRunner; 44 45 import java.util.List; 46 47 @RunWith(MockitoJUnitRunner.class) 48 public final class CarMediaManagerUnitTest extends AbstractExpectableTestCase { 49 50 // Need to setup ravenwood rule to stub out Binder.clearCallingIdentity/restoreCallingIdentity 51 // on host. 52 @Rule 53 public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build(); 54 55 private static final int TEST_MODE = CarMediaManager.MEDIA_SOURCE_MODE_BROWSE; 56 private static final int TEST_USER_ID = 100; 57 @Mock 58 private ICarBase mCarMock; 59 @Mock 60 private IBinder mBinderMock; 61 @Mock 62 private Context mContextMock; 63 @Mock 64 private ComponentName mComponentNameMock1; 65 @Mock 66 private ComponentName mComponentNameMock2; 67 @Mock 68 private ICarMedia mServiceMock; 69 @Mock 70 private CarMediaManager.MediaSourceChangedListener mListenerMock; 71 72 private RemoteException mRemoteException = new RemoteException(); 73 private CarMediaManager mMediaManager; 74 75 @Before setUp()76 public void setUp() { 77 when(mBinderMock.queryLocalInterface(anyString())).thenReturn(mServiceMock); 78 when(mCarMock.getContext()).thenReturn(mContextMock); 79 when(mContextMock.getUser()).thenReturn(UserHandle.of(TEST_USER_ID)); 80 mMediaManager = new CarMediaManager(mCarMock, mBinderMock); 81 doAnswer(invocation -> invocation.getArgument(1)).when(mCarMock) 82 .handleRemoteExceptionFromCarService(any(RemoteException.class), any()); 83 } 84 85 @Test testGetMediaSource()86 public void testGetMediaSource() throws Exception { 87 when(mServiceMock.getMediaSource(TEST_MODE, TEST_USER_ID)).thenReturn(mComponentNameMock1); 88 89 expectWithMessage("Media source for browse mode").that(mMediaManager.getMediaSource( 90 TEST_MODE)).isEqualTo(mComponentNameMock1); 91 } 92 93 @Test testGetMediaSource_whenServiceThrowsRemoteException_returnsNull()94 public void testGetMediaSource_whenServiceThrowsRemoteException_returnsNull() throws Exception { 95 doThrow(mRemoteException).when(mServiceMock).getMediaSource(TEST_MODE, TEST_USER_ID); 96 97 expectWithMessage("Media source when service throws remote exception") 98 .that(mMediaManager.getMediaSource(TEST_MODE)).isNull(); 99 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException, null); 100 } 101 102 @Test testSetMediaSource()103 public void testSetMediaSource() throws Exception { 104 mMediaManager.setMediaSource(mComponentNameMock1, TEST_MODE); 105 106 verify(mServiceMock).setMediaSource(mComponentNameMock1, TEST_MODE, TEST_USER_ID); 107 } 108 109 @Test testSetMediaSource_whenServiceThrowsRemoteException()110 public void testSetMediaSource_whenServiceThrowsRemoteException() throws Exception { 111 doThrow(mRemoteException).when(mServiceMock) 112 .setMediaSource(mComponentNameMock1, TEST_MODE, TEST_USER_ID); 113 114 mMediaManager.setMediaSource(mComponentNameMock1, TEST_MODE); 115 116 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException); 117 } 118 119 @Test testAddMediaSourceListener()120 public void testAddMediaSourceListener() throws Exception { 121 mMediaManager.addMediaSourceListener(mListenerMock, TEST_MODE); 122 123 verify(mServiceMock).registerMediaSourceListener(any(), eq(TEST_MODE), eq(TEST_USER_ID)); 124 } 125 126 @Test testAddMediaSourceListener_whenServiceThrowsRemoteException()127 public void testAddMediaSourceListener_whenServiceThrowsRemoteException() throws Exception { 128 doThrow(mRemoteException).when(mServiceMock).registerMediaSourceListener(any(), 129 eq(TEST_MODE), eq(TEST_USER_ID)); 130 131 mMediaManager.addMediaSourceListener(mListenerMock, TEST_MODE); 132 133 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException); 134 } 135 136 @Test testOnMediaSourceChanged_forMediaSourceListener()137 public void testOnMediaSourceChanged_forMediaSourceListener() throws Exception { 138 ArgumentCaptor<ICarMediaSourceListener> serviceListenerCaptor = ArgumentCaptor.forClass( 139 ICarMediaSourceListener.class); 140 mMediaManager.addMediaSourceListener(mListenerMock, TEST_MODE); 141 verify(mServiceMock).registerMediaSourceListener(serviceListenerCaptor.capture(), 142 eq(TEST_MODE), eq(TEST_USER_ID)); 143 ICarMediaSourceListener serviceListener = serviceListenerCaptor.getValue(); 144 145 serviceListener.onMediaSourceChanged(mComponentNameMock2); 146 147 verify(mListenerMock).onMediaSourceChanged(mComponentNameMock2); 148 } 149 150 @Test testRemoveMediaSourceListener()151 public void testRemoveMediaSourceListener() throws Exception { 152 ArgumentCaptor<ICarMediaSourceListener> serviceListenerCaptor = ArgumentCaptor.forClass( 153 ICarMediaSourceListener.class); 154 mMediaManager.addMediaSourceListener(mListenerMock, TEST_MODE); 155 verify(mServiceMock).registerMediaSourceListener(serviceListenerCaptor.capture(), 156 eq(TEST_MODE), eq(TEST_USER_ID)); 157 158 mMediaManager.removeMediaSourceListener(mListenerMock, TEST_MODE); 159 160 verify(mServiceMock).unregisterMediaSourceListener(serviceListenerCaptor.getValue(), 161 TEST_MODE, TEST_USER_ID); 162 } 163 164 @Test testRemoveMediaSourceListener_whenServiceThrowsRemoteException()165 public void testRemoveMediaSourceListener_whenServiceThrowsRemoteException() throws Exception { 166 doThrow(mRemoteException).when(mServiceMock).unregisterMediaSourceListener(any(), 167 eq(TEST_MODE), eq(TEST_USER_ID)); 168 169 mMediaManager.removeMediaSourceListener(mListenerMock, TEST_MODE); 170 171 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException); 172 } 173 174 @Test testGetLastMediaSources()175 public void testGetLastMediaSources() throws RemoteException { 176 List<ComponentName> lastMediaSources = List.of(mComponentNameMock1, mComponentNameMock1); 177 when(mServiceMock.getLastMediaSources(TEST_MODE, TEST_USER_ID)) 178 .thenReturn(lastMediaSources); 179 180 expectWithMessage("Last media sources").that(mMediaManager.getLastMediaSources( 181 TEST_MODE)).containsExactlyElementsIn(lastMediaSources); 182 } 183 184 @Test testGetLastMediaSources_whenServiceThrowsRemoteException_returnsNull()185 public void testGetLastMediaSources_whenServiceThrowsRemoteException_returnsNull() throws 186 RemoteException { 187 doThrow(mRemoteException).when(mServiceMock).getLastMediaSources(TEST_MODE, TEST_USER_ID); 188 189 expectWithMessage("Last media sources").that(mMediaManager.getLastMediaSources( 190 TEST_MODE)).isNull(); 191 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException, null); 192 } 193 194 @Test testIsIndependentPlaybackConfig()195 public void testIsIndependentPlaybackConfig() throws RemoteException { 196 when(mServiceMock.isIndependentPlaybackConfig(TEST_USER_ID)).thenReturn(true); 197 198 expectWithMessage("Independent playback config").that(mMediaManager 199 .isIndependentPlaybackConfig()).isTrue(); 200 } 201 202 @Test testIsIndependentPlaybackConfig_whenServiceThrowsRemoteException_returnFalse()203 public void testIsIndependentPlaybackConfig_whenServiceThrowsRemoteException_returnFalse() 204 throws RemoteException { 205 doThrow(mRemoteException).when(mServiceMock).isIndependentPlaybackConfig(TEST_USER_ID); 206 207 expectWithMessage("Independent playback config when service throws remote exception") 208 .that(mMediaManager.isIndependentPlaybackConfig()).isFalse(); 209 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException, false); 210 } 211 212 @Test testSetIndependentPlaybackConfig()213 public void testSetIndependentPlaybackConfig() throws 214 RemoteException { 215 mMediaManager.setIndependentPlaybackConfig(true); 216 217 verify(mServiceMock).setIndependentPlaybackConfig(true, TEST_USER_ID); 218 } 219 220 @Test testSetIndependentPlaybackConfig_whenServiceThrowsRemoteException()221 public void testSetIndependentPlaybackConfig_whenServiceThrowsRemoteException() throws 222 RemoteException { 223 doThrow(mRemoteException).when(mServiceMock) 224 .setIndependentPlaybackConfig(true, TEST_USER_ID); 225 226 mMediaManager.setIndependentPlaybackConfig(true); 227 228 verify(mCarMock).handleRemoteExceptionFromCarService(mRemoteException); 229 } 230 } 231