summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelka Chang <felkachang@google.com>2019-11-19 15:06:52 +0800
committerFelka Chang <felkachang@google.com>2019-12-16 09:52:12 +0800
commit0d824d4161ee582e6a4ca518ed262a0ca68bbef5 (patch)
tree44665f4073411909068b242728f7acdc467263df
parent70b60797305e68d001a7f5f9a6c6afa634deab4d (diff)
Add the root of crates by Context.getCrateDir
Context.getCrateDir() creates and returns the File for the root of the crates for the application context. Any child directories under the crates root in Context.getDataFile() is called the crate directory. For example: /data/user/0/com.exmaple.app/crates/IAmCratedFolder/decentFiles /data/user/0/com.exmaple.app/crates/IAmCratedFolder/decentDirs Context.getCrateDir return the crate dir --> /data/user/0/com.exmaple.app/crates/IAmCratedFolder The crate dir --> IAmCratedFolder The decent directories or files are not crated folders --> decentFiles, decentDirs Test: atest CtsOsTestCases:android.os.storage.cts.StorageCrateTest Bug: 141660526 Change-Id: If3ec1e121fb8f72bab5571d6190378e3ae208832
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/app/ContextImpl.java21
-rw-r--r--core/java/android/content/Context.java25
-rw-r--r--core/java/android/content/ContextWrapper.java10
-rw-r--r--test-mock/src/android/test/mock/MockContext.java10
5 files changed, 67 insertions, 0 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index 8dcc09590ddb..3fbbd61d7f6e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -697,6 +697,7 @@ package android.content {
public abstract class Context {
method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int);
method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public java.io.File getCrateDir(@NonNull String);
method public abstract android.view.Display getDisplay();
method public abstract int getDisplayId();
method public android.os.UserHandle getUser();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 46f88d5c81e4..155e93f9be19 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -99,6 +99,7 @@ import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteOrder;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -251,6 +252,8 @@ class ContextImpl extends Context {
@GuardedBy("mSync")
private File mFilesDir;
@GuardedBy("mSync")
+ private File mCratesDir;
+ @GuardedBy("mSync")
private File mNoBackupFilesDir;
@GuardedBy("mSync")
private File mCacheDir;
@@ -702,6 +705,24 @@ class ContextImpl extends Context {
}
@Override
+ public File getCrateDir(@NonNull String crateId) {
+ Preconditions.checkArgument(FileUtils.isValidExtFilename(crateId), "invalidated crateId");
+ final Path cratesRootPath = getDataDir().toPath().resolve("crates");
+ final Path absoluteNormalizedCratePath = cratesRootPath.resolve(crateId)
+ .toAbsolutePath().normalize();
+
+ synchronized (mSync) {
+ if (mCratesDir == null) {
+ mCratesDir = cratesRootPath.toFile();
+ }
+ ensurePrivateDirExists(mCratesDir);
+ }
+
+ File cratedDir = absoluteNormalizedCratePath.toFile();
+ return ensurePrivateDirExists(cratedDir);
+ }
+
+ @Override
public File getNoBackupFilesDir() {
synchronized (mSync) {
if (mNoBackupFilesDir == null) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fe774f8f639a..09b5132646c3 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1060,6 +1060,31 @@ public abstract class Context {
public abstract File getFilesDir();
/**
+ * Returns the absolute path to the directory that is related to the crate on the filesystem.
+ * <p>
+ * The crateId require a validated file name. It can't contain any "..", ".",
+ * {@link File#separatorChar} etc..
+ * </p>
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * </p>
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path.
+ *</p>
+ *
+ * @param crateId the relative validated file name under {@link Context#getDataDir()}/crates
+ * @return the crate directory file.
+ * @hide
+ */
+ @NonNull
+ @TestApi
+ public File getCrateDir(@NonNull String crateId) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* Returns the absolute path to the directory on the filesystem similar to
* {@link #getFilesDir()}. The difference is that files placed under this
* directory will be excluded from automatic backup to remote storage. See
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index d6442e28439f..d1b5135e959d 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -252,6 +252,16 @@ public class ContextWrapper extends Context {
return mBase.getFilesDir();
}
+ /**
+ * {@inheritDoc Context#getCrateDir()}
+ * @hide
+ */
+ @NonNull
+ @Override
+ public File getCrateDir(@NonNull String cratedId) {
+ return mBase.getCrateDir(cratedId);
+ }
+
@Override
public File getNoBackupFilesDir() {
return mBase.getNoBackupFilesDir();
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 0208c3a0a0de..9d913b9861e5 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -16,6 +16,7 @@
package android.test.mock;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
@@ -211,6 +212,15 @@ public class MockContext extends Context {
throw new UnsupportedOperationException();
}
+ /**
+ * {@inheritDoc Context#getCrateDir()}
+ * @hide
+ */
+ @Override
+ public File getCrateDir(@NonNull String crateId) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public File getNoBackupFilesDir() {
throw new UnsupportedOperationException();