Create sdk sandbox data when starting instrumentation
If a client package of the sdk sandbox process we are instrumenting
doesn't depend on any SDKs (i.e. doesn't have <uses-sdk-library> tags),
then we won't create sdk sandbox data directories for the sdk sandbox
process.
This changes fixes it by manually calling reconcileSdkData during
notifyInstrumentationStarted
Bug: 209061624
Test: atest SdkSandboxManagerServiceUnitTests
Test: atest SdkSandboxInprocessTests
Change-Id: Iebeabb96dc218f7c0b67339d5ae31fdc61a3e76c
diff --git a/sdksandbox/SdkSandbox/tests_inprocess/src/com/android/sdksandbox/inprocess/SdkSandboxConfigurationTest.java b/sdksandbox/SdkSandbox/tests_inprocess/src/com/android/sdksandbox/inprocess/SdkSandboxConfigurationTest.java
index 636a8d6..7654aaf 100644
--- a/sdksandbox/SdkSandbox/tests_inprocess/src/com/android/sdksandbox/inprocess/SdkSandboxConfigurationTest.java
+++ b/sdksandbox/SdkSandbox/tests_inprocess/src/com/android/sdksandbox/inprocess/SdkSandboxConfigurationTest.java
@@ -16,6 +16,8 @@
package com.android.sdksandbox.inprocess;
+import static android.content.Context.MODE_PRIVATE;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -31,7 +33,10 @@
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
/**
* Tests to check some basic properties of the Sdk Sandbox processes.
@@ -97,4 +102,41 @@
assertThat(dir.getAbsolutePath()).isEqualTo(
"/data/misc_de/0/sdksandbox/" + TEST_PKG + "/shared");
}
+
+ /**
+ * Tests that sdk sandbox process can write to it's CE storage.
+ */
+ @Test
+ public void testCanWriteToDataDir_CE() throws Exception {
+ final Context ctx = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ try (OutputStreamWriter writer = new OutputStreamWriter(
+ ctx.openFileOutput("random_ce_file", MODE_PRIVATE))) {
+ writer.write("I am an sdk sandbox");
+ }
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(ctx.openFileInput("random_ce_file")))) {
+ String line = reader.readLine();
+ assertThat(line).isEqualTo("I am an sdk sandbox");
+ }
+ }
+
+ /**
+ * Tests that sdk sandbox process can write to it's DE storage.
+ */
+ @Test
+ public void testCanWriteToDataDir_DE() throws Exception {
+ final Context ctx =
+ InstrumentationRegistry.getInstrumentation()
+ .getTargetContext()
+ .createDeviceProtectedStorageContext();
+ try (OutputStreamWriter writer = new OutputStreamWriter(
+ ctx.openFileOutput("random_de_file", MODE_PRIVATE))) {
+ writer.write("I am also an sdk sandbox");
+ }
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(ctx.openFileInput("random_de_file")))) {
+ String line = reader.readLine();
+ assertThat(line).isEqualTo("I am also an sdk sandbox");
+ }
+ }
}
diff --git a/sdksandbox/service/java/com/android/server/sdksandbox/SdkSandboxManagerService.java b/sdksandbox/service/java/com/android/server/sdksandbox/SdkSandboxManagerService.java
index 1682e27..0cb13eb 100644
--- a/sdksandbox/service/java/com/android/server/sdksandbox/SdkSandboxManagerService.java
+++ b/sdksandbox/service/java/com/android/server/sdksandbox/SdkSandboxManagerService.java
@@ -151,7 +151,8 @@
final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
// TODO(b/223386213): We could miss broadcast or app might be started before we
// handle broadcast.
- mHandler.post(() -> reconcileSdkData(packageName, uid));
+ mHandler.post(
+ () -> reconcileSdkData(packageName, uid, /* forInstrumentation= */ false));
}
};
mContext.registerReceiver(packageAddedIntentReceiver, packageAddedIntentFilter,
@@ -209,12 +210,21 @@
return Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
}
- private void reconcileSdkData(String packageName, int uid) {
+ private void reconcileSdkData(String packageName, int uid, boolean forInstrumentation) {
final List<SharedLibraryInfo> sdksUsed = getSdksUsed(packageName);
if (sdksUsed.isEmpty()) {
- return;
+ if (forInstrumentation) {
+ Log.w(TAG,
+ "Running instrumentation for the sdk-sandbox process belonging to client "
+ + "app "
+ + packageName + " (uid = " + uid
+ + "). However client app doesn't depend on any SDKs. Only "
+ + "creating \"shared\" sdk sandbox data sub directory");
+ } else {
+ return;
+ }
}
- final List<String> subDirNames = new ArrayList();
+ final List<String> subDirNames = new ArrayList<>();
subDirNames.add("shared");
for (int i = 0; i < sdksUsed.size(); i++) {
final SharedLibraryInfo sdk = sdksUsed.get(i);
@@ -689,6 +699,9 @@
mActivityManager.killUid(sdkSandboxUid, "instrumentation started");
mRunningInstrumentations.add(clientAppUid);
}
+ // TODO(b/223386213): we need to check if there is reconcileSdkData task already enqueued
+ // because the instrumented client app was just installed.
+ reconcileSdkData(clientAppPackageName, clientAppUid, /* forInstrumentation= */ true);
}
private void notifyInstrumentationFinished(