1 /* 2 * Copyright (C) 2022 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 package android.car.content.pm; 17 18 import static android.view.Display.DEFAULT_DISPLAY; 19 20 import static com.google.common.truth.Truth.assertThat; 21 22 import static org.junit.Assert.assertThrows; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.car.CarVersion; 30 import android.content.Context; 31 import android.content.pm.PackageManager.NameNotFoundException; 32 import android.os.RemoteException; 33 import android.os.ServiceSpecificException; 34 import android.platform.test.annotations.DisabledOnRavenwood; 35 import android.platform.test.ravenwood.RavenwoodRule; 36 37 import com.android.car.internal.ICarBase; 38 39 import org.junit.Before; 40 import org.junit.Rule; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 import org.mockito.Mock; 44 import org.mockito.junit.MockitoJUnitRunner; 45 46 import java.util.concurrent.Executor; 47 48 @RunWith(MockitoJUnitRunner.class) 49 public final class CarPackageManagerUnitTest { 50 51 // Need to fake Process.myUserHandle(). 52 @Rule 53 public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() 54 .setProcessApp() 55 .build(); 56 57 @Mock 58 private ICarBase mCar; 59 60 @Mock 61 private ICarPackageManager mService; 62 63 @Mock 64 private Executor mExecutor; 65 66 @Mock 67 private CarPackageManager.BlockingUiCommandListener mBlockingUiCommandListener; 68 69 private CarPackageManager mMgr; 70 71 @Before setFixtures()72 public void setFixtures() { 73 mMgr = new CarPackageManager(mCar, mService); 74 } 75 76 @Test testGetTargetCarVersion_self_ok()77 public void testGetTargetCarVersion_self_ok() throws Exception { 78 mockPackageName("dr.evil"); 79 CarVersion apiVersion = CarVersion.forMajorAndMinorVersions(66, 6); 80 when(mService.getSelfTargetCarVersion("dr.evil")).thenReturn(apiVersion); 81 82 assertThat(mMgr.getTargetCarVersion()).isSameInstanceAs(apiVersion); 83 } 84 85 @Test testGetTargetCarVersion_self_remoteException()86 public void testGetTargetCarVersion_self_remoteException() throws Exception { 87 mockPackageName("the.meaning.of.life"); 88 RemoteException cause = new RemoteException("D'OH!"); 89 when(mService.getSelfTargetCarVersion("the.meaning.of.life")).thenThrow(cause); 90 91 RuntimeException e = assertThrows(RuntimeException.class, () -> mMgr.getTargetCarVersion()); 92 93 assertThat(e.getCause()).isSameInstanceAs(cause); 94 } 95 96 @Test testGetTargetCarVersion_ok()97 public void testGetTargetCarVersion_ok() throws Exception { 98 CarVersion apiVersion = CarVersion.forMajorAndMinorVersions(66, 6); 99 when(mService.getTargetCarVersion("dr.evil")).thenReturn(apiVersion); 100 101 assertThat(mMgr.getTargetCarVersion("dr.evil")).isSameInstanceAs(apiVersion); 102 } 103 104 @Test testGetTargetCarVersion_runtimeException()105 public void testGetTargetCarVersion_runtimeException() throws Exception { 106 RemoteException cause = new RemoteException("D'OH!"); 107 when(mService.getTargetCarVersion("the.meaning.of.life")).thenThrow(cause); 108 109 RuntimeException e = assertThrows(RuntimeException.class, 110 () -> mMgr.getTargetCarVersion("the.meaning.of.life")); 111 112 assertThat(e.getCause()).isSameInstanceAs(cause); 113 } 114 115 @Test testGetTargetCarVersion_serviceException_unexpectedErrorCode()116 public void testGetTargetCarVersion_serviceException_unexpectedErrorCode() throws Exception { 117 ServiceSpecificException cause = new ServiceSpecificException(666, "D'OH!"); 118 when(mService.getTargetCarVersion("the.meaning.of.life")).thenThrow(cause); 119 120 IllegalStateException e = assertThrows(IllegalStateException.class, 121 () -> mMgr.getTargetCarVersion("the.meaning.of.life")); 122 123 assertThat(e.getCause()).isSameInstanceAs(cause); 124 } 125 126 @Test 127 @DisabledOnRavenwood(blockedBy = NameNotFoundException.class) testGetTargetCarVersion_serviceException_notFound()128 public void testGetTargetCarVersion_serviceException_notFound() throws Exception { 129 when(mService.getTargetCarVersion("the.meaning.of.life")) 130 .thenThrow(new ServiceSpecificException(CarPackageManager.ERROR_CODE_NO_PACKAGE, 131 "D'OH!")); 132 133 NameNotFoundException e = assertThrows(NameNotFoundException.class, 134 () -> mMgr.getTargetCarVersion("the.meaning.of.life")); 135 136 assertThat(e.getMessage()).contains("the.meaning.of.life"); 137 assertThat(e.getMessage()).doesNotContain("D'OH!"); 138 } 139 140 @Test registerBlockingUiCommandListener()141 public void registerBlockingUiCommandListener() throws Exception { 142 mMgr.registerBlockingUiCommandListener(DEFAULT_DISPLAY, mExecutor, 143 mBlockingUiCommandListener); 144 145 verify(mService).registerBlockingUiCommandListener(any(), anyInt()); 146 } 147 148 @Test registerBlockingUiCommandListener_sameListenerNotRegisterForAnotherDisplay()149 public void registerBlockingUiCommandListener_sameListenerNotRegisterForAnotherDisplay() 150 throws Exception { 151 int tempDisplayId = 1; 152 153 mMgr.registerBlockingUiCommandListener(DEFAULT_DISPLAY, mExecutor, 154 mBlockingUiCommandListener); 155 156 assertThrows(IllegalStateException.class, 157 () -> mMgr.registerBlockingUiCommandListener(tempDisplayId, mExecutor, 158 mBlockingUiCommandListener)); 159 } 160 161 @Test unregisterBlockingUiCommandListener()162 public void unregisterBlockingUiCommandListener() throws Exception { 163 mMgr.registerBlockingUiCommandListener(DEFAULT_DISPLAY, mExecutor, 164 mBlockingUiCommandListener); 165 166 mMgr.unregisterBlockingUiCommandListener(mBlockingUiCommandListener); 167 168 verify(mService).unregisterBlockingUiCommandListener(any()); 169 } 170 mockPackageName(String name)171 private void mockPackageName(String name) { 172 Context context = mock(Context.class); 173 when(context.getPackageName()).thenReturn(name); 174 when(mCar.getContext()).thenReturn(context); 175 } 176 } 177