• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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