Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2019 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.car; |
| 18 | |
| 19 | import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; |
| 20 | |
| 21 | import static com.google.common.truth.Truth.assertThat; |
| 22 | |
| 23 | import static org.junit.Assert.fail; |
Keun young Park | 2c104d6 | 2020-04-09 14:03:33 -0700 | [diff] [blame] | 24 | import static org.mockito.ArgumentMatchers.anyInt; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 25 | import static org.mockito.Mockito.doReturn; |
| 26 | import static org.mockito.Mockito.when; |
| 27 | import static org.testng.Assert.assertThrows; |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 28 | import static org.testng.Assert.expectThrows; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 29 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 30 | import android.annotation.UserIdInt; |
Keun young Park | c8c565a | 2019-10-11 16:13:34 -0700 | [diff] [blame] | 31 | import android.car.Car; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 32 | import android.car.CarOccupantZoneManager; |
| 33 | import android.car.CarOccupantZoneManager.OccupantZoneInfo; |
| 34 | import android.car.VehicleAreaSeat; |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 35 | import android.car.media.CarAudioManager; |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 36 | import android.car.user.CarUserManager; |
| 37 | import android.car.user.CarUserManager.UserLifecycleEvent; |
Yuncheol Heo | eef96c8 | 2020-05-21 10:51:20 -0700 | [diff] [blame] | 38 | import android.content.ComponentName; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 39 | import android.content.Context; |
Kai | 4156274 | 2020-03-13 15:04:25 -0700 | [diff] [blame] | 40 | import android.content.pm.ApplicationInfo; |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 41 | import android.content.pm.UserInfo; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 42 | import android.content.res.Resources; |
| 43 | import android.hardware.display.DisplayManager; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 44 | import android.os.Looper; |
Yuncheol Heo | eef96c8 | 2020-05-21 10:51:20 -0700 | [diff] [blame] | 45 | import android.os.RemoteException; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 46 | import android.os.UserHandle; |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 47 | import android.os.UserManager; |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 48 | import android.util.SparseArray; |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 49 | import android.util.SparseIntArray; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 50 | import android.view.Display; |
| 51 | import android.view.DisplayAddress; |
| 52 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 53 | import com.android.car.CarOccupantZoneService.DisplayConfig; |
| 54 | import com.android.car.CarOccupantZoneService.DisplayInfo; |
| 55 | import com.android.car.CarOccupantZoneService.OccupantConfig; |
Mayank Garg | 94f3eb9 | 2020-08-12 12:38:58 -0700 | [diff] [blame^] | 56 | import com.android.car.internal.ICarServiceHelper; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 57 | import com.android.car.user.CarUserService; |
| 58 | |
| 59 | import org.junit.After; |
| 60 | import org.junit.Before; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 61 | import org.junit.Test; |
| 62 | import org.junit.runner.RunWith; |
| 63 | import org.mockito.Mock; |
Mayank Garg | 42d83a1 | 2019-10-21 14:46:57 -0700 | [diff] [blame] | 64 | import org.mockito.junit.MockitoJUnitRunner; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 65 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 66 | import java.util.ArrayList; |
| 67 | import java.util.Arrays; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 68 | import java.util.HashMap; |
| 69 | import java.util.LinkedList; |
| 70 | import java.util.List; |
| 71 | import java.util.concurrent.Semaphore; |
| 72 | import java.util.concurrent.TimeUnit; |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 73 | import java.util.stream.Collectors; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 74 | |
Mayank Garg | 42d83a1 | 2019-10-21 14:46:57 -0700 | [diff] [blame] | 75 | @RunWith(MockitoJUnitRunner.class) |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 76 | public class CarOccupantZoneServiceTest { |
| 77 | |
| 78 | private static final String TAG = CarOccupantZoneServiceTest.class.getSimpleName(); |
| 79 | |
| 80 | private CarOccupantZoneService mService; |
| 81 | private CarOccupantZoneManager mManager; |
| 82 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 83 | @Mock |
| 84 | private CarPropertyService mCarPropertyService; |
| 85 | |
| 86 | @Mock |
| 87 | private CarUserService mCarUserService; |
| 88 | |
| 89 | @Mock |
| 90 | private Context mContext; |
| 91 | |
| 92 | @Mock |
| 93 | private DisplayManager mDisplayManager; |
| 94 | |
| 95 | @Mock |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 96 | private UserManager mUserManager; |
| 97 | |
| 98 | @Mock |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 99 | private Resources mResources; |
| 100 | |
| 101 | @Mock |
| 102 | private Display mDisplay0; |
| 103 | |
| 104 | @Mock |
| 105 | private Display mDisplay1; |
| 106 | |
| 107 | @Mock |
| 108 | private Display mDisplay2; |
| 109 | |
| 110 | @Mock |
| 111 | private Display mDisplay3; // not listed by default |
| 112 | |
| 113 | @Mock |
| 114 | private Display mDisplay4; |
| 115 | |
| 116 | @Mock |
| 117 | private Display mDisplay5; // outside display config and become unknown display |
| 118 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 119 | private static final int CURRENT_USER = 100; |
| 120 | private static final int PROFILE_USER1 = 1001; |
| 121 | private static final int PROFILE_USER2 = 1002; |
| 122 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 123 | private static final String[] DEFAULT_OCCUPANT_ZONES = { |
| 124 | "occupantZoneId=0,occupantType=DRIVER,seatRow=1,seatSide=driver", |
| 125 | "occupantZoneId=1,occupantType=FRONT_PASSENGER,seatRow=1,seatSide=oppositeDriver", |
| 126 | "occupantZoneId=2,occupantType=REAR_PASSENGER,seatRow=2,seatSide=left", |
| 127 | "occupantZoneId=3,occupantType=REAR_PASSENGER,seatRow=2,seatSide=right" |
| 128 | }; |
| 129 | |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 130 | private static final int PRIMARY_AUDIO_ZONE_ID = 0; |
| 131 | private static final int PRIMARY_AUDIO_ZONE_ID_OCCUPANT = 0; |
| 132 | private static final int SECONDARY_AUDIO_ZONE_ID = 1; |
| 133 | private static final int SECONDARY_AUDIO_ZONE_ID_OCCUPANT = 3; |
| 134 | private static final int UNMAPPED_AUDIO_ZONE_ID_OCCUPANT = 2; |
| 135 | private static final int INVALID_AUDIO_ZONE_ID_OCCUPANT = 100; |
| 136 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 137 | // LHD : Left Hand Drive |
| 138 | private final OccupantZoneInfo mZoneDriverLHD = new OccupantZoneInfo(0, |
| 139 | CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER, |
| 140 | VehicleAreaSeat.SEAT_ROW_1_LEFT); |
| 141 | private final OccupantZoneInfo mZoneFrontPassengerLHD = new OccupantZoneInfo(1, |
| 142 | CarOccupantZoneManager.OCCUPANT_TYPE_FRONT_PASSENGER, |
| 143 | VehicleAreaSeat.SEAT_ROW_1_RIGHT); |
| 144 | private final OccupantZoneInfo mZoneRearLeft = new OccupantZoneInfo(2, |
| 145 | CarOccupantZoneManager.OCCUPANT_TYPE_REAR_PASSENGER, |
| 146 | VehicleAreaSeat.SEAT_ROW_2_LEFT); |
| 147 | private final OccupantZoneInfo mZoneRearRight = new OccupantZoneInfo(3, |
| 148 | CarOccupantZoneManager.OCCUPANT_TYPE_REAR_PASSENGER, |
| 149 | VehicleAreaSeat.SEAT_ROW_2_RIGHT); |
| 150 | |
| 151 | // port address set to mocked displayid + 10 so that any possible mix of port address and |
| 152 | // display id can be detected. |
| 153 | private static final String[] DEFAULT_OCCUPANT_DISPLAY_MAPPING = { |
| 154 | "displayPort=10,displayType=MAIN,occupantZoneId=0", |
| 155 | "displayPort=11,displayType=INSTRUMENT_CLUSTER,occupantZoneId=0", |
| 156 | "displayPort=12,displayType=MAIN,occupantZoneId=1", |
| 157 | "displayPort=13,displayType=MAIN,occupantZoneId=2", |
| 158 | "displayPort=14,displayType=MAIN,occupantZoneId=3" |
| 159 | }; |
| 160 | |
| 161 | // Stores last changeFlags from onOccupantZoneConfigChanged call. |
| 162 | private int mLastChangeFlags; |
| 163 | private final Semaphore mChangeEventSignal = new Semaphore(0); |
| 164 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 165 | private final ICarServiceHelperImpl mICarServiceHelper = new ICarServiceHelperImpl(); |
| 166 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 167 | private final CarOccupantZoneManager.OccupantZoneConfigChangeListener mChangeListener = |
| 168 | new CarOccupantZoneManager.OccupantZoneConfigChangeListener() { |
| 169 | @Override |
| 170 | public void onOccupantZoneConfigChanged(int changeFlags) { |
| 171 | // should be dispatched to main thread. |
| 172 | assertThat(Looper.getMainLooper()).isEqualTo(Looper.myLooper()); |
| 173 | mLastChangeFlags = changeFlags; |
| 174 | mChangeEventSignal.release(); |
| 175 | } |
| 176 | }; |
| 177 | |
| 178 | private void resetConfigChangeEventWait() { |
| 179 | mLastChangeFlags = 0; |
| 180 | mChangeEventSignal.drainPermits(); |
| 181 | } |
| 182 | |
| 183 | private boolean waitForConfigChangeEventAndAssertFlag(long timeoutMs, int expectedFlag) { |
| 184 | boolean acquired = false; |
| 185 | try { |
| 186 | acquired = mChangeEventSignal.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); |
| 187 | } catch (Exception ignored) { |
| 188 | |
| 189 | } |
| 190 | if (acquired) { |
| 191 | assertThat(expectedFlag).isEqualTo(mLastChangeFlags); |
| 192 | } |
| 193 | return acquired; |
| 194 | } |
| 195 | |
| 196 | private void mockDisplay(DisplayManager displayManager, Display display, int displayId, |
| 197 | int portAddress) { |
| 198 | when(displayManager.getDisplay(displayId)).thenReturn(display); |
| 199 | when(display.getDisplayId()).thenReturn(displayId); |
| 200 | when(display.getAddress()).thenReturn(DisplayAddress.fromPhysicalDisplayId(portAddress)); |
| 201 | } |
| 202 | |
| 203 | @Before |
| 204 | public void setUp() { |
| 205 | when(mContext.getResources()).thenReturn(mResources); |
| 206 | when(mContext.getSystemService(DisplayManager.class)).thenReturn(mDisplayManager); |
| 207 | when(mResources.getStringArray(R.array.config_occupant_zones)) |
| 208 | .thenReturn(DEFAULT_OCCUPANT_ZONES); |
| 209 | when(mResources.getStringArray(R.array.config_occupant_display_mapping)) |
| 210 | .thenReturn(DEFAULT_OCCUPANT_DISPLAY_MAPPING); |
Kai | 4156274 | 2020-03-13 15:04:25 -0700 | [diff] [blame] | 211 | when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo()); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 212 | // Stored as static: Other tests can leave things behind and fail this test in add call. |
| 213 | // So just remove as safety guard. |
| 214 | CarLocalServices.removeServiceForTest(CarPropertyService.class); |
| 215 | CarLocalServices.addService(CarPropertyService.class, mCarPropertyService); |
| 216 | CarLocalServices.removeServiceForTest(CarUserService.class); |
| 217 | CarLocalServices.addService(CarUserService.class, mCarUserService); |
| 218 | mockDisplay(mDisplayManager, mDisplay0, 0, 10); |
| 219 | mockDisplay(mDisplayManager, mDisplay1, 1, 11); |
| 220 | mockDisplay(mDisplayManager, mDisplay2, 2, 12); |
| 221 | mockDisplay(mDisplayManager, mDisplay4, 4, 14); |
| 222 | mockDisplay(mDisplayManager, mDisplay5, 5, 15); |
| 223 | when(mDisplayManager.getDisplays()).thenReturn(new Display[]{ |
| 224 | mDisplay0, |
| 225 | mDisplay1, |
| 226 | mDisplay2, |
| 227 | mDisplay4, |
| 228 | mDisplay5 |
| 229 | }); |
| 230 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 231 | mService = new CarOccupantZoneService(mContext, mDisplayManager, mUserManager, |
| 232 | /* enableProfileUserAssignmentForMultiDisplay= */ false); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 233 | spyOn(mService); |
| 234 | doReturn(VehicleAreaSeat.SEAT_ROW_1_LEFT).when(mService).getDriverSeat(); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 235 | doReturn(CURRENT_USER).when(mService).getCurrentUser(); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 236 | |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 237 | Car car = new Car(mContext, /* service= */ null, /* handler= */ null); |
Keun young Park | c8c565a | 2019-10-11 16:13:34 -0700 | [diff] [blame] | 238 | mManager = new CarOccupantZoneManager(car, mService); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 239 | } |
| 240 | |
| 241 | @After |
| 242 | public void tearDown() { |
| 243 | CarLocalServices.removeServiceForTest(CarUserService.class); |
| 244 | CarLocalServices.removeServiceForTest(CarPropertyService.class); |
| 245 | } |
| 246 | |
| 247 | @Test |
| 248 | public void testDefaultOccupantConfig() { |
| 249 | mService.init(); |
| 250 | |
| 251 | // key : zone id |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 252 | SparseArray<OccupantZoneInfo> configs = mService.getOccupantsConfig(); |
| 253 | assertThat(configs.size()).isEqualTo(DEFAULT_OCCUPANT_ZONES.length); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 254 | assertThat(mZoneDriverLHD).isEqualTo(configs.get(0)); |
| 255 | assertThat(mZoneFrontPassengerLHD).isEqualTo(configs.get(1)); |
| 256 | assertThat(mZoneRearLeft).isEqualTo(configs.get(2)); |
| 257 | assertThat(mZoneRearRight).isEqualTo(configs.get(3)); |
| 258 | } |
| 259 | |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 260 | @Test |
| 261 | public void testDefaultAudioZoneConfig() { |
| 262 | mService.init(); |
| 263 | SparseIntArray audioConfigs = mService.getAudioConfigs(); |
| 264 | assertThat(audioConfigs.size()).isEqualTo(0); |
| 265 | } |
| 266 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 267 | /** RHD: Right Hand Drive */ |
| 268 | @Test |
| 269 | public void testDefaultOccupantConfigForRHD() { |
| 270 | // driver is right side and opposite should be left. |
| 271 | doReturn(VehicleAreaSeat.SEAT_ROW_1_RIGHT).when(mService).getDriverSeat(); |
| 272 | |
| 273 | mService.init(); |
| 274 | |
| 275 | // key : zone id |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 276 | SparseArray<OccupantZoneInfo> configs = mService.getOccupantsConfig(); |
| 277 | assertThat(configs.size()).isEqualTo(DEFAULT_OCCUPANT_ZONES.length); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 278 | assertThat(new OccupantZoneInfo(0, CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER, |
| 279 | VehicleAreaSeat.SEAT_ROW_1_RIGHT)).isEqualTo(configs.get(0)); |
| 280 | assertThat(new OccupantZoneInfo(1, CarOccupantZoneManager.OCCUPANT_TYPE_FRONT_PASSENGER, |
| 281 | VehicleAreaSeat.SEAT_ROW_1_LEFT)).isEqualTo(configs.get(1)); |
| 282 | assertThat(mZoneRearLeft).isEqualTo(configs.get(2)); |
| 283 | assertThat(mZoneRearRight).isEqualTo(configs.get(3)); |
| 284 | } |
| 285 | |
| 286 | private void assertDisplayConfig(DisplayConfig c, int displayType, int occupantZoneId) { |
| 287 | assertThat(displayType).isEqualTo(c.displayType); |
| 288 | assertThat(occupantZoneId).isEqualTo(c.occupantZoneId); |
| 289 | } |
| 290 | |
| 291 | @Test |
| 292 | public void testDefaultOccupantDisplayMapping() { |
| 293 | mService.init(); |
| 294 | |
| 295 | // key: display port address |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 296 | SparseArray<DisplayConfig> configs = mService.getDisplayConfigs(); |
| 297 | assertThat(configs.size()).isEqualTo(DEFAULT_OCCUPANT_DISPLAY_MAPPING.length); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 298 | assertDisplayConfig(configs.get(10), CarOccupantZoneManager.DISPLAY_TYPE_MAIN, 0); |
| 299 | assertDisplayConfig(configs.get(11), CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER, |
| 300 | 0); |
| 301 | assertDisplayConfig(configs.get(12), CarOccupantZoneManager.DISPLAY_TYPE_MAIN, 1); |
| 302 | assertDisplayConfig(configs.get(13), CarOccupantZoneManager.DISPLAY_TYPE_MAIN, 2); |
| 303 | assertDisplayConfig(configs.get(14), CarOccupantZoneManager.DISPLAY_TYPE_MAIN, 3); |
| 304 | } |
| 305 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 306 | private void setUpServiceWithProfileSupportEnabled() { |
| 307 | mService = new CarOccupantZoneService(mContext, mDisplayManager, mUserManager, |
| 308 | /* enableProfileUserAssignmentForMultiDisplay= */ true); |
| 309 | spyOn(mService); |
| 310 | doReturn(VehicleAreaSeat.SEAT_ROW_1_LEFT).when(mService).getDriverSeat(); |
| 311 | doReturn(CURRENT_USER).when(mService).getCurrentUser(); |
| 312 | LinkedList<UserInfo> profileUsers = new LinkedList<>(); |
| 313 | profileUsers.add(new UserInfo(PROFILE_USER1, "1", 0)); |
| 314 | profileUsers.add(new UserInfo(PROFILE_USER2, "1", 0)); |
| 315 | doReturn(profileUsers).when(mUserManager).getEnabledProfiles(CURRENT_USER); |
Keun young Park | 2c104d6 | 2020-04-09 14:03:33 -0700 | [diff] [blame] | 316 | doReturn(true).when(mUserManager).isUserRunning(anyInt()); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 317 | |
| 318 | Car car = new Car(mContext, /* service= */ null, /* handler= */ null); |
| 319 | mManager = new CarOccupantZoneManager(car, mService); |
| 320 | } |
| 321 | |
| 322 | @Test |
| 323 | public void testAssignProfileUserFailForNonProfileUser() throws Exception { |
| 324 | setUpServiceWithProfileSupportEnabled(); |
| 325 | mService.init(); |
| 326 | |
| 327 | int invalidProfileUser = 2000; |
| 328 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 329 | invalidProfileUser)).isFalse(); |
| 330 | } |
| 331 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 332 | private void assertDisplayAllowlist(int userId, int[] displays) { |
| 333 | assertThat(mICarServiceHelper.mAllowlists).containsKey(userId); |
| 334 | assertThat(mICarServiceHelper.mAllowlists.get(userId)).hasSize(displays.length); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 335 | for (int display : displays) { |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 336 | assertThat(mICarServiceHelper.mAllowlists.get(userId)).contains(display); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 337 | } |
| 338 | } |
| 339 | |
| 340 | private void assertPassengerDisplaysFromDefaultConfig() throws Exception { |
| 341 | assertThat(mICarServiceHelper.mPassengerDisplayIds).hasSize(2); |
| 342 | assertThat(mICarServiceHelper.mPassengerDisplayIds).contains( |
| 343 | mDisplay2.getDisplayId()); |
| 344 | assertThat(mICarServiceHelper.mPassengerDisplayIds).contains( |
| 345 | mDisplay4.getDisplayId()); |
| 346 | } |
| 347 | |
| 348 | @Test |
| 349 | public void testAssignProfileUserOnce() throws Exception { |
| 350 | setUpServiceWithProfileSupportEnabled(); |
| 351 | mService.init(); |
| 352 | mService.setCarServiceHelper(mICarServiceHelper); |
| 353 | |
| 354 | assertPassengerDisplaysFromDefaultConfig(); |
| 355 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 356 | mICarServiceHelper.mAllowlists.clear(); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 357 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 358 | PROFILE_USER1)).isTrue(); |
| 359 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 360 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay4.getDisplayId()}); |
| 361 | assertDisplayAllowlist(PROFILE_USER1, new int[] {mDisplay2.getDisplayId()}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 362 | } |
| 363 | |
| 364 | @Test |
Keun young Park | 2c104d6 | 2020-04-09 14:03:33 -0700 | [diff] [blame] | 365 | public void testAssignProfileUserFailForStoppedUser() throws Exception { |
| 366 | setUpServiceWithProfileSupportEnabled(); |
| 367 | mService.init(); |
| 368 | mService.setCarServiceHelper(mICarServiceHelper); |
| 369 | |
| 370 | assertPassengerDisplaysFromDefaultConfig(); |
| 371 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 372 | mICarServiceHelper.mAllowlists.clear(); |
Keun young Park | 2c104d6 | 2020-04-09 14:03:33 -0700 | [diff] [blame] | 373 | doReturn(false).when(mUserManager).isUserRunning(PROFILE_USER1); |
| 374 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 375 | PROFILE_USER1)).isFalse(); |
| 376 | } |
| 377 | |
| 378 | @Test |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 379 | public void testAssignProfileUserSwitch() throws Exception { |
| 380 | setUpServiceWithProfileSupportEnabled(); |
| 381 | mService.init(); |
| 382 | mService.setCarServiceHelper(mICarServiceHelper); |
| 383 | |
| 384 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 385 | PROFILE_USER1)).isTrue(); |
| 386 | |
| 387 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 388 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay4.getDisplayId()}); |
| 389 | assertDisplayAllowlist(PROFILE_USER1, new int[] {mDisplay2.getDisplayId()}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 390 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 391 | mICarServiceHelper.mAllowlists.clear(); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 392 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 393 | PROFILE_USER2)).isTrue(); |
| 394 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 395 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay4.getDisplayId()}); |
| 396 | assertDisplayAllowlist(PROFILE_USER2, new int[] {mDisplay2.getDisplayId()}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 397 | } |
| 398 | |
| 399 | @Test |
| 400 | public void testAssignProfileFollowedByUserSwitch() throws Exception { |
| 401 | setUpServiceWithProfileSupportEnabled(); |
| 402 | mService.init(); |
| 403 | mService.setCarServiceHelper(mICarServiceHelper); |
| 404 | |
| 405 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 406 | PROFILE_USER1)).isTrue(); |
| 407 | |
| 408 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 409 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay4.getDisplayId()}); |
| 410 | assertDisplayAllowlist(PROFILE_USER1, new int[] {mDisplay2.getDisplayId()}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 411 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 412 | mICarServiceHelper.mAllowlists.clear(); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 413 | int newUserId = 200; |
| 414 | doReturn(newUserId).when(mService).getCurrentUser(); |
| 415 | mService.mUserLifecycleListener.onEvent(new UserLifecycleEvent( |
| 416 | CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, newUserId)); |
| 417 | |
| 418 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 419 | assertDisplayAllowlist(newUserId, new int[] {mDisplay2.getDisplayId(), |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 420 | mDisplay4.getDisplayId()}); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 421 | assertThat(mICarServiceHelper.mAllowlists).hasSize(1); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 422 | } |
| 423 | |
| 424 | @Test |
| 425 | public void testAssignProfileFollowedByNullUserAssignment() throws Exception { |
| 426 | setUpServiceWithProfileSupportEnabled(); |
| 427 | mService.init(); |
| 428 | mService.setCarServiceHelper(mICarServiceHelper); |
| 429 | |
| 430 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 431 | PROFILE_USER1)).isTrue(); |
| 432 | |
| 433 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 434 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay4.getDisplayId()}); |
| 435 | assertDisplayAllowlist(PROFILE_USER1, new int[] {mDisplay2.getDisplayId()}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 436 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 437 | mICarServiceHelper.mAllowlists.clear(); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 438 | assertThat(mManager.assignProfileUserToOccupantZone(mZoneFrontPassengerLHD, |
| 439 | UserHandle.USER_NULL)).isTrue(); |
| 440 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 441 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay2.getDisplayId(), |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 442 | mDisplay4.getDisplayId()}); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 443 | assertThat(mICarServiceHelper.mAllowlists).hasSize(1); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 444 | } |
| 445 | |
| 446 | @Test |
| 447 | public void testCarServiceHelperInitialUpdate() throws Exception { |
| 448 | setUpServiceWithProfileSupportEnabled(); |
| 449 | mService.init(); |
| 450 | mService.setCarServiceHelper(mICarServiceHelper); |
| 451 | |
| 452 | assertPassengerDisplaysFromDefaultConfig(); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 453 | assertDisplayAllowlist(CURRENT_USER, new int[] {mDisplay2.getDisplayId(), |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 454 | mDisplay4.getDisplayId()}); |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 455 | assertThat(mICarServiceHelper.mAllowlists).hasSize(1); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 456 | } |
| 457 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 458 | private void assertDisplayInfoIncluded( |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 459 | ArrayList<DisplayInfo> displayInfos, Display display, int displayType) { |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 460 | for (DisplayInfo info : displayInfos) { |
| 461 | if (info.display == display && info.displayType == displayType) { |
| 462 | return; |
| 463 | } |
| 464 | } |
| 465 | fail("Cannot find display:" + display + " type:" + displayType); |
| 466 | } |
| 467 | |
| 468 | private void assertOccupantConfig(OccupantConfig c, int userId, Display[] displays, |
| 469 | int[] displayTypes) { |
| 470 | assertThat(userId).isEqualTo(c.userId); |
| 471 | assertThat(c.displayInfos).hasSize(displays.length); |
| 472 | assertThat(c.displayInfos).hasSize(displayTypes.length); |
| 473 | for (int i = 0; i < displays.length; i++) { |
| 474 | assertDisplayInfoIncluded(c.displayInfos, displays[i], displayTypes[i]); |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | @Test |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 479 | public void testSetAudioConfigMapping() { |
| 480 | mService.init(); |
| 481 | |
| 482 | SparseIntArray audioZoneIdToOccupantZoneMapping = |
| 483 | getDefaultAudioZoneToOccupantZoneMapping(); |
| 484 | |
| 485 | mService.setAudioZoneIdsForOccupantZoneIds(audioZoneIdToOccupantZoneMapping); |
| 486 | |
| 487 | assertThat(mService.getAudioZoneIdForOccupant(PRIMARY_AUDIO_ZONE_ID_OCCUPANT)) |
| 488 | .isEqualTo(PRIMARY_AUDIO_ZONE_ID); |
| 489 | |
| 490 | assertThat(mService.getAudioZoneIdForOccupant(SECONDARY_AUDIO_ZONE_ID_OCCUPANT)) |
| 491 | .isEqualTo(SECONDARY_AUDIO_ZONE_ID); |
| 492 | } |
| 493 | |
| 494 | private SparseIntArray getDefaultAudioZoneToOccupantZoneMapping() { |
| 495 | SparseIntArray audioZoneIdToOccupantZoneMapping = new SparseIntArray(2); |
| 496 | audioZoneIdToOccupantZoneMapping.put(PRIMARY_AUDIO_ZONE_ID, |
| 497 | PRIMARY_AUDIO_ZONE_ID_OCCUPANT); |
| 498 | audioZoneIdToOccupantZoneMapping.put(SECONDARY_AUDIO_ZONE_ID, |
| 499 | SECONDARY_AUDIO_ZONE_ID_OCCUPANT); |
| 500 | return audioZoneIdToOccupantZoneMapping; |
| 501 | } |
| 502 | |
| 503 | @Test |
| 504 | public void testOccupantZoneConfigInfoForAudio() { |
| 505 | mService.init(); |
| 506 | SparseIntArray audioZoneIdToOccupantZoneMapping = |
| 507 | getDefaultAudioZoneToOccupantZoneMapping(); |
| 508 | |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 509 | SparseArray<CarOccupantZoneManager.OccupantZoneInfo> occupantZoneConfigs = |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 510 | mService.getOccupantsConfig(); |
| 511 | |
| 512 | mService.setAudioZoneIdsForOccupantZoneIds(audioZoneIdToOccupantZoneMapping); |
| 513 | |
| 514 | CarOccupantZoneManager.OccupantZoneInfo primaryOccupantInfo = |
| 515 | mService.getOccupantForAudioZoneId(PRIMARY_AUDIO_ZONE_ID); |
| 516 | assertThat(primaryOccupantInfo).isEqualTo( |
| 517 | occupantZoneConfigs.get(PRIMARY_AUDIO_ZONE_ID_OCCUPANT)); |
| 518 | |
| 519 | CarOccupantZoneManager.OccupantZoneInfo secondaryOccupantInfo = |
| 520 | mService.getOccupantForAudioZoneId(SECONDARY_AUDIO_ZONE_ID); |
| 521 | assertThat(secondaryOccupantInfo).isEqualTo( |
| 522 | occupantZoneConfigs.get(SECONDARY_AUDIO_ZONE_ID_OCCUPANT)); |
| 523 | |
| 524 | CarOccupantZoneManager.OccupantZoneInfo nullOccupantInfo = |
| 525 | mService.getOccupantForAudioZoneId(UNMAPPED_AUDIO_ZONE_ID_OCCUPANT); |
| 526 | assertThat(nullOccupantInfo).isNull(); |
| 527 | } |
| 528 | |
| 529 | @Test |
| 530 | public void testMissingAudioConfigMapping() { |
| 531 | mService.init(); |
| 532 | SparseIntArray audioZoneIdToOccupantZoneMapping = |
| 533 | getDefaultAudioZoneToOccupantZoneMapping(); |
| 534 | |
| 535 | mService.setAudioZoneIdsForOccupantZoneIds(audioZoneIdToOccupantZoneMapping); |
| 536 | |
| 537 | assertThat(mService.getAudioZoneIdForOccupant(UNMAPPED_AUDIO_ZONE_ID_OCCUPANT)) |
| 538 | .isEqualTo(CarAudioManager.INVALID_AUDIO_ZONE); |
| 539 | } |
| 540 | |
| 541 | @Test |
| 542 | public void testSetInvalidAudioConfigMapping() { |
| 543 | mService.init(); |
| 544 | SparseIntArray audioZoneIdToOccupantZoneMapping = new SparseIntArray(2); |
| 545 | audioZoneIdToOccupantZoneMapping.put(PRIMARY_AUDIO_ZONE_ID, |
| 546 | PRIMARY_AUDIO_ZONE_ID_OCCUPANT); |
| 547 | audioZoneIdToOccupantZoneMapping.put(SECONDARY_AUDIO_ZONE_ID, |
| 548 | INVALID_AUDIO_ZONE_ID_OCCUPANT); |
| 549 | IllegalArgumentException thrown = |
| 550 | expectThrows(IllegalArgumentException.class, |
| 551 | () -> mService.setAudioZoneIdsForOccupantZoneIds( |
| 552 | audioZoneIdToOccupantZoneMapping)); |
| 553 | thrown.getMessage().contains("does not exist"); |
| 554 | } |
| 555 | |
| 556 | @Test |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 557 | public void testActiveOccupantConfigs() { |
| 558 | mService.init(); |
| 559 | |
| 560 | // key : zone id |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 561 | SparseArray<OccupantConfig> configs = mService.getActiveOccupantConfigs(); |
| 562 | assertThat(configs.size()).isEqualTo(3); // driver, front passenger, one rear |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 563 | assertOccupantConfig(configs.get(0), CURRENT_USER, new Display[]{mDisplay0, mDisplay1}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 564 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN, |
| 565 | CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 566 | assertOccupantConfig(configs.get(1), CURRENT_USER, new Display[]{mDisplay2}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 567 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 568 | assertOccupantConfig(configs.get(3), CURRENT_USER, new Display[]{mDisplay4}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 569 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
| 570 | } |
| 571 | |
| 572 | @Test |
| 573 | public void testActiveOccupantConfigsAfterDisplayAdd() { |
| 574 | mService.init(); |
| 575 | |
| 576 | mockDisplay(mDisplayManager, mDisplay3, 3, 13); |
| 577 | when(mDisplayManager.getDisplays()).thenReturn(new Display[]{ |
| 578 | mDisplay0, |
| 579 | mDisplay1, |
| 580 | mDisplay2, |
| 581 | mDisplay3, |
| 582 | mDisplay4, |
| 583 | mDisplay5 |
| 584 | }); |
| 585 | mService.mDisplayListener.onDisplayAdded(3); |
| 586 | |
| 587 | // key : zone id |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 588 | SparseArray<OccupantConfig> configs = mService.getActiveOccupantConfigs(); |
| 589 | assertThat(configs.size()).isEqualTo(4); // driver, front passenger, two rear |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 590 | assertOccupantConfig(configs.get(0), CURRENT_USER, new Display[]{mDisplay0, mDisplay1}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 591 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN, |
| 592 | CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 593 | assertOccupantConfig(configs.get(1), CURRENT_USER, new Display[]{mDisplay2}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 594 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 595 | assertOccupantConfig(configs.get(2), CURRENT_USER, new Display[]{mDisplay3}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 596 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 597 | assertOccupantConfig(configs.get(3), CURRENT_USER, new Display[]{mDisplay4}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 598 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
| 599 | } |
| 600 | |
| 601 | @Test |
| 602 | public void testActiveOccupantConfigsAfterDisplayRemoval() { |
| 603 | mService.init(); |
| 604 | |
| 605 | when(mDisplayManager.getDisplays()).thenReturn(new Display[]{ |
| 606 | mDisplay0, |
| 607 | mDisplay1, |
| 608 | mDisplay2, |
| 609 | }); |
| 610 | mService.mDisplayListener.onDisplayRemoved(4); |
| 611 | |
| 612 | // key : zone id |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 613 | SparseArray<OccupantConfig> configs = mService.getActiveOccupantConfigs(); |
| 614 | assertThat(configs.size()).isEqualTo(2); // driver, front passenger |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 615 | assertOccupantConfig(configs.get(0), CURRENT_USER, new Display[]{mDisplay0, mDisplay1}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 616 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN, |
| 617 | CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 618 | assertOccupantConfig(configs.get(1), CURRENT_USER, new Display[]{mDisplay2}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 619 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
| 620 | } |
| 621 | |
| 622 | @Test |
| 623 | public void testActiveUserAfterUserSwitching() { |
| 624 | mService.init(); |
| 625 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 626 | final int newUserId = 200; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 627 | doReturn(newUserId).when(mService).getCurrentUser(); |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 628 | mService.mUserLifecycleListener.onEvent(new UserLifecycleEvent( |
felipeal | 042a73c | 2020-03-30 09:24:05 -0700 | [diff] [blame] | 629 | CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, newUserId)); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 630 | |
| 631 | // key : zone id |
Yuncheol Heo | 392eea5 | 2020-07-07 14:07:22 -0700 | [diff] [blame] | 632 | SparseArray<OccupantConfig> configs = mService.getActiveOccupantConfigs(); |
| 633 | assertThat(configs.size()).isEqualTo(3); // driver, front passenger, one rear |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 634 | assertOccupantConfig(configs.get(0), newUserId, new Display[]{mDisplay0, mDisplay1}, |
| 635 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN, |
| 636 | CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 637 | assertOccupantConfig(configs.get(1), newUserId, new Display[]{mDisplay2}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 638 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 639 | assertOccupantConfig(configs.get(3), newUserId, new Display[]{mDisplay4}, |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 640 | new int[]{CarOccupantZoneManager.DISPLAY_TYPE_MAIN}); |
| 641 | } |
| 642 | |
| 643 | private void assertParsingFailure() { |
| 644 | assertThrows(Exception.class, () -> mService.init()); |
| 645 | // call release to return it to clean state. |
| 646 | mService.release(); |
| 647 | } |
| 648 | |
| 649 | @Test |
| 650 | public void testWrongZoneConfigs() { |
| 651 | final String[] wrongZoneConfigs = { |
| 652 | "unknownKeyword", |
| 653 | "unknownKey=0", |
| 654 | "occupantZoneId=0,occupantType=Unknown,seatRow=1,seatSide=driver", |
| 655 | "occupantZoneId=0,occupantType=DRIVER,seatRow=0,seatSide=driver", // wrong row |
| 656 | "occupantZoneId=0,occupantType=DRIVER,seatRow=1,seatSide=wrongSide" |
| 657 | }; |
| 658 | |
| 659 | String[] zoneConfig = new String[1]; |
| 660 | when(mResources.getStringArray(R.array.config_occupant_zones)) |
| 661 | .thenReturn(zoneConfig); |
| 662 | for (int i = 0; i < wrongZoneConfigs.length; i++) { |
| 663 | zoneConfig[0] = wrongZoneConfigs[i]; |
| 664 | assertParsingFailure(); |
| 665 | } |
| 666 | } |
| 667 | |
| 668 | @Test |
| 669 | public void testWrongDisplayConfigs() { |
| 670 | final String[] wrongDisplayConfigs = { |
| 671 | "unknownKeyword", |
| 672 | "unknownKey=0", |
| 673 | "displayPort=10,displayType=Unknown,occupantZoneId=0", |
| 674 | "displayPort=10,displayType=MAIN,occupantZoneId=100" // wrong zone id |
| 675 | }; |
| 676 | |
| 677 | String[] displayConfig = new String[1]; |
| 678 | when(mResources.getStringArray(R.array.config_occupant_display_mapping)) |
| 679 | .thenReturn(displayConfig); |
| 680 | for (int i = 0; i < wrongDisplayConfigs.length; i++) { |
| 681 | displayConfig[0] = wrongDisplayConfigs[i]; |
| 682 | assertParsingFailure(); |
| 683 | } |
| 684 | } |
| 685 | |
| 686 | @Test |
| 687 | public void testManagerGetAllOccupantZones() { |
| 688 | mService.init(); |
| 689 | |
| 690 | List<OccupantZoneInfo> infos = mManager.getAllOccupantZones(); |
| 691 | assertThat(infos).hasSize(3); |
| 692 | assertThat(infos).contains(mZoneDriverLHD); |
| 693 | assertThat(infos).contains(mZoneFrontPassengerLHD); |
| 694 | assertThat(infos).contains(mZoneRearRight); |
| 695 | } |
| 696 | |
| 697 | @Test |
| 698 | public void testManagerGetAllDisplaysForOccupant() { |
| 699 | mService.init(); |
| 700 | |
| 701 | List<Display> displaysForDriver = mManager.getAllDisplaysForOccupant(mZoneDriverLHD); |
| 702 | assertThat(displaysForDriver).hasSize(2); |
| 703 | assertThat(displaysForDriver).contains(mDisplay0); |
| 704 | assertThat(displaysForDriver).contains(mDisplay1); |
| 705 | |
| 706 | List<Display> displaysForFrontPassenger = mManager.getAllDisplaysForOccupant( |
| 707 | mZoneFrontPassengerLHD); |
| 708 | assertThat(displaysForFrontPassenger).hasSize(1); |
| 709 | assertThat(displaysForFrontPassenger).contains(mDisplay2); |
| 710 | |
| 711 | List<Display> displaysForRearLeft = mManager.getAllDisplaysForOccupant( |
| 712 | mZoneRearLeft); |
| 713 | assertThat(displaysForRearLeft).hasSize(0); |
| 714 | |
| 715 | List<Display> displaysForRearRight = mManager.getAllDisplaysForOccupant( |
| 716 | mZoneRearRight); |
| 717 | assertThat(displaysForRearRight).hasSize(1); |
| 718 | assertThat(displaysForRearRight).contains(mDisplay4); |
| 719 | } |
| 720 | |
| 721 | @Test |
| 722 | public void testManagerGetAllDisplaysForOccupantAfterDisplayAdd() { |
| 723 | mService.init(); |
| 724 | |
| 725 | mockDisplay(mDisplayManager, mDisplay3, 3, 13); |
| 726 | when(mDisplayManager.getDisplays()).thenReturn(new Display[]{ |
| 727 | mDisplay0, |
| 728 | mDisplay1, |
| 729 | mDisplay2, |
| 730 | mDisplay3, |
| 731 | mDisplay4, |
| 732 | mDisplay5 |
| 733 | }); |
| 734 | mService.mDisplayListener.onDisplayAdded(3); |
| 735 | |
| 736 | List<Display> displaysForDriver = mManager.getAllDisplaysForOccupant(mZoneDriverLHD); |
| 737 | assertThat(displaysForDriver).hasSize(2); |
| 738 | assertThat(displaysForDriver).contains(mDisplay0); |
| 739 | assertThat(displaysForDriver).contains(mDisplay1); |
| 740 | |
| 741 | List<Display> displaysForFrontPassenger = mManager.getAllDisplaysForOccupant( |
| 742 | mZoneFrontPassengerLHD); |
| 743 | assertThat(displaysForFrontPassenger).hasSize(1); |
| 744 | assertThat(displaysForFrontPassenger).contains(mDisplay2); |
| 745 | |
| 746 | List<Display> displaysForRearLeft = mManager.getAllDisplaysForOccupant( |
| 747 | mZoneRearLeft); |
| 748 | assertThat(displaysForRearLeft).hasSize(1); |
| 749 | assertThat(displaysForRearLeft).contains(mDisplay3); |
| 750 | |
| 751 | List<Display> displaysForRearRight = mManager.getAllDisplaysForOccupant( |
| 752 | mZoneRearRight); |
| 753 | assertThat(displaysForRearRight).hasSize(1); |
| 754 | assertThat(displaysForRearRight).contains(mDisplay4); |
| 755 | } |
| 756 | |
| 757 | @Test |
| 758 | public void testManagerGetAllDisplaysForOccupantAfterDisplayRemoval() { |
| 759 | mService.init(); |
| 760 | |
| 761 | when(mDisplayManager.getDisplays()).thenReturn(new Display[]{ |
| 762 | mDisplay0, |
| 763 | mDisplay1, |
| 764 | mDisplay2, |
| 765 | }); |
| 766 | mService.mDisplayListener.onDisplayRemoved(4); |
| 767 | |
| 768 | List<Display> displaysForDriver = mManager.getAllDisplaysForOccupant(mZoneDriverLHD); |
| 769 | assertThat(displaysForDriver).hasSize(2); |
| 770 | assertThat(displaysForDriver).contains(mDisplay0); |
| 771 | assertThat(displaysForDriver).contains(mDisplay1); |
| 772 | |
| 773 | List<Display> displaysForFrontPassenger = mManager.getAllDisplaysForOccupant( |
| 774 | mZoneFrontPassengerLHD); |
| 775 | assertThat(displaysForFrontPassenger).hasSize(1); |
| 776 | assertThat(displaysForFrontPassenger).contains(mDisplay2); |
| 777 | |
| 778 | List<Display> displaysForRearLeft = mManager.getAllDisplaysForOccupant( |
| 779 | mZoneRearLeft); |
| 780 | assertThat(displaysForRearLeft).hasSize(0); |
| 781 | |
| 782 | List<Display> displaysForRearRight = mManager.getAllDisplaysForOccupant( |
| 783 | mZoneRearRight); |
| 784 | assertThat(displaysForRearRight).hasSize(0); |
| 785 | } |
| 786 | |
| 787 | @Test |
| 788 | public void testManagerGetDisplayForOccupant() { |
| 789 | mService.init(); |
| 790 | |
| 791 | assertThat(mDisplay0).isEqualTo(mManager.getDisplayForOccupant(mZoneDriverLHD, |
| 792 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN)); |
| 793 | assertThat(mDisplay1).isEqualTo(mManager.getDisplayForOccupant(mZoneDriverLHD, |
| 794 | CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER)); |
| 795 | assertThat(mManager.getDisplayForOccupant(mZoneDriverLHD, |
| 796 | CarOccupantZoneManager.DISPLAY_TYPE_HUD)).isNull(); |
| 797 | |
| 798 | assertThat(mDisplay2).isEqualTo(mManager.getDisplayForOccupant(mZoneFrontPassengerLHD, |
| 799 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN)); |
| 800 | |
| 801 | assertThat(mManager.getDisplayForOccupant(mZoneRearLeft, |
| 802 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN)).isNull(); |
| 803 | |
| 804 | assertThat(mDisplay4).isEqualTo(mManager.getDisplayForOccupant(mZoneRearRight, |
| 805 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN)); |
| 806 | } |
| 807 | |
| 808 | @Test |
| 809 | public void testManagerGetDisplayType() { |
| 810 | mService.init(); |
| 811 | |
Mayank Garg | 42d83a1 | 2019-10-21 14:46:57 -0700 | [diff] [blame] | 812 | assertThat(mManager.getDisplayType(mDisplay0)).isEqualTo( |
| 813 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN); |
| 814 | assertThat(mManager.getDisplayType(mDisplay1)).isEqualTo( |
| 815 | CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER); |
| 816 | assertThat(mManager.getDisplayType(mDisplay2)).isEqualTo( |
| 817 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN); |
| 818 | assertThat(mManager.getDisplayType(mDisplay4)).isEqualTo( |
| 819 | CarOccupantZoneManager.DISPLAY_TYPE_MAIN); |
| 820 | assertThat(mManager.getDisplayType(mDisplay5)).isEqualTo( |
| 821 | CarOccupantZoneManager.DISPLAY_TYPE_UNKNOWN); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 822 | } |
| 823 | |
| 824 | @Test |
| 825 | public void testManagerGetUserForOccupant() { |
| 826 | mService.init(); |
| 827 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 828 | int driverUser = mManager.getUserForOccupant(mZoneDriverLHD); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 829 | assertThat(CURRENT_USER).isEqualTo(driverUser); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 830 | |
| 831 | //TODO update this after secondary user handling |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 832 | assertThat(mManager.getUserForOccupant(mZoneFrontPassengerLHD)).isEqualTo(driverUser); |
Mayank Garg | 42d83a1 | 2019-10-21 14:46:57 -0700 | [diff] [blame] | 833 | assertThat(mManager.getUserForOccupant(mZoneRearLeft)).isEqualTo(UserHandle.USER_NULL); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 834 | assertThat(mManager.getUserForOccupant(mZoneRearRight)).isEqualTo(driverUser); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 835 | } |
| 836 | |
| 837 | @Test |
| 838 | public void testManagerGetUserForOccupantAfterUserSwitch() { |
| 839 | mService.init(); |
| 840 | |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 841 | final int newUserId = 200; |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 842 | doReturn(newUserId).when(mService).getCurrentUser(); |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 843 | mService.mUserLifecycleListener.onEvent(new UserLifecycleEvent( |
felipeal | 042a73c | 2020-03-30 09:24:05 -0700 | [diff] [blame] | 844 | CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, newUserId)); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 845 | |
| 846 | assertThat(newUserId).isEqualTo(mManager.getUserForOccupant(mZoneDriverLHD)); |
| 847 | //TODO update this after secondary user handling |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 848 | assertThat(mManager.getUserForOccupant(mZoneFrontPassengerLHD)).isEqualTo(newUserId); |
Mayank Garg | 42d83a1 | 2019-10-21 14:46:57 -0700 | [diff] [blame] | 849 | assertThat(mManager.getUserForOccupant(mZoneRearLeft)).isEqualTo(UserHandle.USER_NULL); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 850 | assertThat(mManager.getUserForOccupant(mZoneRearRight)).isEqualTo(newUserId); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 851 | } |
| 852 | |
| 853 | @Test |
| 854 | public void testManagerRegisterUnregister() { |
| 855 | mService.init(); |
| 856 | |
| 857 | final long eventWaitTimeMs = 300; |
| 858 | |
| 859 | mManager.registerOccupantZoneConfigChangeListener(mChangeListener); |
| 860 | |
| 861 | resetConfigChangeEventWait(); |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 862 | mService.mUserLifecycleListener.onEvent(new UserLifecycleEvent( |
felipeal | 042a73c | 2020-03-30 09:24:05 -0700 | [diff] [blame] | 863 | CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 0)); // user id does not matter. |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 864 | |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 865 | assertThat(waitForConfigChangeEventAndAssertFlag(eventWaitTimeMs, |
| 866 | CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_USER)).isTrue(); |
| 867 | |
| 868 | resetConfigChangeEventWait(); |
| 869 | mService.mDisplayListener.onDisplayAdded(0); // displayid ignored |
| 870 | assertThat(waitForConfigChangeEventAndAssertFlag(eventWaitTimeMs, |
| 871 | CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_DISPLAY)).isTrue(); |
| 872 | |
| 873 | resetConfigChangeEventWait(); |
| 874 | mManager.unregisterOccupantZoneConfigChangeListener(mChangeListener); |
Antonio Kantek | f700753 | 2020-03-17 10:37:58 -0700 | [diff] [blame] | 875 | mService.mUserLifecycleListener.onEvent(new UserLifecycleEvent( |
felipeal | 042a73c | 2020-03-30 09:24:05 -0700 | [diff] [blame] | 876 | CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, 0)); |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 877 | assertThat(waitForConfigChangeEventAndAssertFlag(eventWaitTimeMs, 0)).isFalse(); |
| 878 | } |
Oscar Azucena | a48a118 | 2020-02-20 16:43:15 -0800 | [diff] [blame] | 879 | |
| 880 | @Test |
| 881 | public void testManagerRegisterUnregisterForAudioConfigs() { |
| 882 | mService.init(); |
| 883 | |
| 884 | long eventWaitTimeMs = 300; |
| 885 | |
| 886 | mManager.registerOccupantZoneConfigChangeListener(mChangeListener); |
| 887 | |
| 888 | resetConfigChangeEventWait(); |
| 889 | |
| 890 | SparseIntArray audioZoneIdToOccupantZoneMapping = |
| 891 | getDefaultAudioZoneToOccupantZoneMapping(); |
| 892 | |
| 893 | mService.setAudioZoneIdsForOccupantZoneIds(audioZoneIdToOccupantZoneMapping); |
| 894 | |
| 895 | assertThat(waitForConfigChangeEventAndAssertFlag(eventWaitTimeMs, |
| 896 | CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_AUDIO)).isTrue(); |
| 897 | |
| 898 | resetConfigChangeEventWait(); |
| 899 | mManager.unregisterOccupantZoneConfigChangeListener(mChangeListener); |
| 900 | mService.setAudioZoneIdsForOccupantZoneIds(audioZoneIdToOccupantZoneMapping); |
| 901 | assertThat(waitForConfigChangeEventAndAssertFlag(eventWaitTimeMs, |
| 902 | CarOccupantZoneManager.ZONE_CONFIG_CHANGE_FLAG_AUDIO)).isFalse(); |
| 903 | } |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 904 | |
| 905 | private static class ICarServiceHelperImpl extends ICarServiceHelper.Stub { |
| 906 | private List<Integer> mPassengerDisplayIds; |
| 907 | |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 908 | /** key: user id, value: display allowlists */ |
| 909 | private HashMap<Integer, List<Integer>> mAllowlists = new HashMap<>(); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 910 | |
| 911 | @Override |
| 912 | public int forceSuspend(int timeoutMs) { |
| 913 | return 0; |
| 914 | } |
| 915 | |
| 916 | @Override |
Mayank Garg | 93b5165 | 2020-08-04 12:24:40 -0700 | [diff] [blame] | 917 | public void setDisplayAllowlistForUser(@UserIdInt int userId, int[] displayIds) { |
| 918 | mAllowlists.put(userId, Arrays.stream(displayIds).boxed().collect(Collectors.toList())); |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 919 | } |
| 920 | |
| 921 | @Override |
| 922 | public void setPassengerDisplays(int[] displayIdsForPassenger) { |
| 923 | mPassengerDisplayIds = Arrays.stream(displayIdsForPassenger).boxed().collect( |
| 924 | Collectors.toList()); |
| 925 | } |
Yuncheol Heo | eef96c8 | 2020-05-21 10:51:20 -0700 | [diff] [blame] | 926 | |
| 927 | @Override |
| 928 | public void setSourcePreferredComponents(boolean enableSourcePreferred, |
| 929 | List<ComponentName> sourcePreferredComponents) throws RemoteException { |
| 930 | } |
Keun young Park | 15ccea4 | 2020-03-27 10:35:31 -0700 | [diff] [blame] | 931 | } |
Keun young Park | bb877e2 | 2019-08-02 10:38:01 -0700 | [diff] [blame] | 932 | } |