Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e14b22c authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "APIs for multiple external storage devices." into klp-dev

parents b8160401 1abdb712
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -5718,11 +5718,14 @@ package android.content {
    method public abstract java.io.File getDatabasePath(java.lang.String);
    method public abstract java.io.File getDir(java.lang.String, int);
    method public abstract java.io.File getExternalCacheDir();
    method public abstract java.io.File[] getExternalCacheDirs();
    method public abstract java.io.File getExternalFilesDir(java.lang.String);
    method public abstract java.io.File[] getExternalFilesDirs(java.lang.String);
    method public abstract java.io.File getFileStreamPath(java.lang.String);
    method public abstract java.io.File getFilesDir();
    method public abstract android.os.Looper getMainLooper();
    method public abstract java.io.File getObbDir();
    method public abstract java.io.File[] getObbDirs();
    method public abstract java.lang.String getPackageCodePath();
    method public abstract android.content.pm.PackageManager getPackageManager();
    method public abstract java.lang.String getPackageName();
@@ -5873,11 +5876,14 @@ package android.content {
    method public java.io.File getDatabasePath(java.lang.String);
    method public java.io.File getDir(java.lang.String, int);
    method public java.io.File getExternalCacheDir();
    method public java.io.File[] getExternalCacheDirs();
    method public java.io.File getExternalFilesDir(java.lang.String);
    method public java.io.File[] getExternalFilesDirs(java.lang.String);
    method public java.io.File getFileStreamPath(java.lang.String);
    method public java.io.File getFilesDir();
    method public android.os.Looper getMainLooper();
    method public java.io.File getObbDir();
    method public java.io.File[] getObbDirs();
    method public java.lang.String getPackageCodePath();
    method public android.content.pm.PackageManager getPackageManager();
    method public java.lang.String getPackageName();
@@ -17530,6 +17536,7 @@ package android.os {
    method public static java.io.File getExternalStoragePublicDirectory(java.lang.String);
    method public static java.lang.String getExternalStorageState();
    method public static java.io.File getRootDirectory();
    method public static java.lang.String getStorageState(java.io.File);
    method public static boolean isExternalStorageEmulated();
    method public static boolean isExternalStorageRemovable();
    field public static java.lang.String DIRECTORY_ALARMS;
@@ -17548,6 +17555,7 @@ package android.os {
    field public static final java.lang.String MEDIA_NOFS = "nofs";
    field public static final java.lang.String MEDIA_REMOVED = "removed";
    field public static final java.lang.String MEDIA_SHARED = "shared";
    field public static final java.lang.String MEDIA_UNKNOWN = "unknown";
    field public static final java.lang.String MEDIA_UNMOUNTABLE = "unmountable";
    field public static final java.lang.String MEDIA_UNMOUNTED = "unmounted";
  }
+67 −46
Original line number Diff line number Diff line
@@ -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) {
        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;
        // Operates on primary external storage
        return getExternalFilesDirs(type)[0];
    }
            File dir = new File(mExternalFilesDir, type);
            if (!dir.exists()) {
                if (!dir.mkdirs()) {
                    Log.w(TAG, "Unable to create external media directory " + dir);
                    return null;

    @Override
    public File[] getExternalFilesDirs(String type) {
        synchronized (mSync) {
            if (mExternalFilesDirs == null) {
                mExternalFilesDirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
            }

            // 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() {
        synchronized (mSync) {
            if (mExternalCacheDir == null) {
                mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
                        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;
        // Operates on primary external storage
        return getExternalCacheDirs()[0];
    }

    @Override
    public File[] getExternalCacheDirs() {
        synchronized (mSync) {
            if (mExternalCacheDirs == null) {
                mExternalCacheDirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
            }
            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;
    }

    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
+4 −5
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app;

import android.content.Context;
@@ -23,17 +24,15 @@ import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.os.MessageQueue;
import android.util.AttributeSet;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.WindowManager;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import java.io.File;
@@ -176,8 +175,8 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
                ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;

        mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
                 getFilesDir().toString(), getObbDir().toString(),
                 Environment.getExternalStorageAppFilesDirectory(ai.packageName).toString(),
                 getFilesDir().getAbsolutePath(), getObbDir().getAbsolutePath(),
                 getExternalFilesDir(null).getAbsolutePath(),
                 Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
        
        if (mNativeHandle == 0) {
+89 −14
Original line number Diff line number Diff line
@@ -590,7 +590,7 @@ public abstract class Context {
     * Returns the absolute path to the directory on the external filesystem
     * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
     * Environment.getExternalStorageDirectory()}) where the application can
     * place persistent files it owns.  These files are private to the
     * place persistent files it owns.  These files are internal to the
     * applications, and not typically visible to the user as media.
     *
     * <p>This is like {@link #getFilesDir()} in that these
@@ -637,9 +637,11 @@ public abstract class Context {
     *
     * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
     * private_picture}
     *
     * <p>Writing to this path requires the
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p>
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, no
     * permissions are required for the owning application to read or write to
     * this path. Otherwise, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
     * or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
     *
     * @param type The type of files directory to return.  May be null for
     * the root of the files directory or one of
@@ -663,17 +665,65 @@ public abstract class Context {
    public abstract File getExternalFilesDir(String type);

    /**
     * Return the directory where this application's OBB files (if there
     * are any) can be found.  Note if the application does not have any OBB
     * files, this directory may not exist.
     * Returns absolute paths to application-specific directories on all
     * external storage devices where the application can place persistent files
     * it owns. These files are internal to the application, and not typically
     * visible to the user as media.
     * <p>
     * External storage devices returned here are considered a permanent part of
     * the device, including both emulated external storage and physical media
     * slots. This does not include transient devices, such as USB flash drives.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, no
     * permissions are required for the owning application to read or write to
     * these paths.
     * <p>
     * The returned paths include any path that would be returned by
     * {@link #getExternalFilesDir(String)}.
     *
     * <p>On devices with multiple users (as described by {@link UserManager}),
     * @see #getExternalFilesDir(String)
     */
    public abstract File[] getExternalFilesDirs(String type);

    /**
     * Return the directory where this application's OBB files (if there are
     * any) can be found. Note if the application does not have any OBB files,
     * this directory may not exist.
     * <p>
     * On devices with multiple users (as described by {@link UserManager}),
     * multiple users may share the same OBB storage location. Applications
     * should ensure that multiple instances running under different users
     * don't interfere with each other.</p>
     * should ensure that multiple instances running under different users don't
     * interfere with each other.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, no
     * permissions are required for the owning application to read or write to
     * this path. Otherwise,
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} or
     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
     */
    public abstract File getObbDir();

    /**
     * Returns absolute paths to application-specific directories on all
     * external storage devices where the application's OBB files (if there are
     * any) can be found. Note if the application does not have any OBB files,
     * these directories may not exist.
     * <p>
     * External storage devices returned here are considered a permanent part of
     * the device, including both emulated external storage and physical media
     * slots. This does not include transient devices, such as USB flash drives.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, no
     * permissions are required for the owning application to read or write to
     * this path.
     * <p>
     * The returned paths include any path that would be returned by
     * {@link #getObbDir()}
     *
     * @see #getObbDir()
     */
    public abstract File[] getObbDirs();

    /**
     * Returns the absolute path to the application specific cache directory
     * on the filesystem. These files will be ones that get deleted first when the
@@ -697,7 +747,8 @@ public abstract class Context {
     * Returns the absolute path to the directory on the external filesystem
     * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
     * Environment.getExternalStorageDirectory()} where the application can
     * place cache files it owns.
     * place cache files it owns. These files are internal to the application, and
     * not typically visible to the user as media.
     *
     * <p>This is like {@link #getCacheDir()} in that these
     * files will be deleted when the application is uninstalled, however there
@@ -722,9 +773,12 @@ public abstract class Context {
     * <p>On devices with multiple users (as described by {@link UserManager}),
     * each user has their own isolated external storage. Applications only
     * have access to the external storage for the user they're running as.</p>
     *
     * <p>Writing to this path requires the
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p>
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, no
     * permissions are required for the owning application to read or write to
     * this path. Otherwise,
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} or
     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
     *
     * @return The path of the directory holding application cache files
     * on external storage.  Returns null if external storage is not currently
@@ -735,6 +789,27 @@ public abstract class Context {
     */
    public abstract File getExternalCacheDir();

    /**
     * Returns absolute paths to application-specific directories on all
     * external storage devices where the application can place cache files it
     * owns. These files are internal to the application, and not typically
     * visible to the user as media.
     * <p>
     * External storage devices returned here are considered a permanent part of
     * the device, including both emulated external storage and physical media
     * slots. This does not include transient devices, such as USB flash drives.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, no
     * permissions are required for the owning application to read or write to
     * these paths.
     * <p>
     * The returned paths include any path that would be returned by
     * {@link #getExternalCacheDir()}.
     *
     * @see #getExternalCacheDir()
     */
    public abstract File[] getExternalCacheDirs();

    /**
     * Returns an array of strings naming the private files associated with
     * this Context's application package.
+17 −2
Original line number Diff line number Diff line
@@ -204,11 +204,21 @@ public class ContextWrapper extends Context {
        return mBase.getExternalFilesDir(type);
    }

    @Override
    public File[] getExternalFilesDirs(String type) {
        return mBase.getExternalFilesDirs(type);
    }

    @Override
    public File getObbDir() {
        return mBase.getObbDir();
    }

    @Override
    public File[] getObbDirs() {
        return mBase.getObbDirs();
    }

    @Override
    public File getCacheDir() {
        return mBase.getCacheDir();
@@ -219,6 +229,11 @@ public class ContextWrapper extends Context {
        return mBase.getExternalCacheDir();
    }

    @Override
    public File[] getExternalCacheDirs() {
        return mBase.getExternalCacheDirs();
    }

    @Override
    public File getDir(String name, int mode) {
        return mBase.getDir(name, mode);
Loading