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

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

Merge "Split VOLUME_EXTERNAL and VOLUME_PRIMARY." into qt-dev

parents a1cab98a 586d3c01
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -38478,8 +38478,8 @@ package android.provider {
  public final class MediaStore {
    ctor public MediaStore();
    method @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
    method @Nullable public static android.net.Uri getDocumentUri(@NonNull android.content.Context, @NonNull android.net.Uri);
    method @NonNull public static java.util.Set<java.lang.String> getExternalVolumeNames(@NonNull android.content.Context);
    method public static android.net.Uri getMediaScannerUri();
    method @Nullable public static android.net.Uri getMediaUri(@NonNull android.content.Context, @NonNull android.net.Uri);
    method @NonNull public static String getVersion(@NonNull android.content.Context);
@@ -38523,6 +38523,7 @@ package android.provider {
    field public static final String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE = "android.media.still_image_camera_preview_service";
    field public static final String UNKNOWN_STRING = "<unknown>";
    field public static final String VOLUME_EXTERNAL = "external";
    field public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
    field public static final String VOLUME_INTERNAL = "internal";
  }
@@ -38771,6 +38772,7 @@ package android.provider {
    field public static final String RELATIVE_PATH = "relative_path";
    field public static final String SIZE = "_size";
    field public static final String TITLE = "title";
    field public static final String VOLUME_NAME = "volume_name";
    field public static final String WIDTH = "width";
  }
+1 −0
Original line number Diff line number Diff line
@@ -514,6 +514,7 @@ package android.provider {

  public final class MediaStore {
    method @Deprecated @NonNull public static android.net.Uri createPending(@NonNull android.content.Context, @NonNull android.provider.MediaStore.PendingParams);
    method @Deprecated @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
    method @Deprecated @NonNull public static android.provider.MediaStore.PendingSession openPending(@NonNull android.content.Context, @NonNull android.net.Uri);
    method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
    method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
+1 −1
Original line number Diff line number Diff line
@@ -1130,7 +1130,7 @@ public class StorageManager {
    public @NonNull StorageVolume getStorageVolume(@NonNull Uri uri) {
        final String volumeName = MediaStore.getVolumeName(uri);
        switch (volumeName) {
            case MediaStore.VOLUME_EXTERNAL:
            case MediaStore.VOLUME_EXTERNAL_PRIMARY:
                return getPrimaryStorageVolume();
            default:
                for (StorageVolume vol : getStorageVolumes()) {
+6 −1
Original line number Diff line number Diff line
@@ -264,9 +264,14 @@ public final class StorageVolume implements Parcelable {
        return mFsUuid;
    }

    /** {@hide} */
    public static @Nullable String normalizeUuid(@Nullable String fsUuid) {
        return fsUuid != null ? fsUuid.toLowerCase(Locale.US) : null;
    }

    /** {@hide} */
    public @Nullable String getNormalizedUuid() {
        return mFsUuid != null ? mFsUuid.toLowerCase(Locale.US) : null;
        return normalizeUuid(mFsUuid);
    }

    /**
+87 −35
Original line number Diff line number Diff line
@@ -102,20 +102,40 @@ public final class MediaStore {
    public static final @NonNull Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);

    /**
     * Volume name used for content on "internal" storage of device. This
     * volume contains media distributed with the device, such as built-in
     * ringtones and wallpapers.
     * Synthetic volume name that provides a view of all content across the
     * "internal" storage of the device.
     * <p>
     * This synthetic volume provides a merged view of all media distributed
     * with the device, such as built-in ringtones and wallpapers.
     * <p>
     * Because this is a synthetic volume, you can't insert new content into
     * this volume.
     */
    public static final String VOLUME_INTERNAL = "internal";

    /**
     * Volume name used for content on "external" storage of device. This only
     * includes media on the primary shared storage device; the contents of any
     * secondary storage devices can be obtained using
     * {@link #getAllVolumeNames(Context)}.
     * Synthetic volume name that provides a view of all content across the
     * "external" storage of the device.
     * <p>
     * This synthetic volume provides a merged view of all media across all
     * currently attached external storage devices.
     * <p>
     * Because this is a synthetic volume, you can't insert new content into
     * this volume. Instead, you can insert content into a specific storage
     * volume obtained from {@link #getExternalVolumeNames(Context)}.
     */
    public static final String VOLUME_EXTERNAL = "external";

    /**
     * Specific volume name that represents the primary external storage device
     * at {@link Environment#getExternalStorageDirectory()}.
     * <p>
     * This volume may not always be available, such as when the user has
     * ejected the device. You can find a list of all specific volume names
     * using {@link #getExternalVolumeNames(Context)}.
     */
    public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";

    /** {@hide} */
    public static final String SCAN_FILE_CALL = "scan_file";
    /** {@hide} */
@@ -1036,6 +1056,16 @@ public final class MediaStore {
        @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
        public static final String OWNER_PACKAGE_NAME = "owner_package_name";

        /**
         * Volume name of the specific storage device where this media item is
         * persisted. The value is typically one of the volume names returned
         * from {@link MediaStore#getExternalVolumeNames(Context)}.
         * <p>
         * This is a read-only column that is automatically computed.
         */
        @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
        public static final String VOLUME_NAME = "volume_name";

        /**
         * Relative path of this media item within the storage device where it
         * is persisted. For example, an item stored at
@@ -1408,7 +1438,7 @@ public final class MediaStore {
            final StorageVolume sv = sm.getStorageVolume(path);
            if (sv != null) {
                if (sv.isPrimary()) {
                    return VOLUME_EXTERNAL;
                    return VOLUME_EXTERNAL_PRIMARY;
                } else {
                    return checkArgumentVolumeName(sv.getNormalizedUuid());
                }
@@ -1710,7 +1740,7 @@ public final class MediaStore {
                String stringUrl = null;    /* value to be returned */

                try {
                    url = cr.insert(EXTERNAL_CONTENT_URI, values);
                    url = cr.insert(getContentUri(VOLUME_EXTERNAL_PRIMARY), values);

                    if (source != null) {
                        try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(
@@ -3224,22 +3254,29 @@ public final class MediaStore {
        }
    }

    /** @removed */
    @Deprecated
    public static @NonNull Set<String> getAllVolumeNames(@NonNull Context context) {
        return getExternalVolumeNames(context);
    }

    /**
     * Return list of all volume names currently available. This includes a
     * unique name for each shared storage device that is currently mounted.
     * Return list of all specific volume names that make up
     * {@link #VOLUME_EXTERNAL}. This includes a unique volume name for each
     * shared storage device that is currently attached, which typically
     * includes {@link MediaStore#VOLUME_EXTERNAL_PRIMARY}.
     * <p>
     * Each name can be passed to APIs like
     * {@link MediaStore.Images.Media#getContentUri(String)} to query media at
     * that location.
     * Each specific volume name can be passed to APIs like
     * {@link MediaStore.Images.Media#getContentUri(String)} to interact with
     * media on that storage device.
     */
    public static @NonNull Set<String> getAllVolumeNames(@NonNull Context context) {
    public static @NonNull Set<String> getExternalVolumeNames(@NonNull Context context) {
        final StorageManager sm = context.getSystemService(StorageManager.class);
        final Set<String> volumeNames = new ArraySet<>();
        volumeNames.add(VOLUME_INTERNAL);
        for (VolumeInfo vi : sm.getVolumes()) {
            if (vi.isVisibleForUser(UserHandle.myUserId()) && vi.isMountedReadable()) {
                if (vi.isPrimary()) {
                    volumeNames.add(VOLUME_EXTERNAL);
                    volumeNames.add(VOLUME_EXTERNAL_PRIMARY);
                } else {
                    volumeNames.add(vi.getNormalizedFsUuid());
                }
@@ -3270,6 +3307,8 @@ public final class MediaStore {
            return volumeName;
        } else if (VOLUME_EXTERNAL.equals(volumeName)) {
            return volumeName;
        } else if (VOLUME_EXTERNAL_PRIMARY.equals(volumeName)) {
            return volumeName;
        }

        // When not one of the well-known values above, it must be a hex UUID
@@ -3285,8 +3324,9 @@ public final class MediaStore {
    }

    /**
     * Return path where the given volume is mounted. Not valid for
     * {@link #VOLUME_INTERNAL}.
     * Return path where the given specific volume is mounted. Not valid for
     * {@link #VOLUME_INTERNAL} or {@link #VOLUME_EXTERNAL}, since those are
     * broad collections that cover many paths.
     *
     * @hide
     */
@@ -3297,7 +3337,11 @@ public final class MediaStore {
            throw new IllegalArgumentException();
        }

        if (VOLUME_EXTERNAL.equals(volumeName)) {
        switch (volumeName) {
            case VOLUME_INTERNAL:
            case VOLUME_EXTERNAL:
                throw new FileNotFoundException(volumeName + " has no associated path");
            case VOLUME_EXTERNAL_PRIMARY:
                return Environment.getExternalStorageDirectory();
        }

@@ -3328,23 +3372,31 @@ public final class MediaStore {
            throw new IllegalArgumentException();
        }

        final Context context = AppGlobals.getInitialApplication();
        final UserManager um = context.getSystemService(UserManager.class);

        final ArrayList<File> res = new ArrayList<>();
        if (VOLUME_INTERNAL.equals(volumeName)) {
            addCanoncialFile(res, new File(Environment.getRootDirectory(), "media"));
            addCanoncialFile(res, new File(Environment.getOemDirectory(), "media"));
            addCanoncialFile(res, new File(Environment.getProductDirectory(), "media"));
            addCanonicalFile(res, new File(Environment.getRootDirectory(), "media"));
            addCanonicalFile(res, new File(Environment.getOemDirectory(), "media"));
            addCanonicalFile(res, new File(Environment.getProductDirectory(), "media"));
        } else if (VOLUME_EXTERNAL.equals(volumeName)) {
            for (String exactVolume : getExternalVolumeNames(context)) {
                addCanonicalFile(res, getVolumePath(exactVolume));
            }
            if (um.isDemoUser()) {
                addCanonicalFile(res, Environment.getDataPreloadsMediaDirectory());
            }
        } else {
            addCanoncialFile(res, getVolumePath(volumeName));
            final UserManager um = AppGlobals.getInitialApplication()
                    .getSystemService(UserManager.class);
            if (VOLUME_EXTERNAL.equals(volumeName) && um.isDemoUser()) {
                addCanoncialFile(res, Environment.getDataPreloadsMediaDirectory());
            addCanonicalFile(res, getVolumePath(volumeName));
            if (VOLUME_EXTERNAL_PRIMARY.equals(volumeName) && um.isDemoUser()) {
                addCanonicalFile(res, Environment.getDataPreloadsMediaDirectory());
            }
        }
        return res;
    }

    private static void addCanoncialFile(List<File> list, File file) {
    private static void addCanonicalFile(List<File> list, File file) {
        try {
            list.add(file.getCanonicalFile());
        } catch (IOException e) {
@@ -3382,12 +3434,12 @@ public final class MediaStore {
     * <p>
     * No other assumptions should be made about the meaning of the version.
     * <p>
     * This method returns the version for {@link MediaStore#VOLUME_EXTERNAL};
     * to obtain a version for a different volume, use
     * {@link #getVersion(Context, String)}.
     * This method returns the version for
     * {@link MediaStore#VOLUME_EXTERNAL_PRIMARY}; to obtain a version for a
     * different volume, use {@link #getVersion(Context, String)}.
     */
    public static @NonNull String getVersion(@NonNull Context context) {
        return getVersion(context, VOLUME_EXTERNAL);
        return getVersion(context, VOLUME_EXTERNAL_PRIMARY);
    }

    /**
@@ -3401,7 +3453,7 @@ public final class MediaStore {
     *
     * @param volumeName specific volume to obtain an opaque version string for.
     *            Must be one of the values returned from
     *            {@link #getAllVolumeNames(Context)}.
     *            {@link #getExternalVolumeNames(Context)}.
     */
    public static @NonNull String getVersion(@NonNull Context context, @NonNull String volumeName) {
        final ContentResolver resolver = context.getContentResolver();