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.server.telecom.tests; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertFalse; 21 import static junit.framework.Assert.assertTrue; 22 import static junit.framework.TestCase.assertNull; 23 24 import android.app.UiModeManager; 25 26 import com.android.server.telecom.CarModeTracker; 27 28 import org.junit.After; 29 import org.junit.Before; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.JUnit4; 33 34 @RunWith(JUnit4.class) 35 public class CarModeTrackerTest extends TelecomTestCase { 36 private static final String CAR_MODE_APP1_PACKAGE_NAME = "com.android.carmode1"; 37 private static final String CAR_MODE_APP2_PACKAGE_NAME = "com.android.carmode2"; 38 private static final String CAR_MODE_APP3_PACKAGE_NAME = "com.android.carmode3"; 39 private static final String CAR_MODE_APP4_PACKAGE_NAME = "com.android.carmode4"; 40 41 private CarModeTracker mCarModeTracker; 42 43 @Override 44 @Before setUp()45 public void setUp() throws Exception { 46 super.setUp(); 47 48 mCarModeTracker = new CarModeTracker(); 49 } 50 51 @Override 52 @After tearDown()53 public void tearDown() throws Exception { 54 super.tearDown(); 55 } 56 57 /** 58 * Basic test; see if we can enter car mode. 59 */ 60 @Test testEnterCarModeBasic()61 public void testEnterCarModeBasic() { 62 // At start, no car mode apps. 63 assertNull(mCarModeTracker.getCurrentCarModePackage()); 64 assertEquals(0, mCarModeTracker.getCarModeApps().size()); 65 66 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 67 68 // We should be tracking our car mode app. 69 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 70 assertTrue(mCarModeTracker.isInCarMode()); 71 } 72 73 /** 74 * Ensure when we enter car mode with a package which has already entered car mode, the extra 75 * request is ignored. 76 */ 77 @Test testEnterCarModeAlreadyInCarMode()78 public void testEnterCarModeAlreadyInCarMode() { 79 testEnterCarModeBasic(); 80 81 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 82 // Still should just be one. 83 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 84 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 85 } 86 87 /** 88 * Ensure when we enter car mode with a package which has already entered car mode, the extra 89 * request is ignored. 90 */ 91 @Test testEnterCarModePriorityInUse()92 public void testEnterCarModePriorityInUse() { 93 testEnterCarModeBasic(); 94 95 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP2_PACKAGE_NAME); 96 97 // We should be tracking car mode with the first package; the 2nd should have been ignored. 98 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 99 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 100 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCarModeApps().get(0)); 101 } 102 103 /** 104 * Ensure that we don't keep a package around after it's been removed from the device 105 */ 106 @Test testForceExitCarMode()107 public void testForceExitCarMode() { 108 testEnterCarModeBasic(); 109 mCarModeTracker.forceRemove(CAR_MODE_APP1_PACKAGE_NAME); 110 assertFalse(mCarModeTracker.isInCarMode()); 111 assertNull(mCarModeTracker.getCurrentCarModePackage()); 112 } 113 114 /** 115 * Verifies only the first app at the default priority gets tracked. 116 */ 117 @Test testEnterCarModeDefaultPriority()118 public void testEnterCarModeDefaultPriority() { 119 assertEquals(0, mCarModeTracker.getCarModeApps().size()); 120 121 mCarModeTracker.handleEnterCarMode(UiModeManager.DEFAULT_PRIORITY, 122 CAR_MODE_APP1_PACKAGE_NAME); 123 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 124 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 125 126 mCarModeTracker.handleEnterCarMode(UiModeManager.DEFAULT_PRIORITY, 127 CAR_MODE_APP2_PACKAGE_NAME); 128 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 129 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 130 } 131 132 /** 133 * Verifies that multiple apps can enter car mode at the default priority and a higher priority. 134 * Verifies that the priority ordering is retained as expected. 135 */ 136 @Test testEnterCarModeDefaultAndHigherPriority()137 public void testEnterCarModeDefaultAndHigherPriority() { 138 testEnterCarModeDefaultPriority(); 139 140 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP3_PACKAGE_NAME); 141 assertEquals(2, mCarModeTracker.getCarModeApps().size()); 142 assertEquals(CAR_MODE_APP3_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 143 assertEquals(CAR_MODE_APP3_PACKAGE_NAME, mCarModeTracker.getCarModeApps().get(0)); 144 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCarModeApps().get(1)); 145 146 mCarModeTracker.handleEnterCarMode(50, CAR_MODE_APP4_PACKAGE_NAME); 147 assertEquals(3, mCarModeTracker.getCarModeApps().size()); 148 assertEquals(CAR_MODE_APP3_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 149 assertEquals(CAR_MODE_APP3_PACKAGE_NAME, mCarModeTracker.getCarModeApps().get(0)); 150 assertEquals(CAR_MODE_APP4_PACKAGE_NAME, mCarModeTracker.getCarModeApps().get(1)); 151 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCarModeApps().get(2)); 152 } 153 154 /** 155 * Verifies entering and exiting car mode at default priority. 156 */ 157 @Test testEnterExitCarModeDefaultPriority()158 public void testEnterExitCarModeDefaultPriority() { 159 mCarModeTracker.handleEnterCarMode(UiModeManager.DEFAULT_PRIORITY, 160 CAR_MODE_APP1_PACKAGE_NAME); 161 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 162 mCarModeTracker.handleExitCarMode(UiModeManager.DEFAULT_PRIORITY, 163 CAR_MODE_APP1_PACKAGE_NAME); 164 assertNull(mCarModeTracker.getCurrentCarModePackage()); 165 } 166 167 /** 168 * Verifies entering and exiting car mode at default priority. 169 * Ensures a different app can exit car mode at the default priority than the one which 170 * entered car mode at that priority. 171 */ 172 @Test testEnterExitCarModeDefaultPriorityDifferentApp()173 public void testEnterExitCarModeDefaultPriorityDifferentApp() { 174 mCarModeTracker.handleEnterCarMode(UiModeManager.DEFAULT_PRIORITY, 175 CAR_MODE_APP1_PACKAGE_NAME); 176 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 177 mCarModeTracker.handleExitCarMode(UiModeManager.DEFAULT_PRIORITY, 178 CAR_MODE_APP2_PACKAGE_NAME); 179 assertNull(mCarModeTracker.getCurrentCarModePackage()); 180 } 181 182 /** 183 * Verifies entering and exiting car mode at higher priority. 184 */ 185 @Test testEnterExitCarModeHigherPriority()186 public void testEnterExitCarModeHigherPriority() { 187 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 188 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 189 mCarModeTracker.handleExitCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 190 assertNull(mCarModeTracker.getCurrentCarModePackage()); 191 } 192 193 /** 194 * Verifies entering and exiting car mode at higher priority, except the exiting app differs. 195 */ 196 @Test testEnterExitCarModeHigherPriorityDifferentApp()197 public void testEnterExitCarModeHigherPriorityDifferentApp() { 198 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 199 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 200 mCarModeTracker.handleExitCarMode(100, CAR_MODE_APP2_PACKAGE_NAME); 201 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 202 } 203 204 /** 205 * Verifies entering and exiting car mode at a bunch of priorities with a bunch of apps. 206 */ 207 @Test testEnterExitCarModeMultiple()208 public void testEnterExitCarModeMultiple() { 209 mCarModeTracker.handleEnterCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 210 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 211 mCarModeTracker.handleEnterCarMode(50, CAR_MODE_APP2_PACKAGE_NAME); 212 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 213 mCarModeTracker.handleEnterCarMode(UiModeManager.DEFAULT_PRIORITY, 214 CAR_MODE_APP3_PACKAGE_NAME); 215 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 216 217 mCarModeTracker.handleExitCarMode(100, CAR_MODE_APP1_PACKAGE_NAME); 218 assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 219 mCarModeTracker.handleExitCarMode(50, CAR_MODE_APP2_PACKAGE_NAME); 220 assertEquals(CAR_MODE_APP3_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 221 mCarModeTracker.handleExitCarMode(UiModeManager.DEFAULT_PRIORITY, 222 CAR_MODE_APP3_PACKAGE_NAME); 223 assertNull(mCarModeTracker.getCurrentCarModePackage()); 224 } 225 226 /** 227 * Verifies that setting automotive projection by itself works. 228 */ 229 @Test testSetAutomotiveProjectionBasic()230 public void testSetAutomotiveProjectionBasic() { 231 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME); 232 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 233 // We should be tracking our car mode app. 234 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 235 assertTrue(mCarModeTracker.isInCarMode()); 236 } 237 238 /** 239 * Verifies that setting automotive projection overrides entering car mode with the highest 240 * priority of 0. Also ensures exiting car mode doesn't interfere with the automotive 241 * projection being set. 242 */ 243 @Test testInterleaveCarModeAndProjectionMode()244 public void testInterleaveCarModeAndProjectionMode() { 245 mCarModeTracker.handleEnterCarMode(0, CAR_MODE_APP1_PACKAGE_NAME); 246 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 247 assertTrue(mCarModeTracker.isInCarMode()); 248 249 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP2_PACKAGE_NAME); 250 assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 251 assertTrue(mCarModeTracker.isInCarMode()); 252 253 mCarModeTracker.handleExitCarMode(0, CAR_MODE_APP1_PACKAGE_NAME); 254 assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 255 assertTrue(mCarModeTracker.isInCarMode()); 256 257 mCarModeTracker.handleReleaseAutomotiveProjection(); 258 } 259 260 /** 261 * Verifies that if we set automotive projection more than once with the same package, nothing 262 * changes. 263 */ 264 @Test testSetAutomotiveProjectionMultipleTimes()265 public void testSetAutomotiveProjectionMultipleTimes() { 266 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME); 267 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME); 268 // Should still only have one app. 269 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 270 assertTrue(mCarModeTracker.isInCarMode()); 271 // It should be the same one. 272 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 273 } 274 275 /** 276 * Verifies that if we set automotive projection more than once, the new package overrides. 277 */ 278 @Test testSetAutomotiveProjectionMultipleTimesDifferentPackages()279 public void testSetAutomotiveProjectionMultipleTimesDifferentPackages() { 280 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME); 281 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP2_PACKAGE_NAME); 282 // Should still only have one app. 283 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 284 assertTrue(mCarModeTracker.isInCarMode()); 285 // It should be the newer one. 286 assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 287 } 288 289 /** 290 * Verifies that releasing automotive projection works as expected. 291 */ 292 @Test testReleaseAutomotiveProjectionBasic()293 public void testReleaseAutomotiveProjectionBasic() { 294 // Releasing before something's set shouldn't break anything. 295 mCarModeTracker.handleReleaseAutomotiveProjection(); 296 assertEquals(0, mCarModeTracker.getCarModeApps().size()); 297 assertFalse(mCarModeTracker.isInCarMode()); 298 299 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP1_PACKAGE_NAME); 300 mCarModeTracker.handleReleaseAutomotiveProjection(); 301 // Should be gone now. 302 assertEquals(0, mCarModeTracker.getCarModeApps().size()); 303 assertFalse(mCarModeTracker.isInCarMode()); 304 } 305 306 /** 307 * Verifies that setting automotive projection overrides but doesn't overwrite car mode apps. 308 */ 309 @Test testAutomotiveProjectionOverridesCarMode()310 public void testAutomotiveProjectionOverridesCarMode() { 311 mCarModeTracker.handleEnterCarMode(50, CAR_MODE_APP1_PACKAGE_NAME); 312 mCarModeTracker.handleSetAutomotiveProjection(CAR_MODE_APP4_PACKAGE_NAME); 313 314 // Should have two apps now, the car mode and the automotive projection one. 315 assertEquals(2, mCarModeTracker.getCarModeApps().size()); 316 assertTrue(mCarModeTracker.isInCarMode()); 317 318 // Automotive projection takes priority. 319 assertEquals(CAR_MODE_APP4_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 320 321 // If we add another car mode app, automotive projection still has priority. 322 mCarModeTracker.handleEnterCarMode(Integer.MAX_VALUE, CAR_MODE_APP2_PACKAGE_NAME); 323 assertEquals(3, mCarModeTracker.getCarModeApps().size()); 324 assertTrue(mCarModeTracker.isInCarMode()); 325 assertEquals(CAR_MODE_APP4_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 326 327 // If we release automotive projection, we go back to the prioritized list of plain car 328 // mode apps. 329 mCarModeTracker.handleReleaseAutomotiveProjection(); 330 assertEquals(2, mCarModeTracker.getCarModeApps().size()); 331 assertTrue(mCarModeTracker.isInCarMode()); 332 assertEquals(CAR_MODE_APP2_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 333 334 // Make sure we didn't mess with the first app that was added. 335 mCarModeTracker.handleExitCarMode(Integer.MAX_VALUE, CAR_MODE_APP2_PACKAGE_NAME); 336 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 337 assertTrue(mCarModeTracker.isInCarMode()); 338 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 339 } 340 341 /** 342 * Verifies that releasing automotive projection doesn't interfere with plain car mode apps. 343 */ 344 @Test testReleaseAutomotiveProjectionNoopForCarModeApps()345 public void testReleaseAutomotiveProjectionNoopForCarModeApps() { 346 mCarModeTracker.handleEnterCarMode(50, CAR_MODE_APP1_PACKAGE_NAME); 347 mCarModeTracker.handleReleaseAutomotiveProjection(); 348 assertEquals(1, mCarModeTracker.getCarModeApps().size()); 349 assertTrue(mCarModeTracker.isInCarMode()); 350 assertEquals(CAR_MODE_APP1_PACKAGE_NAME, mCarModeTracker.getCurrentCarModePackage()); 351 } 352 } 353