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 17 package com.android.server.sdksandbox; 18 19 import static android.Manifest.permission.DUMP; 20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 21 import static android.app.sdksandbox.ISharedPreferencesSyncCallback.PREFERENCES_SYNC_INTERNAL_ERROR; 22 import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY; 23 import static android.app.sdksandbox.SdkSandboxManager.LOAD_SDK_INTERNAL_ERROR; 24 25 import static com.android.server.sdksandbox.SdkSandboxServiceProvider.SANDBOX_INSTR_PROCESS_NAME_SUFFIX; 26 import static com.android.server.sdksandbox.testutils.FakeSdkSandboxProvider.FAKE_DUMP_OUTPUT; 27 import static com.android.server.wm.ActivityInterceptorCallback.MAINLINE_SDK_SANDBOX_ORDER_ID; 28 29 import static com.google.common.truth.Truth.assertThat; 30 31 import static org.junit.Assert.assertEquals; 32 import static org.junit.Assert.assertThrows; 33 import static org.junit.Assume.assumeFalse; 34 import static org.junit.Assume.assumeTrue; 35 import static org.mockito.ArgumentMatchers.any; 36 import static org.mockito.ArgumentMatchers.eq; 37 38 import android.Manifest; 39 import android.app.ActivityManager; 40 import android.app.sdksandbox.AppOwnedSdkSandboxInterface; 41 import android.app.sdksandbox.ILoadSdkCallback; 42 import android.app.sdksandbox.ISharedPreferencesSyncCallback; 43 import android.app.sdksandbox.LoadSdkException; 44 import android.app.sdksandbox.SandboxLatencyInfo; 45 import android.app.sdksandbox.SdkSandboxManager; 46 import android.app.sdksandbox.SharedPreferencesUpdate; 47 import android.app.sdksandbox.testutils.FakeLoadSdkCallbackBinder; 48 import android.app.sdksandbox.testutils.FakeRequestSurfacePackageCallbackBinder; 49 import android.app.sdksandbox.testutils.FakeSdkSandboxManagerLocal; 50 import android.app.sdksandbox.testutils.FakeSdkSandboxProcessDeathCallbackBinder; 51 import android.app.sdksandbox.testutils.FakeSdkSandboxService; 52 import android.app.sdksandbox.testutils.FakeSharedPreferencesSyncCallback; 53 import android.app.sdksandbox.testutils.SdkSandboxDeviceSupportedRule; 54 import android.app.sdksandbox.testutils.SdkSandboxStorageManagerUtility; 55 import android.content.ComponentName; 56 import android.content.Context; 57 import android.content.Intent; 58 import android.content.ServiceConnection; 59 import android.content.pm.ActivityInfo; 60 import android.content.pm.ApplicationInfo; 61 import android.content.pm.PackageManager; 62 import android.content.pm.UserInfo; 63 import android.os.Binder; 64 import android.os.Bundle; 65 import android.os.IBinder; 66 import android.os.ParcelFileDescriptor; 67 import android.os.Process; 68 import android.os.RemoteException; 69 import android.os.ServiceManager; 70 import android.os.UserHandle; 71 import android.util.Log; 72 73 import androidx.test.platform.app.InstrumentationRegistry; 74 75 import com.android.adservices.shared.testing.common.DumpHelper; 76 import com.android.dx.mockito.inline.extended.ExtendedMockito; 77 import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; 78 import com.android.modules.utils.build.SdkLevel; 79 import com.android.sdksandbox.IComputeSdkStorageCallback; 80 import com.android.sdksandbox.IUnloadSdkInSandboxCallback; 81 import com.android.server.LocalManagerRegistry; 82 import com.android.server.SystemService.TargetUser; 83 import com.android.server.am.ActivityManagerLocal; 84 import com.android.server.pm.PackageManagerLocal; 85 import com.android.server.sdksandbox.SdkSandboxStorageManager.StorageDirInfo; 86 import com.android.server.sdksandbox.testutils.FakeSdkSandboxProvider; 87 import com.android.server.wm.ActivityInterceptorCallback; 88 import com.android.server.wm.ActivityInterceptorCallbackRegistry; 89 90 import org.junit.After; 91 import org.junit.Before; 92 import org.junit.Rule; 93 import org.junit.Test; 94 import org.mockito.ArgumentCaptor; 95 import org.mockito.ArgumentMatchers; 96 import org.mockito.Mock; 97 import org.mockito.Mockito; 98 import org.mockito.MockitoSession; 99 import org.mockito.quality.Strictness; 100 101 import java.io.FileDescriptor; 102 import java.io.PrintWriter; 103 import java.io.StringWriter; 104 import java.util.ArrayList; 105 import java.util.Arrays; 106 import java.util.Collections; 107 import java.util.List; 108 import java.util.Objects; 109 110 /** 111 * Unit tests for {@link SdkSandboxManagerService}. 112 */ 113 public class SdkSandboxManagerServiceUnitTest { 114 115 private static final String TAG = SdkSandboxManagerServiceUnitTest.class.getSimpleName(); 116 117 private static final String SDK_NAME = "com.android.codeprovider"; 118 private static final String APP_OWNED_SDK_SANDBOX_INTERFACE_NAME = "com.android.testinterface"; 119 private static final String SDK_PROVIDER_PACKAGE = "com.android.codeprovider_1"; 120 private static final String SDK_PROVIDER_RESOURCES_SDK_NAME = 121 "com.android.codeproviderresources"; 122 private static final String TEST_PACKAGE = "com.android.server.sdksandbox.tests"; 123 private static final String PROPERTY_DISABLE_SANDBOX = "disable_sdk_sandbox"; 124 125 private static final String TEST_KEY = "key"; 126 private static final String TEST_VALUE = "value"; 127 private static final SharedPreferencesUpdate TEST_UPDATE = 128 new SharedPreferencesUpdate(new ArrayList<>(), getTestBundle()); 129 130 private SdkSandboxManagerService mService; 131 private ActivityManager mAmSpy; 132 private FakeSdkSandboxService mSdkSandboxService; 133 private MockitoSession mStaticMockSession; 134 private Context mSpyContext; 135 private SdkSandboxManagerService.Injector mInjector; 136 private int mClientAppUid; 137 private PackageManagerLocal mPmLocal; 138 private ActivityManagerLocal mAmLocal; 139 private ArgumentCaptor<ActivityInterceptorCallback> mInterceptorCallbackArgumentCaptor = 140 ArgumentCaptor.forClass(ActivityInterceptorCallback.class); 141 private SdkSandboxStorageManagerUtility mSdkSandboxStorageManagerUtility; 142 private boolean mDisabledNetworkChecks; 143 private boolean mDisabledForegroundCheck; 144 private SandboxLatencyInfo mSandboxLatencyInfo; 145 146 @Mock private IBinder mAdServicesManager; 147 148 private static FakeSdkSandboxProvider sProvider; 149 private static SdkSandboxPulledAtoms sSdkSandboxPulledAtoms; 150 151 private static SdkSandboxSettingsListener sSdkSandboxSettingsListener; 152 153 private SdkSandboxStorageManager mSdkSandboxStorageManager; 154 private static SdkSandboxManagerLocal sSdkSandboxManagerLocal; 155 private CallingInfo mCallingInfo; 156 private DeviceConfigUtil mDeviceConfigUtil; 157 158 @Rule(order = 0) 159 public final SdkSandboxDeviceSupportedRule supportedRule = new SdkSandboxDeviceSupportedRule(); 160 161 @Before setup()162 public void setup() { 163 StaticMockitoSessionBuilder mockitoSessionBuilder = 164 ExtendedMockito.mockitoSession() 165 .strictness(Strictness.LENIENT) 166 .mockStatic(LocalManagerRegistry.class) 167 .spyStatic(Process.class) 168 .initMocks(this); 169 if (SdkLevel.isAtLeastU()) { 170 mockitoSessionBuilder = 171 mockitoSessionBuilder.mockStatic(ActivityInterceptorCallbackRegistry.class); 172 } 173 // Required to access <sdk-library> information and DeviceConfig update. 174 InstrumentationRegistry.getInstrumentation() 175 .getUiAutomation() 176 .adoptShellPermissionIdentity( 177 Manifest.permission.ACCESS_SHARED_LIBRARIES, 178 Manifest.permission.INSTALL_PACKAGES, 179 Manifest.permission.READ_DEVICE_CONFIG, 180 Manifest.permission.WRITE_DEVICE_CONFIG, 181 // for Context#registerReceiverForAllUsers 182 Manifest.permission.INTERACT_ACROSS_USERS_FULL); 183 184 mStaticMockSession = mockitoSessionBuilder.startMocking(); 185 186 if (SdkLevel.isAtLeastU()) { 187 // mock the activity interceptor registry anc capture the callback if called 188 ActivityInterceptorCallbackRegistry registryMock = 189 Mockito.mock(ActivityInterceptorCallbackRegistry.class); 190 ExtendedMockito.doReturn(registryMock) 191 .when(ActivityInterceptorCallbackRegistry::getInstance); 192 Mockito.doNothing() 193 .when(registryMock) 194 .registerActivityInterceptorCallback( 195 eq(MAINLINE_SDK_SANDBOX_ORDER_ID), 196 mInterceptorCallbackArgumentCaptor.capture()); 197 } 198 199 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 200 mSpyContext = Mockito.spy(context); 201 ActivityManager am = context.getSystemService(ActivityManager.class); 202 mAmSpy = Mockito.spy(Objects.requireNonNull(am)); 203 204 Mockito.when(mSpyContext.getSystemService(ActivityManager.class)).thenReturn(mAmSpy); 205 206 mSdkSandboxService = Mockito.spy(FakeSdkSandboxService.class); 207 sProvider = new FakeSdkSandboxProvider(mSdkSandboxService); 208 209 // Populate LocalManagerRegistry 210 mAmLocal = Mockito.mock(ActivityManagerLocal.class); 211 ExtendedMockito.doReturn(mAmLocal) 212 .when(() -> LocalManagerRegistry.getManager(ActivityManagerLocal.class)); 213 mPmLocal = Mockito.spy(PackageManagerLocal.class); 214 215 sSdkSandboxPulledAtoms = Mockito.spy(new SdkSandboxPulledAtoms()); 216 217 String testDir = context.getDir("test_dir", Context.MODE_PRIVATE).getPath(); 218 mSdkSandboxStorageManager = 219 new SdkSandboxStorageManager( 220 mSpyContext, new FakeSdkSandboxManagerLocal(), mPmLocal, testDir); 221 mSdkSandboxStorageManagerUtility = 222 new SdkSandboxStorageManagerUtility(mSdkSandboxStorageManager); 223 224 mInjector = 225 Mockito.spy( 226 new FakeInjector( 227 mSpyContext, 228 mSdkSandboxStorageManager, 229 sProvider, 230 sSdkSandboxPulledAtoms, 231 new SdkSandboxStatsdLogger())); 232 233 mService = new SdkSandboxManagerService(mSpyContext, mInjector); 234 sSdkSandboxManagerLocal = mService.getLocalManager(); 235 assertThat(sSdkSandboxManagerLocal).isNotNull(); 236 237 sSdkSandboxSettingsListener = mService.getSdkSandboxSettingsListener(); 238 mDeviceConfigUtil = new DeviceConfigUtil(sSdkSandboxSettingsListener); 239 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "false"); 240 241 mClientAppUid = Process.myUid(); 242 mSandboxLatencyInfo = new SandboxLatencyInfo(); 243 mCallingInfo = new CallingInfo(mClientAppUid, TEST_PACKAGE); 244 } 245 246 @After tearDown()247 public void tearDown() { 248 if (sSdkSandboxSettingsListener != null) { 249 sSdkSandboxSettingsListener.unregisterPropertiesListener(); 250 } 251 if (mStaticMockSession != null) { 252 mStaticMockSession.finishMocking(); 253 } 254 } 255 256 /** Mock the ActivityManager::killUid to avoid SecurityException thrown in test. **/ disableKillUid()257 private void disableKillUid() { 258 Mockito.doNothing().when(mAmSpy).killUid(Mockito.anyInt(), Mockito.anyString()); 259 } 260 disableForegroundCheck()261 private void disableForegroundCheck() { 262 if (!mDisabledForegroundCheck) { 263 Mockito.doReturn(IMPORTANCE_FOREGROUND).when(mAmSpy).getUidImportance(Mockito.anyInt()); 264 mDisabledForegroundCheck = true; 265 } 266 } 267 268 /* Ignores network permission checks. */ disableNetworkPermissionChecks()269 private void disableNetworkPermissionChecks() { 270 if (!mDisabledNetworkChecks) { 271 Mockito.doNothing() 272 .when(mSpyContext) 273 .enforceCallingPermission( 274 Mockito.eq("android.permission.INTERNET"), Mockito.anyString()); 275 Mockito.doNothing() 276 .when(mSpyContext) 277 .enforceCallingPermission( 278 Mockito.eq("android.permission.ACCESS_NETWORK_STATE"), 279 Mockito.anyString()); 280 mDisabledNetworkChecks = true; 281 } 282 } 283 284 @Test testOnUserUnlocking()285 public void testOnUserUnlocking() { 286 UserInfo userInfo = new UserInfo(/*id=*/ 0, /*name=*/ "tempUser", /*flags=*/ 0); 287 TargetUser user = new TargetUser(userInfo); 288 289 SdkSandboxManagerService.Lifecycle lifeCycle = 290 new SdkSandboxManagerService.Lifecycle(mSpyContext); 291 lifeCycle.mService = Mockito.mock(SdkSandboxManagerService.class); 292 lifeCycle.onUserUnlocking(user); 293 Mockito.verify(lifeCycle.mService).onUserUnlocking(ArgumentMatchers.eq(/*userId=*/ 0)); 294 } 295 296 @Test testSdkSandboxManagerIsRegistered()297 public void testSdkSandboxManagerIsRegistered() throws Exception { 298 ServiceManager.getServiceOrThrow(SdkSandboxManager.SDK_SANDBOX_SERVICE); 299 } 300 301 @Test testRegisterAndGetAppOwnedSdkSandboxInterfaceSuccess()302 public void testRegisterAndGetAppOwnedSdkSandboxInterfaceSuccess() throws Exception { 303 final IBinder iBinder = new Binder(); 304 305 mService.registerAppOwnedSdkSandboxInterface( 306 TEST_PACKAGE, 307 new AppOwnedSdkSandboxInterface( 308 APP_OWNED_SDK_SANDBOX_INTERFACE_NAME, 309 /*version=*/ 0, 310 /*interfaceIBinder=*/ iBinder), 311 mSandboxLatencyInfo); 312 final List<AppOwnedSdkSandboxInterface> appOwnedSdkSandboxInterfaceList = 313 mService.getAppOwnedSdkSandboxInterfaces(TEST_PACKAGE, mSandboxLatencyInfo); 314 315 assertThat(appOwnedSdkSandboxInterfaceList).hasSize(1); 316 assertThat(appOwnedSdkSandboxInterfaceList.get(0).getName()) 317 .isEqualTo(APP_OWNED_SDK_SANDBOX_INTERFACE_NAME); 318 assertThat(appOwnedSdkSandboxInterfaceList.get(0).getVersion()).isEqualTo(0); 319 assertThat(appOwnedSdkSandboxInterfaceList.get(0).getInterface()).isEqualTo(iBinder); 320 } 321 322 @Test testRegisterAppOwnedSdkSandboxInterfaceAlreadyRegistered()323 public void testRegisterAppOwnedSdkSandboxInterfaceAlreadyRegistered() throws Exception { 324 mService.registerAppOwnedSdkSandboxInterface( 325 TEST_PACKAGE, 326 new AppOwnedSdkSandboxInterface( 327 APP_OWNED_SDK_SANDBOX_INTERFACE_NAME, 328 /*version=*/ 0, 329 /*interfaceIBinder=*/ new Binder()), 330 mSandboxLatencyInfo); 331 332 assertThrows( 333 IllegalStateException.class, 334 () -> 335 mService.registerAppOwnedSdkSandboxInterface( 336 TEST_PACKAGE, 337 new AppOwnedSdkSandboxInterface( 338 APP_OWNED_SDK_SANDBOX_INTERFACE_NAME, 339 /*version=*/ 0, 340 /*interfaceIBinder=*/ new Binder()), 341 mSandboxLatencyInfo)); 342 } 343 344 @Test testUnregisterAppOwnedSdkSandboxInterface()345 public void testUnregisterAppOwnedSdkSandboxInterface() throws Exception { 346 mService.registerAppOwnedSdkSandboxInterface( 347 TEST_PACKAGE, 348 new AppOwnedSdkSandboxInterface( 349 APP_OWNED_SDK_SANDBOX_INTERFACE_NAME, 350 /*version=*/ 0, 351 /*interfaceIBinder=*/ new Binder()), 352 mSandboxLatencyInfo); 353 mService.unregisterAppOwnedSdkSandboxInterface( 354 TEST_PACKAGE, APP_OWNED_SDK_SANDBOX_INTERFACE_NAME, mSandboxLatencyInfo); 355 356 assertThat(mService.getAppOwnedSdkSandboxInterfaces(TEST_PACKAGE, mSandboxLatencyInfo)) 357 .hasSize(0); 358 } 359 360 @Test testLoadSdkIsSuccessful()361 public void testLoadSdkIsSuccessful() throws Exception { 362 disableNetworkPermissionChecks(); 363 disableForegroundCheck(); 364 365 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 366 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 367 // Assume sdk sandbox loads successfully 368 mSdkSandboxService.sendLoadSdkSuccessful(); 369 callback.assertLoadSdkIsSuccessful(); 370 } 371 372 @Test testLoadSdkNonExistentCallingPackage()373 public void testLoadSdkNonExistentCallingPackage() { 374 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 375 376 mService.loadSdk( 377 "does.not.exist", null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 378 379 LoadSdkException thrown = callback.getLoadSdkException(); 380 assertEquals(LOAD_SDK_INTERNAL_ERROR, thrown.getLoadSdkErrorCode()); 381 assertThat(thrown).hasMessageThat().contains("does.not.exist"); 382 } 383 384 // Tests the failure of attempting to load an SDK when the calling package name and calling uid 385 // does not match. 386 @Test testLoadSdkIncorrectCallingPackage()387 public void testLoadSdkIncorrectCallingPackage() { 388 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 389 390 // Try loading the SDK from another installed sample app with a different uid. 391 mService.loadSdk( 392 "com.android.emptysampleapp", 393 null, 394 SDK_NAME, 395 mSandboxLatencyInfo, 396 new Bundle(), 397 callback); 398 399 LoadSdkException thrown = callback.getLoadSdkException(); 400 assertEquals(LOAD_SDK_INTERNAL_ERROR, thrown.getLoadSdkErrorCode()); 401 assertThat(thrown).hasMessageThat().contains("does not belong to uid"); 402 } 403 404 @Test testLoadSdkPackageDoesNotExist()405 public void testLoadSdkPackageDoesNotExist() { 406 disableNetworkPermissionChecks(); 407 disableForegroundCheck(); 408 409 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 410 mService.loadSdk( 411 TEST_PACKAGE, null, "does.not.exist", mSandboxLatencyInfo, new Bundle(), callback); 412 413 // Verify loading failed 414 callback.assertLoadSdkIsUnsuccessful(); 415 assertThat(callback.getLoadSdkErrorCode()) 416 .isEqualTo(SdkSandboxManager.LOAD_SDK_NOT_FOUND); 417 assertThat(callback.getLoadSdkErrorMsg()).contains("does.not.exist"); 418 } 419 420 @Test testLoadSdk_errorFromSdkSandbox()421 public void testLoadSdk_errorFromSdkSandbox() throws Exception { 422 disableNetworkPermissionChecks(); 423 disableForegroundCheck(); 424 425 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 426 427 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 428 mSdkSandboxService.sendLoadSdkError(); 429 430 // Verify loading failed 431 callback.assertLoadSdkIsUnsuccessful(); 432 assertThat(callback.getLoadSdkErrorCode()).isEqualTo(LOAD_SDK_INTERNAL_ERROR); 433 } 434 435 @Test testLoadSdk_errorNoInternet()436 public void testLoadSdk_errorNoInternet() throws Exception { 437 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 438 439 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 440 441 LoadSdkException thrown = callback.getLoadSdkException(); 442 assertEquals(LOAD_SDK_INTERNAL_ERROR, thrown.getLoadSdkErrorCode()); 443 assertThat(thrown).hasMessageThat().contains(android.Manifest.permission.INTERNET); 444 } 445 446 @Test testLoadSdk_errorNoAccessNetworkState()447 public void testLoadSdk_errorNoAccessNetworkState() throws Exception { 448 // Stub out internet permission check 449 Mockito.doNothing().when(mSpyContext).enforceCallingPermission( 450 Mockito.eq("android.permission.INTERNET"), Mockito.anyString()); 451 452 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 453 454 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 455 456 LoadSdkException thrown = callback.getLoadSdkException(); 457 assertEquals(LOAD_SDK_INTERNAL_ERROR, thrown.getLoadSdkErrorCode()); 458 assertThat(thrown).hasMessageThat().contains( 459 android.Manifest.permission.ACCESS_NETWORK_STATE); 460 } 461 462 @Test testLoadSdk_successOnFirstLoad_errorOnLoadAgain()463 public void testLoadSdk_successOnFirstLoad_errorOnLoadAgain() throws Exception { 464 disableNetworkPermissionChecks(); 465 disableForegroundCheck(); 466 467 // Load it once 468 { 469 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 470 mService.loadSdk( 471 TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 472 // Assume SdkSandbox loads successfully 473 mSdkSandboxService.sendLoadSdkSuccessful(); 474 callback.assertLoadSdkIsSuccessful(); 475 } 476 477 // Load it again 478 { 479 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 480 mService.loadSdk( 481 TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 482 // Verify loading failed 483 callback.assertLoadSdkIsUnsuccessful(); 484 assertThat(callback.getLoadSdkErrorCode()) 485 .isEqualTo(SdkSandboxManager.LOAD_SDK_ALREADY_LOADED); 486 assertThat(callback.getLoadSdkErrorMsg()).contains("has been loaded already"); 487 } 488 } 489 490 @Test testLoadSdk_firstLoadPending_errorOnLoadAgainRequest()491 public void testLoadSdk_firstLoadPending_errorOnLoadAgainRequest() throws Exception { 492 disableNetworkPermissionChecks(); 493 disableForegroundCheck(); 494 495 // Request to load the SDK, but do not complete loading it 496 { 497 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 498 mService.loadSdk( 499 TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 500 } 501 502 // Requesting to load the SDK while the first load is still pending should throw an error 503 { 504 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 505 mService.loadSdk( 506 TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 507 // Verify loading failed 508 callback.assertLoadSdkIsUnsuccessful(); 509 assertThat(callback.getLoadSdkErrorCode()) 510 .isEqualTo(SdkSandboxManager.LOAD_SDK_ALREADY_LOADED); 511 assertThat(callback.getLoadSdkErrorMsg()).contains("is currently being loaded"); 512 } 513 } 514 515 @Test testLoadSdk_errorOnFirstLoad_canBeLoadedAgain()516 public void testLoadSdk_errorOnFirstLoad_canBeLoadedAgain() throws Exception { 517 disableNetworkPermissionChecks(); 518 disableForegroundCheck(); 519 520 // Load SDK, but make it fail 521 { 522 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 523 mService.loadSdk( 524 TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 525 // Assume sdk load fails 526 mSdkSandboxService.sendLoadSdkError(); 527 callback.assertLoadSdkIsUnsuccessful(); 528 } 529 530 // Caller should be able to retry loading the code 531 loadSdk(SDK_NAME); 532 } 533 534 @Test testLoadSdk_sandboxDiesInBetween()535 public void testLoadSdk_sandboxDiesInBetween() throws Exception { 536 disableNetworkPermissionChecks(); 537 disableForegroundCheck(); 538 539 // Load an sdk 540 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 541 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 542 543 // Kill the sandbox before the SDK can call the callback 544 killSandbox(); 545 546 callback.assertLoadSdkIsUnsuccessful(); 547 assertThat(callback.getLoadSdkErrorCode()) 548 .isEqualTo(SdkSandboxManager.SDK_SANDBOX_PROCESS_NOT_AVAILABLE); 549 } 550 551 @Test testSdkCanBeLoadedAfterSandboxDeath()552 public void testSdkCanBeLoadedAfterSandboxDeath() throws Exception { 553 loadSdk(SDK_NAME); 554 killSandbox(); 555 loadSdk(SDK_NAME); 556 } 557 558 @Test testLoadSdk_sandboxIsInitialized()559 public void testLoadSdk_sandboxIsInitialized() throws Exception { 560 loadSdk(SDK_NAME); 561 562 // Verify that sandbox was initialized 563 assertThat(mSdkSandboxService.getInitializationCount()).isEqualTo(1); 564 } 565 566 @Test testLoadSdk_sandboxIsInitialized_onlyOnce()567 public void testLoadSdk_sandboxIsInitialized_onlyOnce() throws Exception { 568 loadSdk(SDK_NAME); 569 loadSdk(SDK_PROVIDER_RESOURCES_SDK_NAME); 570 571 // Verify that sandbox was initialized 572 assertThat(mSdkSandboxService.getInitializationCount()).isEqualTo(1); 573 } 574 575 @Test testLoadSdk_sandboxIsInitializedAfterRestart()576 public void testLoadSdk_sandboxIsInitializedAfterRestart() throws Exception { 577 loadSdk(SDK_NAME); 578 restartAndSetSandboxService(); 579 // Restarting creates and sets a new sandbox service. Verify that the new one has been 580 // initialized. 581 assertThat(mSdkSandboxService.getInitializationCount()).isEqualTo(1); 582 } 583 584 @Test testLoadSdk_sandboxInitializationFails()585 public void testLoadSdk_sandboxInitializationFails() throws Exception { 586 disableNetworkPermissionChecks(); 587 disableForegroundCheck(); 588 disableKillUid(); 589 590 mSdkSandboxService.failInitialization = true; 591 592 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 593 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 594 595 // If initialization failed, the sandbox would be unbound. 596 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNull(); 597 598 // Call binderDied() on the sandbox to apply the effects of sandbox death detection after 599 // unbinding. 600 killSandbox(); 601 602 mSdkSandboxService.failInitialization = false; 603 // SDK loading should succeed afterwards. 604 loadSdk(SDK_NAME); 605 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNotNull(); 606 } 607 608 @Test testLoadSdk_sdkDataPrepared_onlyOnce()609 public void testLoadSdk_sdkDataPrepared_onlyOnce() throws Exception { 610 loadSdk(SDK_NAME); 611 loadSdk(SDK_PROVIDER_RESOURCES_SDK_NAME); 612 613 // Verify that SDK data was prepared. 614 Mockito.verify(mPmLocal, Mockito.times(1)) 615 .reconcileSdkData( 616 Mockito.nullable(String.class), 617 Mockito.anyString(), 618 Mockito.anyList(), 619 Mockito.anyInt(), 620 Mockito.anyInt(), 621 Mockito.anyInt(), 622 Mockito.anyString(), 623 Mockito.anyInt()); 624 } 625 626 @Test testLoadSdk_sdkDataPreparedAfterSandboxRestart()627 public void testLoadSdk_sdkDataPreparedAfterSandboxRestart() throws Exception { 628 loadSdk(SDK_NAME); 629 restartAndSetSandboxService(); 630 631 // Verify that SDK data was prepared for the newly restarted sandbox. 632 Mockito.verify(mPmLocal, Mockito.times(1)) 633 .reconcileSdkData( 634 Mockito.nullable(String.class), 635 Mockito.anyString(), 636 Mockito.anyList(), 637 Mockito.anyInt(), 638 Mockito.anyInt(), 639 Mockito.anyInt(), 640 Mockito.anyString(), 641 Mockito.anyInt()); 642 } 643 644 @Test testRequestSurfacePackageSdkNotLoaded_SandboxExists()645 public void testRequestSurfacePackageSdkNotLoaded_SandboxExists() throws Exception { 646 disableNetworkPermissionChecks(); 647 disableForegroundCheck(); 648 649 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 650 mService.loadSdk( 651 TEST_PACKAGE, 652 null, 653 SDK_NAME, 654 mSandboxLatencyInfo, 655 new Bundle(), 656 callback); 657 // Assume SdkSandbox loads successfully 658 mSdkSandboxService.sendLoadSdkSuccessful(); 659 callback.assertLoadSdkIsSuccessful(); 660 661 // Trying to request package with not exist SDK packageName 662 String sdkName = "invalid"; 663 FakeRequestSurfacePackageCallbackBinder surfacePackageCallback = 664 new FakeRequestSurfacePackageCallbackBinder(); 665 mService.requestSurfacePackage( 666 TEST_PACKAGE, 667 sdkName, 668 new Binder(), 669 0, 670 500, 671 500, 672 mSandboxLatencyInfo, 673 new Bundle(), 674 surfacePackageCallback); 675 assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isFalse(); 676 assertThat(surfacePackageCallback.getSurfacePackageErrorCode()) 677 .isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED); 678 } 679 680 @Test testRequestSurfacePackageSdkNotLoaded_SandboxDoesNotExist()681 public void testRequestSurfacePackageSdkNotLoaded_SandboxDoesNotExist() throws Exception { 682 disableForegroundCheck(); 683 684 // Trying to request package when sandbox is not there 685 String sdkName = "invalid"; 686 FakeRequestSurfacePackageCallbackBinder callback = 687 new FakeRequestSurfacePackageCallbackBinder(); 688 mService.requestSurfacePackage( 689 TEST_PACKAGE, 690 sdkName, 691 new Binder(), 692 0, 693 500, 694 500, 695 mSandboxLatencyInfo, 696 new Bundle(), 697 callback); 698 assertThat(callback.isRequestSurfacePackageSuccessful()).isFalse(); 699 assertThat(callback.getSurfacePackageErrorCode()) 700 .isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED); 701 } 702 703 @Test testRequestSurfacePackage()704 public void testRequestSurfacePackage() throws Exception { 705 // 1. We first need to collect a proper sdkToken by calling loadCode 706 loadSdk(SDK_NAME); 707 708 // 2. Call request package with the retrieved sdkToken 709 FakeRequestSurfacePackageCallbackBinder surfacePackageCallback = 710 new FakeRequestSurfacePackageCallbackBinder(); 711 mService.requestSurfacePackage( 712 TEST_PACKAGE, 713 SDK_NAME, 714 new Binder(), 715 0, 716 500, 717 500, 718 mSandboxLatencyInfo, 719 new Bundle(), 720 surfacePackageCallback); 721 mSdkSandboxService.sendSurfacePackageReady(new SandboxLatencyInfo()); 722 assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isTrue(); 723 } 724 725 @Test testRequestSurfacePackageFailedAfterAppDied()726 public void testRequestSurfacePackageFailedAfterAppDied() throws Exception { 727 disableKillUid(); 728 disableNetworkPermissionChecks(); 729 disableForegroundCheck(); 730 731 FakeLoadSdkCallbackBinder callback = Mockito.spy(new FakeLoadSdkCallbackBinder()); 732 Mockito.doReturn(Mockito.mock(Binder.class)).when(callback).asBinder(); 733 734 ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = 735 ArgumentCaptor.forClass(IBinder.DeathRecipient.class); 736 737 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 738 mSdkSandboxService.sendLoadSdkSuccessful(); 739 callback.assertLoadSdkIsSuccessful(); 740 741 Mockito.verify(callback.asBinder()) 742 .linkToDeath(deathRecipient.capture(), ArgumentMatchers.eq(0)); 743 744 // App Died 745 deathRecipient.getValue().binderDied(); 746 747 FakeRequestSurfacePackageCallbackBinder requestSurfacePackageCallback = 748 new FakeRequestSurfacePackageCallbackBinder(); 749 mService.requestSurfacePackage( 750 TEST_PACKAGE, 751 SDK_NAME, 752 new Binder(), 753 0, 754 500, 755 500, 756 mSandboxLatencyInfo, 757 new Bundle(), 758 requestSurfacePackageCallback); 759 assertThat(requestSurfacePackageCallback.isRequestSurfacePackageSuccessful()).isFalse(); 760 assertThat(requestSurfacePackageCallback.getSurfacePackageErrorCode()) 761 .isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED); 762 } 763 764 @Test testSurfacePackageError()765 public void testSurfacePackageError() throws Exception { 766 loadSdk(SDK_NAME); 767 768 // Assume SurfacePackage encounters an error. 769 FakeRequestSurfacePackageCallbackBinder surfacePackageCallback = 770 new FakeRequestSurfacePackageCallbackBinder(); 771 mSdkSandboxService.sendSurfacePackageError( 772 SdkSandboxManager.REQUEST_SURFACE_PACKAGE_INTERNAL_ERROR, 773 "bad surface", 774 surfacePackageCallback); 775 assertThat(surfacePackageCallback.getSurfacePackageErrorMsg()).contains("bad surface"); 776 assertThat(surfacePackageCallback.getSurfacePackageErrorCode()) 777 .isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_INTERNAL_ERROR); 778 } 779 780 @Test testRequestSurfacePackage_SandboxDiesInBetween()781 public void testRequestSurfacePackage_SandboxDiesInBetween() throws Exception { 782 disableNetworkPermissionChecks(); 783 disableForegroundCheck(); 784 785 // Load an sdk 786 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 787 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 788 mSdkSandboxService.sendLoadSdkSuccessful(); 789 callback.assertLoadSdkIsSuccessful(); 790 791 // Request surface package from the SDK 792 FakeRequestSurfacePackageCallbackBinder surfacePackageCallback = 793 new FakeRequestSurfacePackageCallbackBinder(); 794 mService.requestSurfacePackage( 795 TEST_PACKAGE, 796 SDK_NAME, 797 new Binder(), 798 0, 799 500, 800 500, 801 mSandboxLatencyInfo, 802 new Bundle(), 803 surfacePackageCallback); 804 805 // Kill the sandbox before the SDK can call the callback 806 killSandbox(); 807 808 assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isFalse(); 809 assertThat(surfacePackageCallback.getSurfacePackageErrorCode()) 810 .isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED); 811 } 812 813 @Test testAddSdkSandboxProcessDeathCallback_BeforeStartingSandbox()814 public void testAddSdkSandboxProcessDeathCallback_BeforeStartingSandbox() throws Exception { 815 // Register for sandbox death event 816 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback = 817 new FakeSdkSandboxProcessDeathCallbackBinder(); 818 mService.addSdkSandboxProcessDeathCallback( 819 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback); 820 821 // Load SDK and start the sandbox 822 loadSdk(SDK_NAME); 823 824 killSandbox(); 825 826 // Check that death is recorded correctly 827 assertThat(lifecycleCallback.waitForSandboxDeath()).isTrue(); 828 } 829 830 @Test testAddSdkSandboxProcessDeathCallback_AfterStartingSandbox()831 public void testAddSdkSandboxProcessDeathCallback_AfterStartingSandbox() throws Exception { 832 // Load SDK and start the sandbox 833 loadSdk(SDK_NAME); 834 835 // Register for sandbox death event 836 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback = 837 new FakeSdkSandboxProcessDeathCallbackBinder(); 838 mService.addSdkSandboxProcessDeathCallback( 839 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback); 840 841 killSandbox(); 842 843 // Check that death is recorded correctly 844 assertThat(lifecycleCallback.waitForSandboxDeath()).isTrue(); 845 } 846 847 @Test testSdkSandboxProcessDeathCallback_AfterRestartingSandbox()848 public void testSdkSandboxProcessDeathCallback_AfterRestartingSandbox() throws Exception { 849 loadSdk(SDK_NAME); 850 851 // Register for sandbox death event 852 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback1 = 853 new FakeSdkSandboxProcessDeathCallbackBinder(); 854 mService.addSdkSandboxProcessDeathCallback( 855 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback1); 856 killSandbox(); 857 assertThat(lifecycleCallback1.waitForSandboxDeath()).isTrue(); 858 859 restartAndSetSandboxService(); 860 861 // Register for sandbox death event again and verify that death is detected. 862 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback2 = 863 new FakeSdkSandboxProcessDeathCallbackBinder(); 864 mService.addSdkSandboxProcessDeathCallback( 865 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback2); 866 assertThat(lifecycleCallback2.waitForSandboxDeath()).isFalse(); 867 killSandbox(); 868 assertThat(lifecycleCallback2.waitForSandboxDeath()).isTrue(); 869 } 870 871 @Test testMultipleAddSdkSandboxProcessDeathCallbacks()872 public void testMultipleAddSdkSandboxProcessDeathCallbacks() throws Exception { 873 // Load SDK and start the sandbox 874 loadSdk(SDK_NAME); 875 876 // Register for sandbox death event 877 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback1 = 878 new FakeSdkSandboxProcessDeathCallbackBinder(); 879 mService.addSdkSandboxProcessDeathCallback( 880 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback1); 881 882 // Register for sandbox death event again 883 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback2 = 884 new FakeSdkSandboxProcessDeathCallbackBinder(); 885 mService.addSdkSandboxProcessDeathCallback( 886 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback2); 887 888 killSandbox(); 889 890 // Check that death is recorded correctly 891 assertThat(lifecycleCallback1.waitForSandboxDeath()).isTrue(); 892 assertThat(lifecycleCallback2.waitForSandboxDeath()).isTrue(); 893 } 894 895 @Test testRemoveSdkSandboxProcessDeathCallback()896 public void testRemoveSdkSandboxProcessDeathCallback() throws Exception { 897 // Load SDK and start the sandbox 898 loadSdk(SDK_NAME); 899 900 // Register for sandbox death event 901 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback1 = 902 new FakeSdkSandboxProcessDeathCallbackBinder(); 903 mService.addSdkSandboxProcessDeathCallback( 904 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback1); 905 906 // Register for sandbox death event again 907 FakeSdkSandboxProcessDeathCallbackBinder lifecycleCallback2 = 908 new FakeSdkSandboxProcessDeathCallbackBinder(); 909 mService.addSdkSandboxProcessDeathCallback( 910 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback2); 911 912 // Unregister one of the lifecycle callbacks 913 mService.removeSdkSandboxProcessDeathCallback( 914 TEST_PACKAGE, mSandboxLatencyInfo, lifecycleCallback1); 915 916 killSandbox(); 917 918 // Check that death is recorded correctly 919 assertThat(lifecycleCallback1.waitForSandboxDeath()).isFalse(); 920 assertThat(lifecycleCallback2.waitForSandboxDeath()).isTrue(); 921 } 922 923 @Test testSdkSandboxServiceUnbindingWhenAppDied()924 public void testSdkSandboxServiceUnbindingWhenAppDied() throws Exception { 925 disableKillUid(); 926 disableNetworkPermissionChecks(); 927 disableForegroundCheck(); 928 929 ILoadSdkCallback.Stub callback = Mockito.spy(ILoadSdkCallback.Stub.class); 930 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNull(); 931 932 mService.loadSdk( 933 TEST_PACKAGE, 934 null, 935 SDK_NAME, 936 mSandboxLatencyInfo, 937 new Bundle(), 938 callback); 939 940 ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = ArgumentCaptor 941 .forClass(IBinder.DeathRecipient.class); 942 Mockito.verify(callback.asBinder(), Mockito.times(1)) 943 .linkToDeath(deathRecipient.capture(), Mockito.eq(0)); 944 945 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNotNull(); 946 deathRecipient.getValue().binderDied(); 947 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNull(); 948 } 949 950 @Test testEnforceAllowedToHostSandboxedActivityFailIfCalledFromSandboxUid()951 public void testEnforceAllowedToHostSandboxedActivityFailIfCalledFromSandboxUid() 952 throws RemoteException { 953 loadSdk(SDK_NAME); 954 955 SecurityException exception = 956 assertThrows( 957 SecurityException.class, 958 () -> { 959 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 960 new Intent(), 961 Process.toSdkSandboxUid(mClientAppUid), 962 TEST_PACKAGE); 963 }); 964 assertEquals( 965 "Sandbox process is not allowed to start sandbox activities.", 966 exception.getMessage()); 967 } 968 969 @Test testEnforceAllowedToHostSandboxedActivityFailForNullIntents()970 public void testEnforceAllowedToHostSandboxedActivityFailForNullIntents() { 971 SecurityException exception = 972 assertThrows( 973 SecurityException.class, 974 () -> { 975 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 976 null, mClientAppUid, TEST_PACKAGE); 977 }); 978 assertEquals("Intent to start sandbox activity is null.", exception.getMessage()); 979 } 980 981 @Test testEnforceAllowedToHostSandboxedActivityFailForNullActions()982 public void testEnforceAllowedToHostSandboxedActivityFailForNullActions() { 983 SecurityException exception = 984 assertThrows( 985 SecurityException.class, 986 () -> { 987 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 988 new Intent(), mClientAppUid, TEST_PACKAGE); 989 }); 990 assertEquals( 991 "Sandbox activity intent must have an action (" 992 + ACTION_START_SANDBOXED_ACTIVITY 993 + ").", 994 exception.getMessage()); 995 } 996 997 @Test testEnforceAllowedToHostSandboxedActivityFailForWrongAction()998 public void testEnforceAllowedToHostSandboxedActivityFailForWrongAction() { 999 SecurityException exception = 1000 assertThrows( 1001 SecurityException.class, 1002 () -> { 1003 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1004 new Intent().setAction(Intent.ACTION_VIEW), 1005 mClientAppUid, 1006 TEST_PACKAGE); 1007 }); 1008 assertEquals( 1009 "Sandbox activity intent must have an action (" 1010 + ACTION_START_SANDBOXED_ACTIVITY 1011 + ").", 1012 exception.getMessage()); 1013 } 1014 1015 @Test testEnforceAllowedToHostSandboxedActivityFailForNullPackage()1016 public void testEnforceAllowedToHostSandboxedActivityFailForNullPackage() { 1017 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1018 SecurityException exception = 1019 assertThrows( 1020 SecurityException.class, 1021 () -> { 1022 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1023 intent, mClientAppUid, TEST_PACKAGE); 1024 }); 1025 assertEquals( 1026 "Sandbox activity intent's package must be set to the sandbox package", 1027 exception.getMessage()); 1028 } 1029 1030 @Test testEnforceAllowedToHostSandboxedActivityFailForIntentsTargetingOtherPackages()1031 public void testEnforceAllowedToHostSandboxedActivityFailForIntentsTargetingOtherPackages() { 1032 Intent intent = 1033 new Intent() 1034 .setAction(ACTION_START_SANDBOXED_ACTIVITY) 1035 .setPackage("com.random.package"); 1036 SecurityException exception = 1037 assertThrows( 1038 SecurityException.class, 1039 () -> { 1040 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1041 intent, mClientAppUid, TEST_PACKAGE); 1042 }); 1043 assertEquals( 1044 "Sandbox activity intent's package must be set to the sandbox package", 1045 exception.getMessage()); 1046 } 1047 1048 @Test testEnforceAllowedToHostSandboxedActivityFailForIntentsWithWrongComponent()1049 public void testEnforceAllowedToHostSandboxedActivityFailForIntentsWithWrongComponent() 1050 throws Exception { 1051 loadSdk(SDK_NAME); 1052 1053 Intent intent = 1054 new Intent() 1055 .setAction(ACTION_START_SANDBOXED_ACTIVITY) 1056 .setPackage(getSandboxPackageName()) 1057 .setComponent(new ComponentName("random", "")); 1058 SecurityException exception = 1059 assertThrows( 1060 SecurityException.class, 1061 () -> { 1062 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1063 intent, mClientAppUid, TEST_PACKAGE); 1064 }); 1065 assertEquals( 1066 "Sandbox activity intent's component must refer to the sandbox package", 1067 exception.getMessage()); 1068 } 1069 1070 @Test testEnforceAllowedToHostSandboxedActivityFailIfNoSandboxProcees()1071 public void testEnforceAllowedToHostSandboxedActivityFailIfNoSandboxProcees() { 1072 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1073 intent.setPackage(getSandboxPackageName()); 1074 1075 SecurityException exception = 1076 assertThrows( 1077 SecurityException.class, 1078 () -> { 1079 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1080 intent, mClientAppUid, TEST_PACKAGE); 1081 }); 1082 assertEquals( 1083 "There is no sandbox process running for the caller uid: " + mClientAppUid + ".", 1084 exception.getMessage()); 1085 } 1086 1087 @Test testEnforceAllowedToHostSandboxedActivityFailIfIntentHasNoExtras()1088 public void testEnforceAllowedToHostSandboxedActivityFailIfIntentHasNoExtras() 1089 throws RemoteException { 1090 loadSdk(SDK_NAME); 1091 1092 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1093 intent.setPackage(getSandboxPackageName()); 1094 1095 IllegalArgumentException exception = 1096 assertThrows( 1097 IllegalArgumentException.class, 1098 () -> { 1099 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1100 intent, mClientAppUid, TEST_PACKAGE); 1101 }); 1102 assertEquals( 1103 "Intent should contain an extra params with key = " 1104 + mService.getSandboxedActivityHandlerKey() 1105 + " and value is an IBinder that identifies a registered " 1106 + "SandboxedActivityHandler.", 1107 exception.getMessage()); 1108 } 1109 1110 @Test testEnforceAllowedToHostSandboxedActivityFailIfIntentHasNoHandlerExtra()1111 public void testEnforceAllowedToHostSandboxedActivityFailIfIntentHasNoHandlerExtra() 1112 throws RemoteException { 1113 loadSdk(SDK_NAME); 1114 1115 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1116 intent.setPackage(getSandboxPackageName()); 1117 intent.putExtras(new Bundle()); 1118 1119 IllegalArgumentException exception = 1120 assertThrows( 1121 IllegalArgumentException.class, 1122 () -> { 1123 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1124 intent, mClientAppUid, TEST_PACKAGE); 1125 }); 1126 assertEquals( 1127 "Intent should contain an extra params with key = " 1128 + mService.getSandboxedActivityHandlerKey() 1129 + " and value is an IBinder that identifies a registered " 1130 + "SandboxedActivityHandler.", 1131 exception.getMessage()); 1132 } 1133 1134 @Test testEnforceAllowedToHostSandboxedActivityFailIfIntentHasWrongTypeOfHandlerExtra()1135 public void testEnforceAllowedToHostSandboxedActivityFailIfIntentHasWrongTypeOfHandlerExtra() 1136 throws RemoteException { 1137 loadSdk(SDK_NAME); 1138 1139 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1140 intent.setPackage(getSandboxPackageName()); 1141 Bundle params = new Bundle(); 1142 params.putString(mService.getSandboxedActivityHandlerKey(), ""); 1143 intent.putExtras(params); 1144 1145 IllegalArgumentException exception = 1146 assertThrows( 1147 IllegalArgumentException.class, 1148 () -> { 1149 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1150 intent, mClientAppUid, TEST_PACKAGE); 1151 }); 1152 assertEquals( 1153 "Intent should contain an extra params with key = " 1154 + mService.getSandboxedActivityHandlerKey() 1155 + " and value is an IBinder that identifies a registered " 1156 + "SandboxedActivityHandler.", 1157 exception.getMessage()); 1158 } 1159 1160 @Test testEnforceAllowedToHostSandboxedActivitySuccessWithoutComponent()1161 public void testEnforceAllowedToHostSandboxedActivitySuccessWithoutComponent() 1162 throws Exception { 1163 loadSdk(SDK_NAME); 1164 1165 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1166 intent.setPackage(getSandboxPackageName()); 1167 Bundle params = new Bundle(); 1168 params.putBinder(mService.getSandboxedActivityHandlerKey(), new Binder()); 1169 intent.putExtras(params); 1170 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1171 intent, mClientAppUid, TEST_PACKAGE); 1172 } 1173 1174 @Test testEnforceAllowedToHostSandboxedActivitySuccessWithComponentReferToSandboxPackage()1175 public void testEnforceAllowedToHostSandboxedActivitySuccessWithComponentReferToSandboxPackage() 1176 throws Exception { 1177 loadSdk(SDK_NAME); 1178 1179 Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); 1180 intent.setPackage(getSandboxPackageName()); 1181 intent.setComponent(new ComponentName(getSandboxPackageName(), "")); 1182 Bundle params = new Bundle(); 1183 params.putBinder(mService.getSandboxedActivityHandlerKey(), new Binder()); 1184 intent.putExtras(params); 1185 sSdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( 1186 intent, mClientAppUid, TEST_PACKAGE); 1187 } 1188 1189 @Test testGetSdkSandboxProcessNameForInstrumentation()1190 public void testGetSdkSandboxProcessNameForInstrumentation() throws Exception { 1191 final PackageManager pm = 1192 InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); 1193 final ApplicationInfo info = pm.getApplicationInfo(TEST_PACKAGE, 0); 1194 final String processName = 1195 sSdkSandboxManagerLocal.getSdkSandboxProcessNameForInstrumentation(info); 1196 assertThat(processName).isEqualTo(TEST_PACKAGE + SANDBOX_INSTR_PROCESS_NAME_SUFFIX); 1197 } 1198 1199 @Test test_getSdkInstrumentationInfo()1200 public void test_getSdkInstrumentationInfo() throws Exception { 1201 final PackageManager pm = 1202 InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); 1203 ApplicationInfo clientAppInfo = pm.getApplicationInfo(TEST_PACKAGE, 0); 1204 1205 ApplicationInfo sdkSandboxInfo = 1206 sSdkSandboxManagerLocal.getSdkSandboxApplicationInfoForInstrumentation( 1207 clientAppInfo, /* isSdkInSandbox= */ false); 1208 1209 assertThat(sdkSandboxInfo.processName) 1210 .isEqualTo(TEST_PACKAGE + SANDBOX_INSTR_PROCESS_NAME_SUFFIX); 1211 assertThat(sdkSandboxInfo.packageName).isEqualTo(pm.getSdkSandboxPackageName()); 1212 assertThat(sdkSandboxInfo.sourceDir).startsWith("/apex/com.android.adservices"); 1213 } 1214 1215 @Test test_getSdkInstrumentationInfo_sdkInSandbox()1216 public void test_getSdkInstrumentationInfo_sdkInSandbox() throws Exception { 1217 final PackageManager pm = 1218 InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); 1219 ApplicationInfo clientAppInfo = pm.getApplicationInfo(TEST_PACKAGE, 0); 1220 1221 ApplicationInfo sdkSandboxInfo = 1222 sSdkSandboxManagerLocal.getSdkSandboxApplicationInfoForInstrumentation( 1223 clientAppInfo, /* isSdkInSandbox= */ true); 1224 1225 assertThat(sdkSandboxInfo.processName) 1226 .isEqualTo(TEST_PACKAGE + SANDBOX_INSTR_PROCESS_NAME_SUFFIX); 1227 assertThat(sdkSandboxInfo.packageName).isEqualTo(pm.getSdkSandboxPackageName()); 1228 assertThat(sdkSandboxInfo.sourceDir).startsWith("/data/app"); 1229 } 1230 1231 @Test testNotifyInstrumentationStarted_killsSandboxProcess()1232 public void testNotifyInstrumentationStarted_killsSandboxProcess() throws Exception { 1233 disableKillUid(); 1234 1235 // First load SDK. 1236 loadSdk(SDK_NAME); 1237 1238 // Check that sdk sandbox for TEST_PACKAGE is bound 1239 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNotNull(); 1240 1241 sSdkSandboxManagerLocal.notifyInstrumentationStarted(TEST_PACKAGE, mClientAppUid); 1242 1243 // Verify that sdk sandbox was killed 1244 Mockito.verify(mAmSpy) 1245 .killUid(Mockito.eq(Process.toSdkSandboxUid(mClientAppUid)), Mockito.anyString()); 1246 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNull(); 1247 } 1248 1249 @Test testNotifyInstrumentationStarted_doesNotAllowLoadSdk()1250 public void testNotifyInstrumentationStarted_doesNotAllowLoadSdk() throws Exception { 1251 disableKillUid(); 1252 1253 // First load SDK. 1254 loadSdk(SDK_NAME); 1255 1256 final CallingInfo callingInfo = new CallingInfo(mClientAppUid, TEST_PACKAGE); 1257 1258 // Check that sdk sandbox for TEST_PACKAGE is bound 1259 assertThat(sProvider.getSdkSandboxServiceForApp(callingInfo)).isNotNull(); 1260 1261 sSdkSandboxManagerLocal.notifyInstrumentationStarted(TEST_PACKAGE, mClientAppUid); 1262 assertThat(sProvider.getSdkSandboxServiceForApp(callingInfo)).isNull(); 1263 1264 // Try load again, it should throw SecurityException 1265 FakeLoadSdkCallbackBinder callback2 = new FakeLoadSdkCallbackBinder(); 1266 1267 mService.loadSdk( 1268 TEST_PACKAGE, 1269 callback2.asBinder(), 1270 SDK_NAME, 1271 mSandboxLatencyInfo, 1272 new Bundle(), 1273 callback2); 1274 1275 LoadSdkException thrown = callback2.getLoadSdkException(); 1276 assertEquals(LOAD_SDK_INTERNAL_ERROR, thrown.getLoadSdkErrorCode()); 1277 assertThat(thrown) 1278 .hasMessageThat() 1279 .contains("Currently running instrumentation of this sdk sandbox process"); 1280 } 1281 1282 @Test testNotifyInstrumentationFinished_canLoadSdk()1283 public void testNotifyInstrumentationFinished_canLoadSdk() throws Exception { 1284 disableKillUid(); 1285 disableNetworkPermissionChecks(); 1286 disableForegroundCheck(); 1287 1288 sSdkSandboxManagerLocal.notifyInstrumentationStarted(TEST_PACKAGE, mClientAppUid); 1289 1290 final CallingInfo callingInfo = new CallingInfo(mClientAppUid, TEST_PACKAGE); 1291 assertThat(sProvider.getSdkSandboxServiceForApp(callingInfo)).isNull(); 1292 1293 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 1294 1295 mService.loadSdk( 1296 TEST_PACKAGE, 1297 null, 1298 SDK_NAME, 1299 mSandboxLatencyInfo, 1300 new Bundle(), 1301 callback); 1302 1303 LoadSdkException thrown = callback.getLoadSdkException(); 1304 assertEquals(LOAD_SDK_INTERNAL_ERROR, thrown.getLoadSdkErrorCode()); 1305 assertThat(thrown) 1306 .hasMessageThat() 1307 .contains("Currently running instrumentation of this sdk sandbox process"); 1308 1309 sSdkSandboxManagerLocal.notifyInstrumentationFinished(TEST_PACKAGE, mClientAppUid); 1310 1311 FakeLoadSdkCallbackBinder callback2 = new FakeLoadSdkCallbackBinder(); 1312 // Now loading should work 1313 mService.loadSdk( 1314 TEST_PACKAGE, 1315 callback2.asBinder(), 1316 SDK_NAME, 1317 mSandboxLatencyInfo, 1318 new Bundle(), 1319 callback2); 1320 mSdkSandboxService.sendLoadSdkSuccessful(); 1321 callback2.assertLoadSdkIsSuccessful(); 1322 assertThat(sProvider.getSdkSandboxServiceForApp(callingInfo)).isNotNull(); 1323 } 1324 1325 @Test testGetEffectiveTargetSdkVersion()1326 public void testGetEffectiveTargetSdkVersion() throws Exception { 1327 assertThat( 1328 sSdkSandboxManagerLocal.getEffectiveTargetSdkVersion( 1329 Process.toSdkSandboxUid(mClientAppUid))) 1330 .isEqualTo(34); 1331 } 1332 1333 @Test testGetSandboxedSdks_afterLoadSdkSuccess()1334 public void testGetSandboxedSdks_afterLoadSdkSuccess() throws Exception { 1335 loadSdk(SDK_NAME); 1336 assertThat(mService.getSandboxedSdks(TEST_PACKAGE, mSandboxLatencyInfo)).hasSize(1); 1337 assertThat( 1338 mService.getSandboxedSdks(TEST_PACKAGE, mSandboxLatencyInfo) 1339 .get(0) 1340 .getSharedLibraryInfo() 1341 .getName()) 1342 .isEqualTo(SDK_NAME); 1343 } 1344 1345 @Test testGetSandboxedSdks_errorLoadingSdk()1346 public void testGetSandboxedSdks_errorLoadingSdk() throws Exception { 1347 disableNetworkPermissionChecks(); 1348 disableForegroundCheck(); 1349 1350 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 1351 1352 mService.loadSdk(TEST_PACKAGE, null, SDK_NAME, mSandboxLatencyInfo, new Bundle(), callback); 1353 mSdkSandboxService.sendLoadSdkError(); 1354 1355 // Verify sdkInfo is missing when loading failed 1356 callback.assertLoadSdkIsUnsuccessful(); 1357 assertThat(callback.getLoadSdkErrorCode()).isEqualTo(LOAD_SDK_INTERNAL_ERROR); 1358 assertThat(mService.getSandboxedSdks(TEST_PACKAGE, mSandboxLatencyInfo)).isEmpty(); 1359 } 1360 1361 @Test testAdServicesPackageIsResolved()1362 public void testAdServicesPackageIsResolved() throws Exception { 1363 assertThat(mInjector.getAdServicesPackageName()).contains("adservices"); 1364 } 1365 1366 @Test testUnloadSdkThatIsNotLoaded()1367 public void testUnloadSdkThatIsNotLoaded() throws Exception { 1368 // Load SDK to bring up a sandbox 1369 loadSdk(SDK_NAME); 1370 // Trying to unload an SDK that is not loaded should do nothing - it's a no-op. 1371 mService.unloadSdk(TEST_PACKAGE, SDK_PROVIDER_PACKAGE, mSandboxLatencyInfo); 1372 } 1373 1374 @Test testUnloadSdkThatIsLoaded()1375 public void testUnloadSdkThatIsLoaded() throws Exception { 1376 disableKillUid(); 1377 loadSdk(SDK_NAME); 1378 1379 loadSdk(SDK_PROVIDER_RESOURCES_SDK_NAME); 1380 mService.unloadSdk(TEST_PACKAGE, SDK_NAME, mSandboxLatencyInfo); 1381 1382 // One SDK should still be loaded, therefore the sandbox should still be alive. 1383 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNotNull(); 1384 1385 mService.unloadSdk(TEST_PACKAGE, SDK_PROVIDER_RESOURCES_SDK_NAME, mSandboxLatencyInfo); 1386 1387 // No more SDKs should be loaded at this point. Verify that the sandbox has been killed. 1388 if (!SdkLevel.isAtLeastU()) { 1389 // For T, killUid() is used to kill the sandbox. 1390 Mockito.verify(mAmSpy) 1391 .killUid( 1392 Mockito.eq(Process.toSdkSandboxUid(mClientAppUid)), 1393 Mockito.anyString()); 1394 } 1395 assertThat(sProvider.getSdkSandboxServiceForApp(mCallingInfo)).isNull(); 1396 } 1397 1398 @Test testUnloadSdkThatIsBeingLoaded()1399 public void testUnloadSdkThatIsBeingLoaded() throws Exception { 1400 // Ask to load SDK, but don't finish loading it 1401 disableKillUid(); 1402 disableNetworkPermissionChecks(); 1403 disableForegroundCheck(); 1404 1405 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 1406 mService.loadSdk( 1407 TEST_PACKAGE, 1408 null, 1409 SDK_NAME, 1410 mSandboxLatencyInfo, 1411 new Bundle(), 1412 callback); 1413 1414 // Trying to unload an SDK that is being loaded should fail 1415 assertThrows( 1416 IllegalArgumentException.class, 1417 () -> mService.unloadSdk(TEST_PACKAGE, SDK_NAME, mSandboxLatencyInfo)); 1418 1419 // After loading the SDK, unloading should not fail 1420 mSdkSandboxService.sendLoadSdkSuccessful(); 1421 callback.assertLoadSdkIsSuccessful(); 1422 mService.unloadSdk(TEST_PACKAGE, SDK_NAME, mSandboxLatencyInfo); 1423 } 1424 1425 @Test testUnloadSdkAfterKillingSandboxDoesNotThrowException()1426 public void testUnloadSdkAfterKillingSandboxDoesNotThrowException() throws Exception { 1427 loadSdk(SDK_NAME); 1428 killSandbox(); 1429 1430 // Unloading SDK should be a no-op 1431 mService.unloadSdk(TEST_PACKAGE, SDK_NAME, mSandboxLatencyInfo); 1432 } 1433 1434 @Test test_syncDataFromClient_verifiesCallingPackageName()1435 public void test_syncDataFromClient_verifiesCallingPackageName() { 1436 FakeSharedPreferencesSyncCallback callback = new FakeSharedPreferencesSyncCallback(); 1437 mService.syncDataFromClient("does.not.exist", mSandboxLatencyInfo, TEST_UPDATE, callback); 1438 1439 assertEquals(PREFERENCES_SYNC_INTERNAL_ERROR, callback.getErrorCode()); 1440 assertThat(callback.getErrorMsg()).contains("does.not.exist"); 1441 } 1442 1443 @Test test_syncDataFromClient_sandboxServiceIsNotBound()1444 public void test_syncDataFromClient_sandboxServiceIsNotBound() { 1445 // Sync data from client 1446 final FakeSharedPreferencesSyncCallback callback = new FakeSharedPreferencesSyncCallback(); 1447 mService.syncDataFromClient(TEST_PACKAGE, mSandboxLatencyInfo, TEST_UPDATE, callback); 1448 1449 // Verify when sandbox is not bound, manager service does not try to sync 1450 assertThat(mSdkSandboxService.getLastSyncUpdate()).isNull(); 1451 // Verify on error was called 1452 assertThat(callback.hasError()).isTrue(); 1453 assertThat(callback.getErrorCode()) 1454 .isEqualTo(ISharedPreferencesSyncCallback.SANDBOX_NOT_AVAILABLE); 1455 assertThat(callback.getErrorMsg()).contains("Sandbox not available"); 1456 } 1457 1458 @Test test_syncDataFromClient_sandboxServiceIsNotBound_sandboxStartedLater()1459 public void test_syncDataFromClient_sandboxServiceIsNotBound_sandboxStartedLater() 1460 throws Exception { 1461 // Sync data from client 1462 final FakeSharedPreferencesSyncCallback callback = new FakeSharedPreferencesSyncCallback(); 1463 mService.syncDataFromClient(TEST_PACKAGE, mSandboxLatencyInfo, TEST_UPDATE, callback); 1464 1465 // Verify on error was called 1466 assertThat(callback.hasError()).isTrue(); 1467 callback.resetLatch(); 1468 1469 // Now loadSdk so that sandbox is created 1470 loadSdk(SDK_NAME); 1471 1472 // Verify that onSandboxStart was called 1473 assertThat(callback.hasSandboxStarted()).isTrue(); 1474 } 1475 1476 @Test test_syncDataFromClient_sandboxServiceIsAlreadyBound_forwardsToSandbox()1477 public void test_syncDataFromClient_sandboxServiceIsAlreadyBound_forwardsToSandbox() 1478 throws Exception { 1479 // Ensure a sandbox service is already bound for the client 1480 sProvider.bindService(mCallingInfo, Mockito.mock(ServiceConnection.class)); 1481 1482 // Sync data from client 1483 final Bundle data = new Bundle(); 1484 final FakeSharedPreferencesSyncCallback callback = new FakeSharedPreferencesSyncCallback(); 1485 mService.syncDataFromClient(TEST_PACKAGE, mSandboxLatencyInfo, TEST_UPDATE, callback); 1486 1487 // Verify that manager service calls sandbox to sync data 1488 assertThat(mSdkSandboxService.getLastSyncUpdate()).isSameInstanceAs(TEST_UPDATE); 1489 } 1490 1491 @Test testStopSdkSandbox()1492 public void testStopSdkSandbox() throws Exception { 1493 disableKillUid(); 1494 1495 assertThat(mService.isSdkSandboxServiceRunning(TEST_PACKAGE)).isFalse(); 1496 loadSdk(SDK_NAME); 1497 assertThat(mService.isSdkSandboxServiceRunning(TEST_PACKAGE)).isTrue(); 1498 1499 Mockito.doNothing() 1500 .when(mSpyContext) 1501 .enforceCallingPermission( 1502 Mockito.eq("com.android.app.sdksandbox.permission.STOP_SDK_SANDBOX"), 1503 Mockito.anyString()); 1504 mService.stopSdkSandbox(TEST_PACKAGE); 1505 int callingUid = Binder.getCallingUid(); 1506 final CallingInfo callingInfo = new CallingInfo(callingUid, TEST_PACKAGE); 1507 assertThat(sProvider.getSdkSandboxServiceForApp(callingInfo)).isEqualTo(null); 1508 assertThat(mService.isSdkSandboxServiceRunning(TEST_PACKAGE)).isFalse(); 1509 } 1510 1511 @Test(expected = SecurityException.class) testStopSdkSandbox_WithoutPermission()1512 public void testStopSdkSandbox_WithoutPermission() { 1513 mService.stopSdkSandbox(TEST_PACKAGE); 1514 } 1515 1516 @Test testDump_preU_notPublished()1517 public void testDump_preU_notPublished() throws Exception { 1518 requiresAtLeastU(false); 1519 mockGrantedPermission(DUMP); 1520 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ false); 1521 1522 String dump = mockAdServicesDumpAndDump("FakeAdServiceDump"); 1523 1524 assertThat(dump).contains(FAKE_DUMP_OUTPUT); 1525 assertThat(dump).contains("FakeAdServiceDump"); 1526 } 1527 1528 @Test testDump_preU_published()1529 public void testDump_preU_published() throws Exception { 1530 requiresAtLeastU(false); 1531 mockGrantedPermission(DUMP); 1532 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ true); 1533 1534 String dump = dump(); 1535 1536 assertThat(dump).contains(FAKE_DUMP_OUTPUT); 1537 Mockito.verify(mAdServicesManager, Mockito.never()) 1538 .dump(ArgumentMatchers.any(), ArgumentMatchers.any()); 1539 } 1540 1541 @Test testDump_atLeastU_notPublished()1542 public void testDump_atLeastU_notPublished() throws Exception { 1543 requiresAtLeastU(true); 1544 mockGrantedPermission(DUMP); 1545 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ false); 1546 1547 String dump = mockAdServicesDumpAndDump("FakeAdServiceDump"); 1548 1549 assertThat(dump).contains(FAKE_DUMP_OUTPUT); 1550 assertThat(dump).contains("FakeAdServiceDump"); 1551 } 1552 1553 @Test testDump_atLeastU_published()1554 public void testDump_atLeastU_published() throws Exception { 1555 requiresAtLeastU(true); 1556 mockGrantedPermission(DUMP); 1557 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ true); 1558 1559 String dump = dump(); 1560 1561 assertThat(dump).contains(FAKE_DUMP_OUTPUT); 1562 Mockito.verify(mAdServicesManager, Mockito.never()) 1563 .dump(ArgumentMatchers.any(), ArgumentMatchers.any()); 1564 } 1565 1566 @Test testDump_adServices_preU_notPublished()1567 public void testDump_adServices_preU_notPublished() throws Exception { 1568 requiresAtLeastU(false); 1569 mockGrantedPermission(DUMP); 1570 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ false); 1571 1572 String dump = mockAdServicesDumpAndDump("FakeAdServiceDump", "--AdServices"); 1573 1574 assertThat(dump).isEqualTo("AdServices:\n\nFakeAdServiceDump\n\n"); 1575 } 1576 1577 @Test testDump_adServices_preU_published()1578 public void testDump_adServices_preU_published() throws Exception { 1579 requiresAtLeastU(false); 1580 mockGrantedPermission(DUMP); 1581 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ true); 1582 1583 String dump = dump("--AdServices"); 1584 1585 assertThat(dump) 1586 .isEqualTo( 1587 SdkSandboxManagerService 1588 .DUMP_AD_SERVICES_MESSAGE_HANDLED_BY_AD_SERVICES_ITSELF 1589 + "\n"); 1590 Mockito.verify(mAdServicesManager, Mockito.never()) 1591 .dump(ArgumentMatchers.any(), ArgumentMatchers.any()); 1592 } 1593 1594 @Test testDump_adServices_atLeastU_notPublished()1595 public void testDump_adServices_atLeastU_notPublished() throws Exception { 1596 requiresAtLeastU(true); 1597 mockGrantedPermission(DUMP); 1598 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ false); 1599 1600 String dump = mockAdServicesDumpAndDump("FakeAdServiceDump", "--AdServices"); 1601 1602 assertThat(dump).isEqualTo("AdServices:\n\nFakeAdServiceDump\n\n"); 1603 } 1604 1605 @Test testDump_adServices_atLeastU_published()1606 public void testDump_adServices_atLeastU_published() throws Exception { 1607 requiresAtLeastU(true); 1608 mockGrantedPermission(DUMP); 1609 mService.registerAdServicesManagerService(mAdServicesManager, /* published= */ true); 1610 1611 String dump = mockAdServicesDumpAndDump("FakeAdServiceDump", "--AdServices"); 1612 1613 assertThat(dump) 1614 .isEqualTo( 1615 SdkSandboxManagerService 1616 .DUMP_AD_SERVICES_MESSAGE_HANDLED_BY_AD_SERVICES_ITSELF 1617 + "\n"); 1618 } 1619 1620 @Test(expected = SecurityException.class) testDump_WithoutPermission()1621 public void testDump_WithoutPermission() { 1622 mService.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]); 1623 } 1624 1625 @Test testHandleShellCommandExecutesCommand()1626 public void testHandleShellCommandExecutesCommand() throws Exception { 1627 SdkSandboxShellCommand command = Mockito.mock(SdkSandboxShellCommand.class); 1628 Mockito.when( 1629 mInjector.createShellCommand( 1630 mService, mSpyContext, /* supportsAdServicesShellCmd= */ true)) 1631 .thenReturn(command); 1632 final String[] args = new String[] {"start"}; 1633 try (ParcelFileDescriptor pfdIn = ParcelFileDescriptor.dup(FileDescriptor.in); 1634 ParcelFileDescriptor pfdOut = ParcelFileDescriptor.dup(FileDescriptor.out); 1635 ParcelFileDescriptor pfdErr = ParcelFileDescriptor.dup(FileDescriptor.err)) { 1636 1637 mService.handleShellCommand(pfdIn, pfdOut, pfdErr, args); 1638 1639 Mockito.verify(mInjector) 1640 .createShellCommand( 1641 mService, mSpyContext, /* supportsAdServicesShellCmd= */ true); 1642 Mockito.verify(command) 1643 .exec( 1644 mService, 1645 pfdIn.getFileDescriptor(), 1646 pfdOut.getFileDescriptor(), 1647 pfdErr.getFileDescriptor(), 1648 args); 1649 } 1650 } 1651 1652 @Test testIsDisabled()1653 public void testIsDisabled() { 1654 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "false"); 1655 assertThat(mService.isSdkSandboxDisabled()).isFalse(); 1656 } 1657 1658 @Test testSdkSandboxEnabledForEmulator()1659 public void testSdkSandboxEnabledForEmulator() { 1660 // SDK sandbox is enabled for an emulator, even if the killswitch is turned on provided 1661 // AdServices APK is present. 1662 Mockito.when(mInjector.isEmulator()).thenReturn(true); 1663 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "true"); 1664 assertThat(mService.isSdkSandboxDisabled()).isFalse(); 1665 1666 // SDK sandbox is disabled when the killswitch is enabled if the device is not an emulator. 1667 Mockito.when(mInjector.isEmulator()).thenReturn(false); 1668 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "true"); 1669 assertThat(mService.isSdkSandboxDisabled()).isTrue(); 1670 } 1671 1672 @Test testSdkSandboxDisabledForEmulator()1673 public void testSdkSandboxDisabledForEmulator() { 1674 // SDK sandbox is disabled for an emulator, if AdServices APK is not present. 1675 Mockito.doReturn(false).when(mInjector).isAdServiceApkPresent(); 1676 Mockito.when(mInjector.isEmulator()).thenReturn(true); 1677 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "true"); 1678 assertThat(mService.isSdkSandboxDisabled()).isTrue(); 1679 } 1680 1681 @Test testSdkSandboxDisabledForAdServiceApkMissing()1682 public void testSdkSandboxDisabledForAdServiceApkMissing() { 1683 Mockito.doReturn(true).when(mInjector).isAdServiceApkPresent(); 1684 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "false"); 1685 assertThat(mService.isSdkSandboxDisabled()).isFalse(); 1686 1687 Mockito.doReturn(false).when(mInjector).isAdServiceApkPresent(); 1688 assertThat(mService.isSdkSandboxDisabled()).isTrue(); 1689 } 1690 1691 @Test testKillswitchStopsSandbox()1692 public void testKillswitchStopsSandbox() throws Exception { 1693 disableKillUid(); 1694 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "false"); 1695 loadSdk(SDK_NAME); 1696 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "true"); 1697 int callingUid = Binder.getCallingUid(); 1698 final CallingInfo callingInfo = new CallingInfo(callingUid, TEST_PACKAGE); 1699 assertThat(sProvider.getSdkSandboxServiceForApp(callingInfo)).isEqualTo(null); 1700 } 1701 1702 @Test testLoadSdkFailsWhenSandboxDisabled()1703 public void testLoadSdkFailsWhenSandboxDisabled() { 1704 disableNetworkPermissionChecks(); 1705 disableForegroundCheck(); 1706 1707 mDeviceConfigUtil.setDeviceConfigProperty(PROPERTY_DISABLE_SANDBOX, "true"); 1708 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 1709 mService.loadSdk( 1710 TEST_PACKAGE, 1711 null, 1712 SDK_NAME, 1713 mSandboxLatencyInfo, 1714 new Bundle(), 1715 callback); 1716 callback.assertLoadSdkIsUnsuccessful(); 1717 assertThat(callback.getLoadSdkErrorCode()) 1718 .isEqualTo(SdkSandboxManager.LOAD_SDK_SDK_SANDBOX_DISABLED); 1719 assertThat(callback.getLoadSdkErrorMsg()).isEqualTo("SDK sandbox is disabled"); 1720 } 1721 1722 @Test testRemoveAppOwnedSdkSandboxInterfacesOnAppDeath()1723 public void testRemoveAppOwnedSdkSandboxInterfacesOnAppDeath() throws Exception { 1724 IBinder iBinder = Mockito.mock(IBinder.class); 1725 mService.registerAppOwnedSdkSandboxInterface( 1726 TEST_PACKAGE, 1727 new AppOwnedSdkSandboxInterface( 1728 APP_OWNED_SDK_SANDBOX_INTERFACE_NAME, 1729 /*version=*/ 0, 1730 /*interfaceIBinder=*/ iBinder), 1731 mSandboxLatencyInfo); 1732 ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = 1733 ArgumentCaptor.forClass(IBinder.DeathRecipient.class); 1734 1735 Mockito.verify(iBinder).linkToDeath(deathRecipient.capture(), ArgumentMatchers.eq(0)); 1736 1737 // App Died 1738 deathRecipient.getValue().binderDied(); 1739 1740 assertThat(mService.getAppOwnedSdkSandboxInterfaces(TEST_PACKAGE, mSandboxLatencyInfo)) 1741 .hasSize(0); 1742 } 1743 1744 @Test testUnloadSdkNotCalledOnAppDeath()1745 public void testUnloadSdkNotCalledOnAppDeath() throws Exception { 1746 disableKillUid(); 1747 disableForegroundCheck(); 1748 disableNetworkPermissionChecks(); 1749 FakeLoadSdkCallbackBinder callback = Mockito.spy(new FakeLoadSdkCallbackBinder()); 1750 Mockito.doReturn(Mockito.mock(Binder.class)).when(callback).asBinder(); 1751 1752 ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = 1753 ArgumentCaptor.forClass(IBinder.DeathRecipient.class); 1754 1755 mService.loadSdk( 1756 TEST_PACKAGE, 1757 null, 1758 SDK_NAME, 1759 mSandboxLatencyInfo, 1760 new Bundle(), 1761 callback); 1762 mSdkSandboxService.sendLoadSdkSuccessful(); 1763 callback.assertLoadSdkIsSuccessful(); 1764 1765 Mockito.verify(callback.asBinder()) 1766 .linkToDeath(deathRecipient.capture(), ArgumentMatchers.eq(0)); 1767 1768 // App Died 1769 deathRecipient.getValue().binderDied(); 1770 1771 Mockito.verify(mSdkSandboxService, Mockito.never()) 1772 .unloadSdk( 1773 Mockito.anyString(), 1774 Mockito.any(IUnloadSdkInSandboxCallback.class), 1775 Mockito.any(SandboxLatencyInfo.class)); 1776 } 1777 1778 @Test testLoadSdk_computeSdkStorage()1779 public void testLoadSdk_computeSdkStorage() throws Exception { 1780 mSdkSandboxStorageManagerUtility.createSdkStorageForTest( 1781 UserHandle.getUserId(mClientAppUid), 1782 TEST_PACKAGE, 1783 Arrays.asList("sdk1", "sdk2"), 1784 Arrays.asList( 1785 SdkSandboxStorageManager.SubDirectories.SHARED_DIR, 1786 SdkSandboxStorageManager.SubDirectories.SANDBOX_DIR)); 1787 1788 loadSdk(SDK_NAME); 1789 // Assume sdk storage information calculated and sent 1790 mSdkSandboxService.sendStorageInfoToSystemServer(); 1791 1792 final List<SdkSandboxStorageManager.StorageDirInfo> internalStorageDirInfo = 1793 mSdkSandboxStorageManager.getInternalStorageDirInfo(mCallingInfo); 1794 final List<SdkSandboxStorageManager.StorageDirInfo> sdkStorageDirInfo = 1795 mSdkSandboxStorageManager.getSdkStorageDirInfo(mCallingInfo); 1796 1797 Mockito.verify(sSdkSandboxPulledAtoms, Mockito.timeout(5000)) 1798 .logStorage(mClientAppUid, /*sharedStorage=*/ 0, /*sdkStorage=*/ 0); 1799 1800 Mockito.verify(mSdkSandboxService, Mockito.times(1)) 1801 .computeSdkStorage( 1802 Mockito.eq(mService.getListOfStoragePaths(internalStorageDirInfo)), 1803 Mockito.eq(mService.getListOfStoragePaths(sdkStorageDirInfo)), 1804 Mockito.any(IComputeSdkStorageCallback.class)); 1805 } 1806 1807 @Test testLoadSdk_CustomizedApplicationInfoIsPopulatedProperly()1808 public void testLoadSdk_CustomizedApplicationInfoIsPopulatedProperly() throws Exception { 1809 final int userId = UserHandle.getUserId(mClientAppUid); 1810 1811 // Create fake storage directories 1812 mSdkSandboxStorageManagerUtility.createSdkStorageForTest( 1813 userId, TEST_PACKAGE, Arrays.asList(SDK_NAME), Collections.emptyList()); 1814 StorageDirInfo storageInfo = 1815 mSdkSandboxStorageManagerUtility 1816 .getSdkStorageDirInfoForTest( 1817 null, userId, TEST_PACKAGE, Arrays.asList(SDK_NAME)) 1818 .get(0); 1819 1820 // Load SDK so that information is passed to sandbox service 1821 loadSdk(SDK_NAME); 1822 1823 // Verify customized application info is overloaded with per-sdk storage paths 1824 ApplicationInfo ai = mSdkSandboxService.getCustomizedInfo(); 1825 assertThat(ai.dataDir).isEqualTo(storageInfo.getCeDataDir()); 1826 assertThat(ai.credentialProtectedDataDir).isEqualTo(storageInfo.getCeDataDir()); 1827 assertThat(ai.deviceProtectedDataDir).isEqualTo(storageInfo.getDeDataDir()); 1828 } 1829 1830 @Test testRegisterActivityInterceptorCallbackOnServiceStart()1831 public void testRegisterActivityInterceptorCallbackOnServiceStart() 1832 throws PackageManager.NameNotFoundException { 1833 assumeTrue(SdkLevel.isAtLeastU()); 1834 1835 // Build ActivityInterceptorInfo 1836 int callingUid = 1000; 1837 Intent intent = new Intent(); 1838 intent.setAction(SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY); 1839 intent.setPackage(getSandboxPackageName()); 1840 ActivityInfo activityInfo = new ActivityInfo(); 1841 1842 ActivityInterceptorCallback.ActivityInterceptResult result = 1843 interceptActivityLunch(intent, callingUid, activityInfo); 1844 1845 assertThat(result.getIntent()).isEqualTo(intent); 1846 assertThat(result.getActivityOptions()).isNull(); 1847 assertThat(result.isActivityResolved()).isTrue(); 1848 assertThat(activityInfo.processName) 1849 .isEqualTo( 1850 mInjector 1851 .getSdkSandboxServiceProvider() 1852 .toSandboxProcessName( 1853 new CallingInfo(mClientAppUid, TEST_PACKAGE))); 1854 assertThat(activityInfo.applicationInfo.uid).isEqualTo(Process.toSdkSandboxUid(callingUid)); 1855 } 1856 1857 @Test testRegisterActivityInterceptionWithRightComponentSuccess()1858 public void testRegisterActivityInterceptionWithRightComponentSuccess() 1859 throws PackageManager.NameNotFoundException { 1860 assumeTrue(SdkLevel.isAtLeastU()); 1861 1862 // Build ActivityInterceptorInfo 1863 int callingUid = 1000; 1864 Intent intent = new Intent(); 1865 intent.setAction(SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY); 1866 intent.setPackage(getSandboxPackageName()); 1867 intent.setComponent(new ComponentName(getSandboxPackageName(), "")); 1868 ActivityInfo activityInfo = new ActivityInfo(); 1869 1870 ActivityInterceptorCallback.ActivityInterceptResult result = 1871 interceptActivityLunch(intent, callingUid, activityInfo); 1872 1873 assertThat(result.getIntent()).isEqualTo(intent); 1874 assertThat(result.getActivityOptions()).isNull(); 1875 assertThat(result.isActivityResolved()).isTrue(); 1876 assertThat(activityInfo.processName) 1877 .isEqualTo( 1878 mInjector 1879 .getSdkSandboxServiceProvider() 1880 .toSandboxProcessName(mCallingInfo)); 1881 assertThat(activityInfo.applicationInfo.uid).isEqualTo(Process.toSdkSandboxUid(callingUid)); 1882 } 1883 1884 @Test testRegisterActivityInterceptionNotProceedForNullIntent()1885 public void testRegisterActivityInterceptionNotProceedForNullIntent() { 1886 assumeTrue(SdkLevel.isAtLeastU()); 1887 1888 ActivityInterceptorCallback.ActivityInterceptResult result = interceptActivityLunch(null); 1889 1890 assertThat(result).isNull(); 1891 } 1892 1893 @Test testRegisterActivityInterceptionNotProceedForNullPackage()1894 public void testRegisterActivityInterceptionNotProceedForNullPackage() { 1895 assumeTrue(SdkLevel.isAtLeastU()); 1896 1897 Intent intent = new Intent(); 1898 1899 ActivityInterceptorCallback.ActivityInterceptResult result = interceptActivityLunch(intent); 1900 1901 assertThat(result).isNull(); 1902 } 1903 1904 @Test testRegisterActivityInterceptionNotProceedForWrongPackage()1905 public void testRegisterActivityInterceptionNotProceedForWrongPackage() { 1906 assumeTrue(SdkLevel.isAtLeastU()); 1907 1908 Intent intent = new Intent(); 1909 intent.setPackage("com.random.package"); 1910 1911 ActivityInterceptorCallback.ActivityInterceptResult result = interceptActivityLunch(intent); 1912 1913 assertThat(result).isNull(); 1914 } 1915 1916 @Test testRegisterActivityInterceptionCallbackReturnNullForNullAction()1917 public void testRegisterActivityInterceptionCallbackReturnNullForNullAction() { 1918 assumeTrue(SdkLevel.isAtLeastU()); 1919 1920 Intent intent = new Intent(); 1921 intent.setPackage("com.random.package"); 1922 1923 ActivityInterceptorCallback.ActivityInterceptResult result = interceptActivityLunch(intent); 1924 1925 assertThat(result).isNull(); 1926 } 1927 1928 @Test testRegisterActivityInterceptionCallbackReturnNullForWrongAction()1929 public void testRegisterActivityInterceptionCallbackReturnNullForWrongAction() { 1930 assumeTrue(SdkLevel.isAtLeastU()); 1931 1932 Intent intent = new Intent(); 1933 intent.setPackage("com.random.package"); 1934 intent.setAction(Intent.ACTION_VIEW); 1935 1936 ActivityInterceptorCallback.ActivityInterceptResult result = interceptActivityLunch(intent); 1937 1938 assertThat(result).isNull(); 1939 } 1940 1941 @Test testRegisterActivityInterceptionCallbackReturnNullForWrongComponent()1942 public void testRegisterActivityInterceptionCallbackReturnNullForWrongComponent() { 1943 assumeTrue(SdkLevel.isAtLeastU()); 1944 1945 Intent intent = new Intent(); 1946 intent.setAction(SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY); 1947 intent.setPackage(getSandboxPackageName()); 1948 intent.setComponent(new ComponentName("random", "")); 1949 1950 ActivityInterceptorCallback.ActivityInterceptResult result = interceptActivityLunch(intent); 1951 1952 assertThat(result).isNull(); 1953 } 1954 1955 @Test testRegisterActivityInterceptorCallbackForInstrumentationActivities()1956 public void testRegisterActivityInterceptorCallbackForInstrumentationActivities() { 1957 assumeTrue(SdkLevel.isAtLeastV()); 1958 disableKillUid(); 1959 ExtendedMockito.when(Process.isSdkSandboxUid(Mockito.anyInt())).thenReturn(true); 1960 sSdkSandboxManagerLocal.notifyInstrumentationStarted(TEST_PACKAGE, mClientAppUid); 1961 1962 Intent intent = new Intent().setAction(Intent.ACTION_VIEW); 1963 ActivityInfo activityInfo = new ActivityInfo(); 1964 activityInfo.processName = TEST_PACKAGE; 1965 activityInfo.applicationInfo = new ApplicationInfo(); 1966 activityInfo.applicationInfo.packageName = TEST_PACKAGE; 1967 activityInfo.applicationInfo.uid = mClientAppUid; 1968 1969 InstrumentationRegistry.getInstrumentation() 1970 .getUiAutomation() 1971 .adoptShellPermissionIdentity( 1972 // Required to intercept activities during CTS-in-sandbox tests. 1973 android.Manifest.permission.START_ACTIVITIES_FROM_SDK_SANDBOX, 1974 // Required for test tearDown. 1975 Manifest.permission.READ_DEVICE_CONFIG, 1976 Manifest.permission.WRITE_DEVICE_CONFIG); 1977 ActivityInterceptorCallback.ActivityInterceptResult result = 1978 mInterceptorCallbackArgumentCaptor 1979 .getValue() 1980 .onInterceptActivityLaunch( 1981 new ActivityInterceptorCallback.ActivityInterceptorInfo.Builder( 1982 mClientAppUid, 1983 Process.myPid(), 1984 /* realCallingUid= */ 0, 1985 /* realCallingPid= */ 0, 1986 /* userId= */ 0, 1987 intent, 1988 /* rInfo= */ null, 1989 activityInfo) 1990 .setCallingPackage(TEST_PACKAGE) 1991 .build()); 1992 1993 assertThat(result.getIntent()).isEqualTo(intent); 1994 assertThat(result.getActivityOptions()).isNull(); 1995 assertThat(result.isActivityResolved()).isTrue(); 1996 assertThat(activityInfo.processName) 1997 .isEqualTo(TEST_PACKAGE + SANDBOX_INSTR_PROCESS_NAME_SUFFIX); 1998 assertThat(activityInfo.applicationInfo.uid).isEqualTo(mClientAppUid); 1999 } 2000 interceptActivityLunch( Intent intent)2001 private ActivityInterceptorCallback.ActivityInterceptResult interceptActivityLunch( 2002 Intent intent) { 2003 return interceptActivityLunch(intent, 1000, new ActivityInfo()); 2004 } 2005 interceptActivityLunch( Intent intent, int callingUid, ActivityInfo activityInfo)2006 private ActivityInterceptorCallback.ActivityInterceptResult interceptActivityLunch( 2007 Intent intent, int callingUid, ActivityInfo activityInfo) { 2008 activityInfo.applicationInfo = new ApplicationInfo(); 2009 ActivityInterceptorCallback.ActivityInterceptorInfo info = 2010 new ActivityInterceptorCallback.ActivityInterceptorInfo.Builder( 2011 callingUid, 0, 0, 0, 0, intent, null, activityInfo) 2012 .setCallingPackage(TEST_PACKAGE) 2013 .build(); 2014 return mInterceptorCallbackArgumentCaptor.getValue().onInterceptActivityLaunch(info); 2015 } 2016 loadSdk(String sdkName)2017 private void loadSdk(String sdkName) throws RemoteException { 2018 disableNetworkPermissionChecks(); 2019 disableForegroundCheck(); 2020 FakeLoadSdkCallbackBinder callback = new FakeLoadSdkCallbackBinder(); 2021 mService.loadSdk(TEST_PACKAGE, null, sdkName, mSandboxLatencyInfo, new Bundle(), callback); 2022 mSdkSandboxService.sendLoadSdkSuccessful(); 2023 callback.assertLoadSdkIsSuccessful(); 2024 } 2025 killSandbox()2026 private void killSandbox() throws Exception { 2027 ArgumentCaptor<IBinder.DeathRecipient> deathRecipientCaptor = 2028 ArgumentCaptor.forClass(IBinder.DeathRecipient.class); 2029 Mockito.verify(mSdkSandboxService.asBinder(), Mockito.atLeastOnce()) 2030 .linkToDeath(deathRecipientCaptor.capture(), ArgumentMatchers.eq(0)); 2031 List<IBinder.DeathRecipient> deathRecipients = deathRecipientCaptor.getAllValues(); 2032 for (IBinder.DeathRecipient deathRecipient : deathRecipients) { 2033 deathRecipient.binderDied(); 2034 } 2035 } 2036 2037 // Restart sandbox which creates a new sandbox service binder. restartAndSetSandboxService()2038 private void restartAndSetSandboxService() throws Exception { 2039 mSdkSandboxService = sProvider.restartSandbox(); 2040 } 2041 getSandboxPackageName()2042 private String getSandboxPackageName() { 2043 return mSpyContext.getPackageManager().getSdkSandboxPackageName(); 2044 } 2045 mockGrantedPermission(String permission)2046 private void mockGrantedPermission(String permission) { 2047 Log.d(TAG, "mockGrantedPermission(" + permission + ")"); 2048 Mockito.doNothing() 2049 .when(mSpyContext) 2050 .enforceCallingPermission(Mockito.eq(permission), Mockito.anyString()); 2051 } 2052 requiresAtLeastU(boolean required)2053 private void requiresAtLeastU(boolean required) { 2054 Log.d( 2055 TAG, 2056 "requireAtLeastU(" 2057 + required 2058 + "): SdkLevel.isAtLeastU()=" 2059 + SdkLevel.isAtLeastU()); 2060 // TODO(b/280677793): rather than assuming it's the given version, mock it: 2061 // ExtendedMockito.doReturn(required).when(() -> SdkLevel.isAtLeastU()); 2062 if (required) { 2063 assumeTrue("Device must be at least U", SdkLevel.isAtLeastU()); 2064 } else { 2065 assumeFalse("Device must be less than U", SdkLevel.isAtLeastU()); 2066 } 2067 } 2068 dump(String... args)2069 private String dump(String... args) throws Exception { 2070 Log.d(TAG, "dump(): args=" + Arrays.toString(args)); 2071 return DumpHelper.dump(pw -> mService.dump(new FileDescriptor(), pw, args)); 2072 } 2073 mockAdServicesDumpAndDump(String adServicesDump, String... args)2074 private String mockAdServicesDumpAndDump(String adServicesDump, String... args) 2075 throws Exception { 2076 Log.d( 2077 TAG, 2078 "mockAdServicesDumpAndDump(): adServicesDump=" 2079 + adServicesDump 2080 + ", args=" 2081 + Arrays.toString(args)); 2082 return DumpHelper.dump( 2083 pw -> { 2084 Mockito.doAnswer( 2085 inv -> { 2086 Log.d(TAG, inv.toString()); 2087 pw.println(adServicesDump); 2088 return null; 2089 }) 2090 .when(mAdServicesManager) 2091 .dump(any(), eq(args)); 2092 2093 mService.dump(new FileDescriptor(), pw, args); 2094 }); 2095 } 2096 2097 private static Bundle getTestBundle() { 2098 final Bundle data = new Bundle(); 2099 data.putString(TEST_KEY, TEST_VALUE); 2100 return data; 2101 } 2102 } 2103