blob: 2bb2941caa3f1e531cf0c8fced1ee6ab7186ff78 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tests.sdksandbox.endtoend;
import static android.app.sdksandbox.SdkSandboxManager.EXTRA_DISPLAY_ID;
import static android.app.sdksandbox.SdkSandboxManager.EXTRA_HEIGHT_IN_PIXELS;
import static android.app.sdksandbox.SdkSandboxManager.EXTRA_HOST_TOKEN;
import static android.app.sdksandbox.SdkSandboxManager.EXTRA_WIDTH_IN_PIXELS;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import android.app.sdksandbox.LoadSdkException;
import android.app.sdksandbox.SandboxedSdk;
import android.app.sdksandbox.SdkSandboxManager;
import android.app.sdksandbox.testutils.FakeLoadSdkCallback;
import android.app.sdksandbox.testutils.FakeRequestSurfacePackageCallback;
import android.app.sdksandbox.testutils.FakeSdkSandboxProcessDeathCallback;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Parcel;
import androidx.lifecycle.Lifecycle;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.platform.app.InstrumentationRegistry;
import com.google.common.truth.Expect;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.List;
/*
* TODO(b/215372846): These providers
* (RequestSurfacePackageSuccessfullySdkProvider, RetryLoadSameSdkShouldFailSdkProvider) could be
* deleted after solving this bug, as then tests can onload and load same SDK multiple times.
*/
@RunWith(JUnit4.class)
public class SdkSandboxManagerTest {
private static final String NON_EXISTENT_SDK = "com.android.not_exist";
@Rule
public final ActivityScenarioRule<TestActivity> mRule =
new ActivityScenarioRule<>(TestActivity.class);
@Rule public final Expect mExpect = Expect.create();
private ActivityScenario<TestActivity> mScenario;
private SdkSandboxManager mSdkSandboxManager;
@Before
public void setup() {
final Context context = InstrumentationRegistry.getInstrumentation().getContext();
mSdkSandboxManager = context.getSystemService(SdkSandboxManager.class);
mScenario = mRule.getScenario();
}
@Test
public void testGetSdkSandboxState() throws Exception {
int state = mSdkSandboxManager.getSdkSandboxState();
assertThat(state).isEqualTo(SdkSandboxManager.SDK_SANDBOX_STATE_ENABLED_PROCESS_ISOLATION);
}
@Test
public void loadSdkSuccessfully() {
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
assertNotNull(callback.getSandboxedSdk());
assertNotNull(callback.getSandboxedSdk().getInterface());
mSdkSandboxManager.unloadSdk(sdkName);
}
@Test
public void getSandboxedSdkSuccessfully() {
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
List<SandboxedSdk> sandboxedSdks = mSdkSandboxManager.getSandboxedSdks();
int nLoadedSdks = sandboxedSdks.size();
assertThat(nLoadedSdks).isGreaterThan(0);
assertThat(
sandboxedSdks.stream()
.filter(s -> s.getSharedLibraryInfo().getName().equals(sdkName))
.count())
.isEqualTo(1);
mSdkSandboxManager.unloadSdk(sdkName);
List<SandboxedSdk> sandboxedSdksAfterUnload = mSdkSandboxManager.getSandboxedSdks();
assertThat(sandboxedSdksAfterUnload.size()).isEqualTo(nLoadedSdks - 1);
}
@Test
public void loadSdkAndCheckClassloader() {
final String sdkName = "com.android.loadSdkAndCheckClassloader";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
assertNotNull(callback.getSandboxedSdk());
assertNotNull(callback.getSandboxedSdk().getInterface());
mSdkSandboxManager.unloadSdk(sdkName);
}
@Test
public void retryLoadSameSdkShouldFail() {
final String sdkName = "com.android.loadSdkSuccessfullySdkProviderTwo";
FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isFalse();
assertThat(callback.getLoadSdkErrorCode())
.isEqualTo(SdkSandboxManager.LOAD_SDK_ALREADY_LOADED);
}
@Test
public void loadNotExistSdkShouldFail() {
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(NON_EXISTENT_SDK, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isFalse();
assertThat(callback.getLoadSdkErrorCode())
.isEqualTo(SdkSandboxManager.LOAD_SDK_NOT_FOUND);
}
@Test
public void loadNotExistSdkShouldFail_checkLoadSdkException() {
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(NON_EXISTENT_SDK, new Bundle(), Runnable::run, callback);
LoadSdkException loadSdkException = callback.getLoadSdkException();
assertThat(loadSdkException.getExtraInformation()).isNotNull();
assertThat(loadSdkException.getExtraInformation().isEmpty()).isTrue();
}
@Test
public void loadSdkWithInternalErrorShouldFail() throws Exception {
final String sdkName = "com.android.loadSdkWithInternalErrorSdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isFalse();
assertThat(callback.getLoadSdkErrorCode())
.isEqualTo(SdkSandboxManager.LOAD_SDK_SDK_DEFINED_ERROR);
}
@Test
public void unloadAndReloadSdk() throws Exception {
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
mSdkSandboxManager.unloadSdk(sdkName);
// Wait till SDK is unloaded.
Thread.sleep(2000);
// Calls to an unloaded SDK should fail.
final FakeRequestSurfacePackageCallback requestSurfacePackageCallback =
new FakeRequestSurfacePackageCallback();
mSdkSandboxManager.requestSurfacePackage(
sdkName,
getRequestSurfacePackageParams(),
Runnable::run,
requestSurfacePackageCallback);
assertThat(requestSurfacePackageCallback.isRequestSurfacePackageSuccessful()).isFalse();
assertThat(requestSurfacePackageCallback.getSurfacePackageErrorCode())
.isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED);
// SDK can be reloaded after being unloaded.
final FakeLoadSdkCallback callback2 = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback2);
assertThat(callback2.isLoadSdkSuccessful()).isTrue();
}
@Test
public void unloadNonexistentSdk() {
final String sdkName1 = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName1, new Bundle(), Runnable::run, callback);
// If the SDK provider has already been loaded from another test, ignore the error.
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
final String sdkName2 = "com.android.nonexistent";
// Unloading does nothing - call should go throw without error.
mSdkSandboxManager.unloadSdk(sdkName2);
}
@Test
public void reloadingSdkDoesNotInvalidateIt() {
final String sdkName = "com.android.requestSurfacePackageSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
// If the SDK provider has already been loaded from another test, ignore the error.
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
SandboxedSdk sandboxedSdk = callback.getSandboxedSdk();
assertNotNull(sandboxedSdk.getInterface());
// Attempt to load the SDK again and see that it fails.
final FakeLoadSdkCallback reloadCallback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, reloadCallback);
assertThat(reloadCallback.isLoadSdkSuccessful()).isFalse();
// SDK's interface should still be obtainable.
assertNotNull(sandboxedSdk.getInterface());
// Further calls to the SDK should still be valid.
final FakeRequestSurfacePackageCallback surfacePackageCallback =
new FakeRequestSurfacePackageCallback();
mSdkSandboxManager.requestSurfacePackage(
sdkName, getRequestSurfacePackageParams(), Runnable::run, surfacePackageCallback);
assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isTrue();
}
@Test
public void testReloadingSdkAfterKillingSandboxIsSuccessful() throws Exception {
// Kill the sandbox if it already exists from previous tests
killSandboxIfExists();
// Killing the sandbox and loading the same SDKs again multiple times should work
for (int i = 0; i < 3; ++i) {
FakeSdkSandboxProcessDeathCallback callback = new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, callback);
// The same SDKs should be able to be loaded again after sandbox death
loadMultipleSdks();
killSandbox();
assertThat(callback.isSdkSandboxDeathDetected()).isTrue();
}
}
@Test
public void testAddSdkSandboxProcessDeathCallback_BeforeStartingSandbox() throws Exception {
// Kill the sandbox if it already exists from previous tests
killSandboxIfExists();
// Add a sandbox lifecycle callback before starting the sandbox
FakeSdkSandboxProcessDeathCallback lifecycleCallback =
new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, lifecycleCallback);
// Bring up the sandbox
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
killSandbox();
assertThat(lifecycleCallback.isSdkSandboxDeathDetected()).isTrue();
}
@Test
public void testAddSdkSandboxProcessDeathCallback_AfterStartingSandbox() throws Exception {
// Bring up the sandbox
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
// Add a sandbox lifecycle callback before starting the sandbox
FakeSdkSandboxProcessDeathCallback lifecycleCallback =
new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, lifecycleCallback);
killSandbox();
assertThat(lifecycleCallback.isSdkSandboxDeathDetected()).isTrue();
}
@Test
public void testRegisterMultipleSdkSandboxProcessDeathCallbacks() throws Exception {
// Kill the sandbox if it already exists from previous tests
killSandboxIfExists();
// Add a sandbox lifecycle callback before starting the sandbox
FakeSdkSandboxProcessDeathCallback lifecycleCallback1 =
new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, lifecycleCallback1);
// Bring up the sandbox
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
// Add another sandbox lifecycle callback after starting it
FakeSdkSandboxProcessDeathCallback lifecycleCallback2 =
new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, lifecycleCallback2);
killSandbox();
assertThat(lifecycleCallback1.isSdkSandboxDeathDetected()).isTrue();
assertThat(lifecycleCallback2.isSdkSandboxDeathDetected()).isTrue();
}
@Test
public void testRemoveSdkSandboxProcessDeathCallback() throws Exception {
// Bring up the sandbox
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
// Add and remove a sandbox lifecycle callback
FakeSdkSandboxProcessDeathCallback lifecycleCallback1 =
new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, lifecycleCallback1);
mSdkSandboxManager.removeSdkSandboxProcessDeathCallback(lifecycleCallback1);
// Add a lifecycle callback but don't remove it
FakeSdkSandboxProcessDeathCallback lifecycleCallback2 =
new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, lifecycleCallback2);
killSandbox();
assertThat(lifecycleCallback1.isSdkSandboxDeathDetected()).isFalse();
assertThat(lifecycleCallback2.isSdkSandboxDeathDetected()).isTrue();
}
@Test
public void requestSurfacePackageSuccessfully() {
final String sdkName = "com.android.requestSurfacePackageSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
// If the SDK provider has already been loaded from another test, ignore the SDK already
// loaded error.
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
final FakeRequestSurfacePackageCallback surfacePackageCallback =
new FakeRequestSurfacePackageCallback();
mSdkSandboxManager.requestSurfacePackage(
sdkName, getRequestSurfacePackageParams(), Runnable::run, surfacePackageCallback);
assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isTrue();
}
@Test
public void requestSurfacePackageWithInternalErrorShouldFail() {
final String sdkName = "com.android.requestSurfacePackageWithInternalErrorSdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
final FakeRequestSurfacePackageCallback surfacePackageCallback =
new FakeRequestSurfacePackageCallback();
mSdkSandboxManager.requestSurfacePackage(
sdkName, getRequestSurfacePackageParams(), Runnable::run, surfacePackageCallback);
assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isFalse();
assertThat(surfacePackageCallback.getSurfacePackageErrorCode())
.isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_INTERNAL_ERROR);
assertThat(surfacePackageCallback.getExtraErrorInformation()).isNotNull();
assertThat(surfacePackageCallback.getExtraErrorInformation().isEmpty()).isTrue();
}
@Test
public void testRequestSurfacePackage_SandboxDiesAfterLoadingSdk() throws Exception {
final String sdkName = "com.android.requestSurfacePackageSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
assertThat(killSandboxIfExists()).isTrue();
final FakeRequestSurfacePackageCallback surfacePackageCallback =
new FakeRequestSurfacePackageCallback();
mSdkSandboxManager.requestSurfacePackage(
sdkName, getRequestSurfacePackageParams(), Runnable::run, surfacePackageCallback);
assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isFalse();
assertThat(surfacePackageCallback.getSurfacePackageErrorCode())
.isEqualTo(SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED);
}
@Test
public void testResourcesAndAssets() {
final String sdkName = "com.android.codeproviderresources";
FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
}
@Test
public void testLoadSdkInBackgroundFails() throws Exception {
mScenario.moveToState(Lifecycle.State.DESTROYED);
// Wait for the activity to be destroyed
Thread.sleep(1000);
final String sdkName = "com.android.loadSdkSuccessfullySdkProvider";
final FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
SecurityException thrown =
assertThrows(
SecurityException.class,
() ->
mSdkSandboxManager.loadSdk(
sdkName, new Bundle(), Runnable::run, callback));
assertThat(thrown).hasMessageThat().contains("does not run in the foreground");
}
@Test
public void testSandboxApisAreUsableAfterUnbindingSandbox() throws Exception {
final String sdkName1 = "com.android.requestSurfacePackageSuccessfullySdkProvider";
FakeLoadSdkCallback callback1 = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName1, new Bundle(), Runnable::run, callback1);
assertThat(callback1.isLoadSdkSuccessful(/*ignoreSdkAlreadyLoadedError=*/ true)).isTrue();
// Move the app to the background and bring it back to the foreground again.
mScenario.recreate();
// Loading another sdk should work without issue
final String sdkName2 = "com.android.loadSdkSuccessfullySdkProvider";
FakeLoadSdkCallback callback2 = new FakeLoadSdkCallback();
mSdkSandboxManager.loadSdk(sdkName2, new Bundle(), Runnable::run, callback2);
assertThat(callback2.isLoadSdkSuccessful()).isTrue();
// Requesting surface package from the first loaded sdk should work.
final FakeRequestSurfacePackageCallback surfacePackageCallback =
new FakeRequestSurfacePackageCallback();
mSdkSandboxManager.requestSurfacePackage(
sdkName1, getRequestSurfacePackageParams(), Runnable::run, surfacePackageCallback);
assertThat(surfacePackageCallback.isRequestSurfacePackageSuccessful()).isTrue();
mSdkSandboxManager.unloadSdk(sdkName1);
mSdkSandboxManager.unloadSdk(sdkName2);
}
/** Checks that {@code SdkSandbox.apk} only requests normal permissions in its manifest. */
// TODO: This should probably be a separate test module
@Test
public void testSdkSandboxPermissions() throws Exception {
final PackageManager pm =
InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
try {
final PackageInfo sdkSandboxPackage =
pm.getPackageInfo(
pm.getSdkSandboxPackageName(),
PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS));
for (int i = 0; i < sdkSandboxPackage.requestedPermissions.length; i++) {
final String permissionName = sdkSandboxPackage.requestedPermissions[i];
final PermissionInfo permissionInfo = pm.getPermissionInfo(permissionName, 0);
mExpect.withMessage(
"SdkSandbox.apk requests non-normal permission " + permissionName)
.that(permissionInfo.getProtection())
.isEqualTo(PermissionInfo.PROTECTION_NORMAL);
}
} catch (PackageManager.NameNotFoundException exception) {
// TODO(b/259936418): Remove once we stop needing non-system permissions.
}
}
// TODO(b/244730098): The test below needs to be moved from e2e.
// It is not and e2e test.
@Test
public void testLoadSdkExceptionWriteToParcel() throws Exception {
final Bundle bundle = new Bundle();
bundle.putChar("testKey", /*testValue=*/ 'C');
final LoadSdkException exception = new LoadSdkException(/*Throwable=*/ null, bundle);
final Parcel parcel = Parcel.obtain();
exception.writeToParcel(parcel, /*flags=*/ 0);
// Create LoadSdkException with the same parcel
parcel.setDataPosition(0); // rewind
final LoadSdkException exceptionCheck = LoadSdkException.CREATOR.createFromParcel(parcel);
assertThat(exceptionCheck.getLoadSdkErrorCode()).isEqualTo(exception.getLoadSdkErrorCode());
assertThat(exceptionCheck.getExtraInformation().getChar("testKey"))
.isEqualTo(exception.getExtraInformation().getChar("testKey"));
assertThat(exceptionCheck.getExtraInformation().keySet()).containsExactly("testKey");
}
// TODO(b/244730098): The test below needs to be moved from e2e.
// It is not and e2e test.
@Test
public void testLoadSdkExceptionDescribeContents() throws Exception {
final LoadSdkException exception = new LoadSdkException(/*Throwable=*/ null, new Bundle());
assertThat(exception.describeContents()).isEqualTo(0);
}
// TODO(b/244730098): The test below needs to be moved from e2e.
// It is not and e2e test.
@Test
public void testSandboxedSdkDescribeContents() throws Exception {
final SandboxedSdk sandboxedSdk = new SandboxedSdk(new Binder());
assertThat(sandboxedSdk.describeContents()).isEqualTo(0);
}
private Bundle getRequestSurfacePackageParams() {
Bundle params = new Bundle();
params.putInt(EXTRA_WIDTH_IN_PIXELS, 500);
params.putInt(EXTRA_HEIGHT_IN_PIXELS, 500);
params.putInt(EXTRA_DISPLAY_ID, 0);
params.putBinder(EXTRA_HOST_TOKEN, new Binder());
return params;
}
private void loadMultipleSdks() {
FakeLoadSdkCallback callback = new FakeLoadSdkCallback();
final String sdk1 = "com.android.loadSdkSuccessfullySdkProvider";
mSdkSandboxManager.loadSdk(sdk1, new Bundle(), Runnable::run, callback);
assertThat(callback.isLoadSdkSuccessful()).isTrue();
FakeLoadSdkCallback callback2 = new FakeLoadSdkCallback();
final String sdk2 = "com.android.loadSdkSuccessfullySdkProviderTwo";
mSdkSandboxManager.loadSdk(sdk2, new Bundle(), Runnable::run, callback2);
assertThat(callback2.isLoadSdkSuccessful()).isTrue();
}
// Returns true if the sandbox was already likely existing, false otherwise.
private boolean killSandboxIfExists() throws Exception {
FakeSdkSandboxProcessDeathCallback callback = new FakeSdkSandboxProcessDeathCallback();
mSdkSandboxManager.addSdkSandboxProcessDeathCallback(Runnable::run, callback);
killSandbox();
return callback.isSdkSandboxDeathDetected();
}
private void killSandbox() throws Exception {
// TODO(b/241542162): Avoid using reflection as a workaround once test apis can be run
// without issue.
mSdkSandboxManager.getClass().getMethod("stopSdkSandbox").invoke(mSdkSandboxManager);
}
}