summaryrefslogtreecommitdiffstats
path: root/core/java/android/app/ContextImpl.java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-08-11 16:28:14 -0700
committerJeff Sharkey <jsharkey@android.com>2013-08-11 17:07:44 -0700
commit1abdb7123025e52512b2ed7a518f8c754c35f50a (patch)
treec6ee8a4b4b4f8cf7b865d2d537823d6a59dca441 /core/java/android/app/ContextImpl.java
parent09335703572db7d6a9b43f3aba32074e473d6a0f (diff)
downloadframeworks_base-1abdb7123025e52512b2ed7a518f8c754c35f50a.zip
frameworks_base-1abdb7123025e52512b2ed7a518f8c754c35f50a.tar.gz
frameworks_base-1abdb7123025e52512b2ed7a518f8c754c35f50a.tar.bz2
APIs for multiple external storage devices.
Provide developer APIs to discover application-specific paths on secondary external storage devices. Covers files, cache, and OBB directories. Apps will not have write access outside their package- specific directories on secondary devices, so only primary storage is exposed through Environment. Creation of .nomedia files will be handled by FUSE daemon in future change. Change-Id: Ifcce6201a686d80269d7285adb597c008cf8fa7c
Diffstat (limited to 'core/java/android/app/ContextImpl.java')
-rw-r--r--core/java/android/app/ContextImpl.java113
1 files changed, 67 insertions, 46 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index eb5c3e7..cdec399 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -111,6 +111,7 @@ import android.accounts.AccountManager;
import android.accounts.IAccountManager;
import android.app.admin.DevicePolicyManager;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.internal.os.IDropBoxManagerService;
@@ -197,13 +198,21 @@ class ContextImpl extends Context {
private final Object mSync = new Object();
+ @GuardedBy("mSync")
private File mDatabasesDir;
+ @GuardedBy("mSync")
private File mPreferencesDir;
+ @GuardedBy("mSync")
private File mFilesDir;
+ @GuardedBy("mSync")
private File mCacheDir;
- private File mObbDir;
- private File mExternalFilesDir;
- private File mExternalCacheDir;
+
+ @GuardedBy("mSync")
+ private File[] mExternalObbDirs;
+ @GuardedBy("mSync")
+ private File[] mExternalFilesDirs;
+ @GuardedBy("mSync")
+ private File[] mExternalCacheDirs;
private static final String[] EMPTY_FILE_LIST = {};
@@ -802,44 +811,41 @@ class ContextImpl extends Context {
@Override
public File getExternalFilesDir(String type) {
+ // Operates on primary external storage
+ return getExternalFilesDirs(type)[0];
+ }
+
+ @Override
+ public File[] getExternalFilesDirs(String type) {
synchronized (mSync) {
- if (mExternalFilesDir == null) {
- mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
- getPackageName());
- }
- if (!mExternalFilesDir.exists()) {
- try {
- (new File(Environment.getExternalStorageAndroidDataDir(),
- ".nomedia")).createNewFile();
- } catch (IOException e) {
- }
- if (!mExternalFilesDir.mkdirs()) {
- Log.w(TAG, "Unable to create external files directory");
- return null;
- }
- }
- if (type == null) {
- return mExternalFilesDir;
+ if (mExternalFilesDirs == null) {
+ mExternalFilesDirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
}
- File dir = new File(mExternalFilesDir, type);
- if (!dir.exists()) {
- if (!dir.mkdirs()) {
- Log.w(TAG, "Unable to create external media directory " + dir);
- return null;
- }
+
+ // Splice in requested type, if any
+ File[] dirs = mExternalFilesDirs;
+ if (type != null) {
+ dirs = Environment.buildPaths(dirs, type);
}
- return dir;
+
+ // Create dirs if needed
+ return ensureDirsExistOrFilter(dirs);
}
}
@Override
public File getObbDir() {
+ // Operates on primary external storage
+ return getObbDirs()[0];
+ }
+
+ @Override
+ public File[] getObbDirs() {
synchronized (mSync) {
- if (mObbDir == null) {
- mObbDir = Environment.getExternalStorageAppObbDirectory(
- getPackageName());
+ if (mExternalObbDirs == null) {
+ mExternalObbDirs = Environment.buildExternalStorageAppObbDirs(getPackageName());
}
- return mObbDir;
+ return mExternalObbDirs;
}
}
@@ -865,23 +871,19 @@ class ContextImpl extends Context {
@Override
public File getExternalCacheDir() {
+ // Operates on primary external storage
+ return getExternalCacheDirs()[0];
+ }
+
+ @Override
+ public File[] getExternalCacheDirs() {
synchronized (mSync) {
- if (mExternalCacheDir == null) {
- mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
- getPackageName());
+ if (mExternalCacheDirs == null) {
+ mExternalCacheDirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
}
- if (!mExternalCacheDir.exists()) {
- try {
- (new File(Environment.getExternalStorageAndroidDataDir(),
- ".nomedia")).createNewFile();
- } catch (IOException e) {
- }
- if (!mExternalCacheDir.mkdirs()) {
- Log.w(TAG, "Unable to create external cache directory");
- return null;
- }
- }
- return mExternalCacheDir;
+
+ // Create dirs if needed
+ return ensureDirsExistOrFilter(mExternalCacheDirs);
}
}
@@ -2081,6 +2083,25 @@ class ContextImpl extends Context {
"File " + name + " contains a path separator");
}
+ /**
+ * Ensure that given directories exist, trying to create them if missing. If
+ * unable to create, they are filtered by replacing with {@code null}.
+ */
+ private static File[] ensureDirsExistOrFilter(File[] dirs) {
+ File[] result = new File[dirs.length];
+ for (int i = 0; i < dirs.length; i++) {
+ File dir = dirs[i];
+ if (!dir.exists()) {
+ if (!dir.mkdirs()) {
+ Log.w(TAG, "Failed to ensure directory: " + dir);
+ dir = null;
+ }
+ }
+ result[i] = dir;
+ }
+ return result;
+ }
+
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------