summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapi/system-current.txt7
-rw-r--r--core/java/android/content/ApexContext.java98
-rw-r--r--core/tests/coretests/src/android/content/ApexContextTest.java47
3 files changed, 152 insertions, 0 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index ba6a2ef05329..0e5f0e2123c5 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1718,6 +1718,13 @@ package android.companion {
package android.content {
+ public class ApexContext {
+ method @NonNull public static android.content.ApexContext getApexContext(@NonNull String);
+ method @NonNull public java.io.File getCredentialProtectedDataDirForUser(@NonNull android.os.UserHandle);
+ method @NonNull public java.io.File getDeviceProtectedDataDir();
+ method @NonNull public java.io.File getDeviceProtectedDataDirForUser(@NonNull android.os.UserHandle);
+ }
+
public abstract class BroadcastReceiver {
method @NonNull public final android.os.UserHandle getSendingUser();
}
diff --git a/core/java/android/content/ApexContext.java b/core/java/android/content/ApexContext.java
new file mode 100644
index 000000000000..fe5cedca4654
--- /dev/null
+++ b/core/java/android/content/ApexContext.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 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 android.content;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Environment;
+import android.os.UserHandle;
+
+import java.io.File;
+import java.util.Objects;
+
+/**
+ * Provides information about the environment for a particular APEX.
+ *
+ * @hide
+ */
+@SystemApi
+public class ApexContext {
+
+ private static final String APEX_DATA = "apexdata";
+
+ /**
+ * Returns an ApexContext instance for the APEX with the provided {@code apexModuleName}.
+ *
+ * <p>To preserve the safety and integrity of APEX modules, you must only obtain the ApexContext
+ * for your specific APEX, and you <em>must never</em> attempt to obtain an ApexContext for
+ * another APEX. Any coordination between APEXs must be performed through well-defined
+ * interfaces; attempting to directly read or write raw files belonging to another APEX will
+ * violate the hermetic storage requirements placed upon each module.
+ */
+ @NonNull
+ public static ApexContext getApexContext(@NonNull String apexModuleName) {
+ Objects.requireNonNull(apexModuleName, "apexModuleName cannot be null");
+ //TODO(b/141148175): Check that apexModuleName is an actual APEX name
+ return new ApexContext(apexModuleName);
+ }
+
+ private final String mApexModuleName;
+
+ private ApexContext(String apexModuleName) {
+ mApexModuleName = apexModuleName;
+ }
+
+ /**
+ * Returns the data directory for the APEX in device-encrypted, non-user-specific storage.
+ *
+ * <p>This directory is automatically created by the system for installed APEXes, and its
+ * contents will be rolled back if the APEX is rolled back.
+ */
+ @NonNull
+ public File getDeviceProtectedDataDir() {
+ return Environment.buildPath(
+ Environment.getDataMiscDirectory(), APEX_DATA, mApexModuleName);
+ }
+
+ /**
+ * Returns the data directory for the APEX in device-encrypted, user-specific storage for the
+ * specified {@code user}.
+ *
+ * <p>This directory is automatically created by the system for each user and for each installed
+ * APEX, and its contents will be rolled back if the APEX is rolled back.
+ */
+ @NonNull
+ public File getDeviceProtectedDataDirForUser(@NonNull UserHandle user) {
+ return Environment.buildPath(
+ Environment.getDataMiscDeDirectory(user.getIdentifier()), APEX_DATA,
+ mApexModuleName);
+ }
+
+ /**
+ * Returns the data directory for the APEX in credential-encrypted, user-specific storage for
+ * the specified {@code user}.
+ *
+ * <p>This directory is automatically created by the system for each user and for each installed
+ * APEX, and its contents will be rolled back if the APEX is rolled back.
+ */
+ @NonNull
+ public File getCredentialProtectedDataDirForUser(@NonNull UserHandle user) {
+ return Environment.buildPath(
+ Environment.getDataMiscCeDirectory(user.getIdentifier()), APEX_DATA,
+ mApexModuleName);
+ }
+}
diff --git a/core/tests/coretests/src/android/content/ApexContextTest.java b/core/tests/coretests/src/android/content/ApexContextTest.java
new file mode 100644
index 000000000000..d15c64d0935d
--- /dev/null
+++ b/core/tests/coretests/src/android/content/ApexContextTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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 android.content;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.UserHandle;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ApexContextTest {
+
+ @Test
+ public void dataDirectoryPathsAreAsExpected() {
+ ApexContext apexContext = ApexContext.getApexContext("my.apex");
+
+ assertEquals("/data/misc/apexdata/my.apex",
+ apexContext.getDeviceProtectedDataDir().getAbsolutePath());
+
+ assertEquals("/data/misc_de/5/apexdata/my.apex",
+ apexContext.getDeviceProtectedDataDirForUser(UserHandle.of(5)).getAbsolutePath());
+
+ assertEquals("/data/misc_ce/16/apexdata/my.apex",
+ apexContext.getCredentialProtectedDataDirForUser(
+ UserHandle.of(16)).getAbsolutePath());
+ }
+}