Test SDK sandbox creation per user
Check that a unique sandbox is created for each user calling loadSdk()
from the same app.
Bug: 221024799
Test: atest SdkSandboxLifecycleHostTest#testSandboxIsCreatedPerUser
Change-Id: I373fca36eb9656b08e5093bc1b2a4f8619ce9492
diff --git a/sdksandbox/tests/hostsidetests/Android.bp b/sdksandbox/tests/hostsidetests/Android.bp
index 0d7e9bc..7f5a443 100644
--- a/sdksandbox/tests/hostsidetests/Android.bp
+++ b/sdksandbox/tests/hostsidetests/Android.bp
@@ -28,6 +28,7 @@
static_libs: [
"cts-install-lib-host",
"modules-utils-build-testing",
+ "SdkSandboxHostTestUtils",
],
data: [
":TestCodeProvider",
diff --git a/sdksandbox/tests/hostsidetests/src/com/android/tests/sdksandbox/host/SdkSandboxLifecycleHostTest.java b/sdksandbox/tests/hostsidetests/src/com/android/tests/sdksandbox/host/SdkSandboxLifecycleHostTest.java
index 1eecd5d..03404ba 100644
--- a/sdksandbox/tests/hostsidetests/src/com/android/tests/sdksandbox/host/SdkSandboxLifecycleHostTest.java
+++ b/sdksandbox/tests/hostsidetests/src/com/android/tests/sdksandbox/host/SdkSandboxLifecycleHostTest.java
@@ -20,6 +20,8 @@
import static org.junit.Assume.assumeTrue;
+import android.app.sdksandbox.hosttestutils.SecondaryUserUtils;
+
import com.android.modules.utils.build.testing.DeviceSdkLevel;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -34,6 +36,7 @@
public final class SdkSandboxLifecycleHostTest extends BaseHostJUnit4Test {
private static final String APP_PACKAGE = "com.android.sdksandbox.app";
+ private static final String APP_APK = "SdkSandboxTestApp.apk";
private static final String APP_2_PACKAGE = "com.android.sdksandbox.app2";
private static final String APP_SHARED_PACKAGE = "com.android.sdksandbox.shared.app1";
@@ -60,18 +63,11 @@
private static final String SANDBOX_SHARED_2_PROCESS_NAME =
APP_SHARED_2_PACKAGE + "_sdk_sandbox";
+ private final SecondaryUserUtils mUserUtils = new SecondaryUserUtils(this);
+
private boolean mWasRoot;
private DeviceSdkLevel mDeviceSdkLevel;
- private void startActivity(String pkg, String activity) throws Exception {
- getDevice().executeShellCommand(String.format("am start -W -n %s/.%s", pkg, activity));
- }
-
- private void killApp(String pkg) throws Exception {
- getDevice().executeShellCommand(String.format("am force-stop %s", pkg));
- waitForProcessDeath(pkg + '\n');
- }
-
@Before
public void setUp() throws Exception {
assertThat(getBuild()).isNotNull();
@@ -85,6 +81,7 @@
@After
public void tearDown() throws Exception {
+ mUserUtils.removeSecondaryUserIfNecessary();
cleanUpAppAndSandboxProcesses();
if (!mWasRoot) {
@@ -135,6 +132,40 @@
}
@Test
+ public void testSandboxIsCreatedPerUser() throws Exception {
+ assumeTrue(getDevice().isMultiUserSupported());
+
+ int initialUserId = getDevice().getCurrentUser();
+ int secondaryUserId = mUserUtils.createAndStartSecondaryUser();
+ installPackageAsUser(APP_APK, false, secondaryUserId);
+
+ // Start app for the primary user
+ startActivityAsUser(APP_PACKAGE, APP_ACTIVITY, initialUserId);
+ String processDump = getDevice().executeAdbCommand("shell", "ps", "-A");
+ assertThat(processDump).contains(APP_PACKAGE + '\n');
+ assertThat(processDump).contains(SANDBOX_1_PROCESS_NAME);
+
+ getDevice().switchUser(secondaryUserId);
+
+ // Should still see an app/sdk sandbox running.
+ processDump = getDevice().executeAdbCommand("shell", "ps", "-A");
+ assertThat(processDump).contains(APP_PACKAGE + '\n');
+ assertThat(processDump).contains(SANDBOX_1_PROCESS_NAME);
+
+ // Start the app for the secondary user.
+ startActivityAsUser(APP_PACKAGE, APP_ACTIVITY, secondaryUserId);
+ // There should be two instances of app and sandbox processes - one for each user.
+ assertThat(getProcessOccurrenceCount(APP_PACKAGE + '\n')).isEqualTo(2);
+ assertThat(getProcessOccurrenceCount(SANDBOX_1_PROCESS_NAME)).isEqualTo(2);
+
+ // Kill the app process for the secondary user.
+ killApp(APP_PACKAGE + '\n');
+ // There should be one instance of app and sandbox process after kill
+ assertThat(getProcessOccurrenceCount(APP_PACKAGE + '\n')).isEqualTo(1);
+ assertThat(getProcessOccurrenceCount(SANDBOX_1_PROCESS_NAME)).isEqualTo(1);
+ }
+
+ @Test
public void testAppAndSdkSandboxAreKilledOnLoadedSdkUpdate() throws Exception {
startActivity(APP_PACKAGE, APP_ACTIVITY);
@@ -331,6 +362,34 @@
assertThat(finalSandboxOomScoreAdj).isGreaterThan(initialSandboxOomScoreAdj);
}
+ private void startActivity(String pkg, String activity) throws Exception {
+ getDevice().executeShellCommand(String.format("am start -W -n %s/.%s", pkg, activity));
+ }
+
+ private void startActivityAsUser(String pkg, String activity, int userId) throws Exception {
+ getDevice()
+ .executeShellCommand(
+ String.format("am start -W -n %s/.%s --user %d", pkg, activity, userId));
+ }
+
+ private void killApp(String pkg) throws Exception {
+ getDevice().executeShellCommand(String.format("am force-stop --user current %s", pkg));
+ waitForProcessDeath(pkg + '\n');
+ }
+
+ // Get the number of running processes with the given process name.
+ private int getProcessOccurrenceCount(String processName) throws Exception {
+ String processDump = getDevice().executeAdbCommand("shell", "ps", "-A");
+
+ int count = 0;
+ int processOccurrenceIndex = processDump.indexOf(processName);
+ while (processOccurrenceIndex >= 0) {
+ count++;
+ processOccurrenceIndex = processDump.indexOf(processName, processOccurrenceIndex + 1);
+ }
+ return count;
+ }
+
private void cleanUpAppAndSandboxProcesses() throws Exception {
for (String pkg :
new String[] {