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

Commit 2ac87694 authored by Felipe Leme's avatar Felipe Leme
Browse files

Minor tweaks on Scoped Directory Access:

- Only allow entire directory access on non-primary volumes.
- Do not display primary storage label on scoped access.

BUG: 27743842
BUG: 27676858
Change-Id: I9884fb1e2df3534fceebc5d5bef44adfb758724c
parent 3d6dc3a6
Loading
Loading
Loading
Loading
+24 −17
Original line number Diff line number Diff line
@@ -315,27 +315,34 @@ public final class StorageVolume implements Parcelable {
     * To gain access to descendants (child, grandchild, etc) documents, use
     * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)}, or
     * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} with the returned URI.
     *
     * <b>If your application only needs to store internal data, consider using
     * <p>
     * If your application only needs to store internal data, consider using
     * {@link Context#getExternalFilesDirs(String) Context.getExternalFilesDirs},
     * {@link Context#getExternalCacheDirs()}, or
     * {@link Context#getExternalMediaDirs()}, which require no permissions to read or write.
     *
     * <strong>NOTE: </strong>requesting access to the entire volume is not recommended and it will
     * result in a stronger message displayed to the user, which may cause the user to reject
     * the request.
     *
     * @param directoryName must be one of
     * {@link Environment#DIRECTORY_MUSIC}, {@link Environment#DIRECTORY_PODCASTS},
     * {@link Environment#DIRECTORY_RINGTONES}, {@link Environment#DIRECTORY_ALARMS},
     * {@link Environment#DIRECTORY_NOTIFICATIONS}, {@link Environment#DIRECTORY_PICTURES},
     * {@link Environment#DIRECTORY_MOVIES}, {@link Environment#DIRECTORY_DOWNLOADS},
     * {@link Environment#DIRECTORY_DCIM}, or {@link Environment#DIRECTORY_DOCUMENTS}, or
     * {code null} to request access to the entire volume.
     * {@link Context#getExternalCacheDirs()}, or {@link Context#getExternalMediaDirs()}, which
     * require no permissions to read or write.
     * <p>
     * Access to the entire volume is only available for non-primary volumes (for the primary
     * volume, apps can use the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} and
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions) and should be used
     * with caution, since users are more likely to deny access when asked for entire volume access
     * rather than specific directories.
     *
     * @param directoryName must be one of {@link Environment#DIRECTORY_MUSIC},
     *            {@link Environment#DIRECTORY_PODCASTS}, {@link Environment#DIRECTORY_RINGTONES},
     *            {@link Environment#DIRECTORY_ALARMS}, {@link Environment#DIRECTORY_NOTIFICATIONS},
     *            {@link Environment#DIRECTORY_PICTURES}, {@link Environment#DIRECTORY_MOVIES},
     *            {@link Environment#DIRECTORY_DOWNLOADS}, {@link Environment#DIRECTORY_DCIM}, or
     *            {@link Environment#DIRECTORY_DOCUMENTS}, or {code null} to request access to the
     *            entire volume.
     * @return intent to request access, or {@code null} if the requested directory is invalid for
     *         that volume.
     * @see DocumentsContract
     */
    public Intent createAccessIntent(String directoryName) {
    public @Nullable Intent createAccessIntent(String directoryName) {
        if ((isPrimary() && directoryName == null) ||
                (directoryName != null && !Environment.isStandardDirectory(directoryName))) {
            return null;
        }
        final Intent intent = new Intent(ACTION_OPEN_EXTERNAL_DIRECTORY);
        intent.putExtra(EXTRA_STORAGE_VOLUME, this);
        intent.putExtra(EXTRA_DIRECTORY_NAME, directoryName);
+3 −0
Original line number Diff line number Diff line
@@ -204,6 +204,9 @@
    <string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory on
        <xliff:g id="storage" example="SD Card"><i>^3</i></xliff:g>?</string>
    <!-- Text in an alert dialog asking user to grant app access to a given directory in the internal storage -->
    <string name="open_external_dialog_request_primary_volume">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory?</string>
    <!-- Text in an alert dialog asking user to grant app access to all data in an external storage volume -->
    <string name="open_external_dialog_root_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
        access to your data, including photos and videos, on <xliff:g id="storage" example="SD Card"><i>^2</i></xliff:g>?</string>
+14 −1
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ public class OpenExternalDirectoryActivity extends Activity {
    private static final String EXTRA_VOLUME_LABEL = "com.android.documentsui.VOLUME_LABEL";
    private static final String EXTRA_VOLUME_UUID = "com.android.documentsui.VOLUME_UUID";
    private static final String EXTRA_IS_ROOT = "com.android.documentsui.IS_ROOT";
    private static final String EXTRA_IS_PRIMARY = "com.android.documentsui.IS_PRIMARY";
    // Special directory name representing the full volume
    static final String DIRECTORY_ROOT = "ROOT_DIRECTORY";

@@ -157,6 +158,13 @@ public class OpenExternalDirectoryActivity extends Activity {
            Log.d(TAG, "showFragment() for volume " + storageVolume.dump() + ", directory "
                    + directoryName + ", and user " + userId);
        final boolean isRoot = directoryName.equals(DIRECTORY_ROOT);
        final boolean isPrimary = storageVolume.isPrimary();

        if (isRoot && isPrimary) {
            if (DEBUG) Log.d(TAG, "root access requested on primary volume");
            return false;
        }

        final File volumeRoot = storageVolume.getPathFile();
        File file;
        try {
@@ -235,6 +243,7 @@ public class OpenExternalDirectoryActivity extends Activity {
        args.putString(EXTRA_VOLUME_UUID, volumeUuid);
        args.putString(EXTRA_APP_LABEL, appLabel);
        args.putBoolean(EXTRA_IS_ROOT, isRoot);
        args.putBoolean(EXTRA_IS_PRIMARY, isPrimary);

        final FragmentManager fm = activity.getFragmentManager();
        final FragmentTransaction ft = fm.beginTransaction();
@@ -352,6 +361,7 @@ public class OpenExternalDirectoryActivity extends Activity {
        private String mVolumeLabel;
        private String mAppLabel;
        private boolean mIsRoot;
        private boolean mIsPrimary;
        private CheckBox mDontAskAgain;
        private OpenExternalDirectoryActivity mActivity;
        private AlertDialog mDialog;
@@ -367,6 +377,7 @@ public class OpenExternalDirectoryActivity extends Activity {
                mVolumeLabel = args.getString(EXTRA_VOLUME_LABEL);
                mAppLabel = args.getString(EXTRA_APP_LABEL);
                mIsRoot = args.getBoolean(EXTRA_IS_ROOT);
                mIsPrimary= args.getBoolean(EXTRA_IS_PRIMARY);
            }
            mActivity = (OpenExternalDirectoryActivity) getActivity();
        }
@@ -435,7 +446,9 @@ public class OpenExternalDirectoryActivity extends Activity {
                message = TextUtils.expandTemplate(getText(
                        R.string.open_external_dialog_root_request), mAppLabel, mVolumeLabel);
            } else {
                message = TextUtils.expandTemplate(getText(R.string.open_external_dialog_request),
                message = TextUtils.expandTemplate(
                        getText(mIsPrimary ? R.string.open_external_dialog_request_primary_volume
                                : R.string.open_external_dialog_request),
                        mAppLabel, directory, mVolumeLabel);
            }
            final TextView messageField = (TextView) view.findViewById(R.id.message);