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

Commit 59d577a5 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Browse mode for DocumentsUI, removed volume state.

The existing management mode is too specific, and requires that
storage backends add queryChildDocumentsForManage(), etc.  Instead,
to offer more natural browsing support, add a new BROWSE_ROOT intent.

It behaves mostly like MANAGE_ROOT, except that it doesn't mutate
its Uris with setManageMode(), and it shortcuts straight to VIEW on
clicked documents.

It can be launched like this:

$ adb shell am start -a android.provider.action.BROWSE_ROOT
    -d content://com.android.externalstorage.documents/root/8405-1DFB
    -c android.intent.category.DEFAULT

Also rename a MetricsConstants to make it clearer, and don't
auto-mount all emulated volumes.

Fix bugs around parceling of DiskInfo/VolumeInfo.  Method to resolve
the best description for a VolumeInfo, which might need to fall
back to DiskInfo.

Add back "removed" volume state so we send broadcast when a volume
is destroyed, matching the expected public API behavior.

Bug: 19993667
Change-Id: I13aff32c5e11dfc63da44aee9e93a27f4690a43f
parent 6036cd51
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package android.os.storage;

import android.content.Context;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DebugUtils;
@@ -57,12 +57,12 @@ public class DiskInfo implements Parcelable {
        volumes = parcel.readStringArray();
    }

    public String getDescription(Context context) {
    public String getDescription() {
        // TODO: splice vendor label into these strings
        if ((flags & FLAG_SD) != 0) {
            return context.getString(com.android.internal.R.string.storage_sd_card);
            return Resources.getSystem().getString(com.android.internal.R.string.storage_sd_card);
        } else if ((flags & FLAG_USB) != 0) {
            return context.getString(com.android.internal.R.string.storage_usb);
            return Resources.getSystem().getString(com.android.internal.R.string.storage_usb);
        } else {
            return null;
        }
@@ -119,7 +119,7 @@ public class DiskInfo implements Parcelable {
    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeString(id);
        parcel.writeInt(flags);
        parcel.writeInt(this.flags);
        parcel.writeLong(size);
        parcel.writeString(label);
        parcel.writeStringArray(volumes);
+31 −0
Original line number Diff line number Diff line
@@ -30,10 +30,12 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;

import java.io.File;
@@ -453,6 +455,18 @@ public class StorageManager {
        return null;
    }

    /** {@hide} */
    public @Nullable DiskInfo findDiskByVolumeId(String volId) {
        Preconditions.checkNotNull(volId);
        // TODO; go directly to service to make this faster
        for (DiskInfo disk : getDisks()) {
            if (ArrayUtils.contains(disk.volumes, volId)) {
                return disk;
            }
        }
        return null;
    }

    /** {@hide} */
    public @Nullable VolumeInfo findVolumeById(String id) {
        Preconditions.checkNotNull(id);
@@ -486,6 +500,23 @@ public class StorageManager {
        }
    }

    /** {@hide} */
    public @Nullable String getBestVolumeDescription(String volId) {
        String descrip = null;

        final VolumeInfo vol = findVolumeById(volId);
        if (vol != null) {
            descrip = vol.getDescription();
        }

        final DiskInfo disk = findDiskByVolumeId(volId);
        if (disk != null && TextUtils.isEmpty(descrip)) {
            descrip = disk.getDescription();
        }

        return descrip;
    }

    /** {@hide} */
    public void mount(String volId) {
        try {
+11 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.mtp.MtpStorage;
import android.os.Environment;
import android.os.Parcel;
@@ -44,6 +45,8 @@ import java.io.File;
 * @hide
 */
public class VolumeInfo implements Parcelable {
    /** Stub volume representing internal private storage */
    public static final String ID_PRIVATE_INTERNAL = "private";
    /** Real volume representing internal emulated storage */
    public static final String ID_EMULATED_INTERNAL = "emulated";

@@ -59,6 +62,7 @@ public class VolumeInfo implements Parcelable {
    public static final int STATE_FORMATTING = 3;
    public static final int STATE_UNMOUNTING = 4;
    public static final int STATE_UNMOUNTABLE = 5;
    public static final int STATE_REMOVED = 6;

    public static final int FLAG_PRIMARY = 1 << 0;
    public static final int FLAG_VISIBLE = 1 << 1;
@@ -73,12 +77,14 @@ public class VolumeInfo implements Parcelable {
        sStateToEnvironment.put(VolumeInfo.STATE_FORMATTING, Environment.MEDIA_UNMOUNTED);
        sStateToEnvironment.put(VolumeInfo.STATE_UNMOUNTING, Environment.MEDIA_EJECTING);
        sStateToEnvironment.put(VolumeInfo.STATE_UNMOUNTABLE, Environment.MEDIA_UNMOUNTABLE);
        sStateToEnvironment.put(VolumeInfo.STATE_REMOVED, Environment.MEDIA_REMOVED);

        sEnvironmentToBroadcast.put(Environment.MEDIA_UNMOUNTED, Intent.ACTION_MEDIA_UNMOUNTED);
        sEnvironmentToBroadcast.put(Environment.MEDIA_CHECKING, Intent.ACTION_MEDIA_CHECKING);
        sEnvironmentToBroadcast.put(Environment.MEDIA_MOUNTED, Intent.ACTION_MEDIA_MOUNTED);
        sEnvironmentToBroadcast.put(Environment.MEDIA_EJECTING, Intent.ACTION_MEDIA_EJECT);
        sEnvironmentToBroadcast.put(Environment.MEDIA_UNMOUNTABLE, Intent.ACTION_MEDIA_UNMOUNTABLE);
        sEnvironmentToBroadcast.put(Environment.MEDIA_REMOVED, Intent.ACTION_MEDIA_REMOVED);
    }

    /** vold state */
@@ -96,8 +102,6 @@ public class VolumeInfo implements Parcelable {
    public final int mtpIndex;
    public String nickname;

    public DiskInfo disk;

    public VolumeInfo(String id, int type, int mtpIndex) {
        this.id = Preconditions.checkNotNull(id);
        this.type = type;
@@ -135,9 +139,9 @@ public class VolumeInfo implements Parcelable {
        return getBroadcastForEnvironment(getEnvironmentForState(state));
    }

    public String getDescription(Context context) {
        if (ID_EMULATED_INTERNAL.equals(id)) {
            return context.getString(com.android.internal.R.string.storage_internal);
    public @Nullable String getDescription() {
        if (ID_PRIVATE_INTERNAL.equals(id)) {
            return Resources.getSystem().getString(com.android.internal.R.string.storage_internal);
        } else if (!TextUtils.isEmpty(nickname)) {
            return nickname;
        } else if (!TextUtils.isEmpty(fsLabel)) {
@@ -189,7 +193,7 @@ public class VolumeInfo implements Parcelable {
            userPath = new File("/dev/null");
        }

        String description = getDescription(context);
        String description = getDescription();
        if (description == null) {
            description = context.getString(android.R.string.unknownName);
        }
@@ -283,7 +287,7 @@ public class VolumeInfo implements Parcelable {
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeString(id);
        parcel.writeInt(type);
        parcel.writeInt(flags);
        parcel.writeInt(this.flags);
        parcel.writeInt(userId);
        parcel.writeInt(state);
        parcel.writeString(fsType);
+3 −0
Original line number Diff line number Diff line
@@ -106,6 +106,9 @@ public final class DocumentsContract {
    /** {@hide} */
    public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";

    /** {@hide} */
    public static final String ACTION_BROWSE_ROOT = "android.provider.action.BROWSE_ROOT";

    /**
     * Buffer is large enough to rewind past any EXIF headers.
     */
+2 −0
Original line number Diff line number Diff line
@@ -69,7 +69,9 @@ public interface MetricsConstants {
    public static final int DEVELOPMENT = 39;
    public static final int DEVICEINFO = 40;
    public static final int DEVICEINFO_IMEI_INFORMATION = 41;
    @Deprecated
    public static final int DEVICEINFO_MEMORY = 42;
    public static final int DEVICEINFO_STORAGE = 42;
    public static final int DEVICEINFO_SIM_STATUS = 43;
    public static final int DEVICEINFO_STATUS = 44;
    public static final int DEVICEINFO_USB = 45;
Loading