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

Commit 56bd3129 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Checkpoint of storage notifications.

Rewrite of storage notifications to support multiple disks/volumes,
handling the state of each independently.  Update strings to match
spec.  Include actions to jump into wizard when adoptable, otherwise
browse or eject.

Move browse intent creation to common place on VolumeInfo.  Also add
well-formed extra names.  VolumeInfo now carries the parent disk ID
along with it to avoid races when unmounting.

Bug: 19993667
Change-Id: I236ddc7f8112490355f438b828bec8d40c331fdd
parent d1500d8f
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import java.io.CharArrayWriter;
 * @hide
 */
public class DiskInfo implements Parcelable {
    public static final String EXTRA_DISK_ID = "android.os.storage.extra.DISK_ID";

    public static final int FLAG_ADOPTABLE = 1 << 0;
    public static final int FLAG_DEFAULT_PRIMARY = 1 << 1;
    public static final int FLAG_SD = 1 << 2;
@@ -42,7 +44,7 @@ public class DiskInfo implements Parcelable {
    public final int flags;
    public long size;
    public String label;
    public String[] volumes;
    public String[] volumeIds;

    public DiskInfo(String id, int flags) {
        this.id = Preconditions.checkNotNull(id);
@@ -54,7 +56,7 @@ public class DiskInfo implements Parcelable {
        flags = parcel.readInt();
        size = parcel.readLong();
        label = parcel.readString();
        volumes = parcel.readStringArray();
        volumeIds = parcel.readStringArray();
    }

    public String getDescription() {
@@ -68,6 +70,18 @@ public class DiskInfo implements Parcelable {
        }
    }

    public boolean isSd() {
        return (flags & FLAG_SD) != 0;
    }

    public boolean isUsb() {
        return (flags & FLAG_USB) != 0;
    }

    public boolean isAdoptable() {
        return (flags & FLAG_ADOPTABLE) != 0;
    }

    @Override
    public String toString() {
        final CharArrayWriter writer = new CharArrayWriter();
@@ -82,7 +96,7 @@ public class DiskInfo implements Parcelable {
        pw.printPair("flags", DebugUtils.flagsToString(getClass(), "FLAG_", flags));
        pw.printPair("size", size);
        pw.printPair("label", label);
        pw.printPair("volumes", volumes);
        pw.printPair("volumeIds", volumeIds);
        pw.decreaseIndent();
        pw.println();
    }
@@ -122,6 +136,6 @@ public class DiskInfo implements Parcelable {
        parcel.writeInt(this.flags);
        parcel.writeLong(size);
        parcel.writeString(label);
        parcel.writeStringArray(volumes);
        parcel.writeStringArray(volumeIds);
    }
}
+7 −23
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ 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;
@@ -455,18 +454,6 @@ 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);
@@ -501,18 +488,15 @@ public class StorageManager {
    }

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

        final VolumeInfo vol = findVolumeById(volId);
        if (vol != null) {
            descrip = vol.getDescription();
        }
    public @Nullable String getBestVolumeDescription(VolumeInfo vol) {
        String descrip = vol.getDescription();

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

        return descrip;
    }
+37 −0
Original line number Diff line number Diff line
@@ -22,10 +22,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.mtp.MtpStorage;
import android.net.Uri;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DebugUtils;
@@ -45,6 +47,8 @@ import java.io.File;
 * @hide
 */
public class VolumeInfo implements Parcelable {
    public static final String EXTRA_VOLUME_ID = "android.os.storage.extra.VOLUME_ID";

    /** Stub volume representing internal private storage */
    public static final String ID_PRIVATE_INTERNAL = "private";
    /** Real volume representing internal emulated storage */
@@ -101,6 +105,7 @@ public class VolumeInfo implements Parcelable {
    /** Framework state */
    public final int mtpIndex;
    public String nickname;
    public String diskId;

    public VolumeInfo(String id, int type, int mtpIndex) {
        this.id = Preconditions.checkNotNull(id);
@@ -120,6 +125,7 @@ public class VolumeInfo implements Parcelable {
        path = parcel.readString();
        mtpIndex = parcel.readInt();
        nickname = parcel.readString();
        diskId = parcel.readString();
    }

    public static @NonNull String getEnvironmentForState(int state) {
@@ -228,6 +234,34 @@ public class VolumeInfo implements Parcelable {
                fsUuid, envState);
    }

    // TODO: avoid this layering violation
    private static final String DOCUMENT_AUTHORITY = "com.android.externalstorage.documents";
    private static final String DOCUMENT_ROOT_PRIMARY_EMULATED = "primary";

    /**
     * Build an intent to browse the contents of this volume. Only valid for
     * {@link #TYPE_EMULATED} or {@link #TYPE_PUBLIC}.
     */
    public Intent buildBrowseIntent() {
        final Uri uri;
        if (type == VolumeInfo.TYPE_PUBLIC) {
            uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid);
        } else if (VolumeInfo.ID_EMULATED_INTERNAL.equals(id)) {
            uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY,
                    DOCUMENT_ROOT_PRIMARY_EMULATED);
        } else if (type == VolumeInfo.TYPE_EMULATED) {
            // TODO: build intent once supported
            uri = null;
        } else {
            throw new IllegalArgumentException();
        }

        final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(uri);
        return intent;
    }

    @Override
    public String toString() {
        final CharArrayWriter writer = new CharArrayWriter();
@@ -250,6 +284,8 @@ public class VolumeInfo implements Parcelable {
        pw.println();
        pw.printPair("path", path);
        pw.printPair("mtpIndex", mtpIndex);
        pw.printPair("nickname", nickname);
        pw.printPair("diskId", diskId);
        pw.decreaseIndent();
        pw.println();
    }
@@ -296,5 +332,6 @@ public class VolumeInfo implements Parcelable {
        parcel.writeString(path);
        parcel.writeInt(mtpIndex);
        parcel.writeString(nickname);
        parcel.writeString(diskId);
    }
}
+38 −45
Original line number Diff line number Diff line
@@ -2878,51 +2878,44 @@
    <string name="candidates_style"><u>candidates</u></string>

    <!-- External media notification strings -->
    <!-- Shown when external media is being checked [CHAR LIMIT=30] -->
    <string name="ext_media_checking_notification_title" product="nosdcard">Preparing USB storage</string>
    <!-- Shown when external media is being checked -->
    <string name="ext_media_checking_notification_title" product="default">Preparing SD card</string>
    <string name="ext_media_checking_notification_message">Checking for errors.</string>

    <!-- Shown when external media is blank (or unsupported filesystem) [CHAR LIMIT=30] -->
    <string name="ext_media_nofs_notification_title" product="nosdcard">Blank USB storage</string>
    <!-- Shown when external media is blank (or unsupported filesystem) -->
    <string name="ext_media_nofs_notification_title" product="default">Blank SD card</string>
    <!-- Shown when USB storage cannot be read.  [CHAR LIMIT=NONE] -->
    <string name="ext_media_nofs_notification_message" product="nosdcard">USB storage is blank or has unsupported filesystem.</string>
    <string name="ext_media_nofs_notification_message" product="default">SD card is blank or has unsupported filesystem.</string>

    <!-- Shown when external media is unmountable (corrupt)) [CHAR LIMIT=30] -->
    <string name="ext_media_unmountable_notification_title" product="nosdcard">Damaged USB storage</string>
    <!-- Shown when external media is unmountable (corrupt)) -->
    <string name="ext_media_unmountable_notification_title" product="default">Damaged SD card</string>
    <!-- Shown when USB storage cannot be read.  [CHAR LIMIT=NONE] -->
    <string name="ext_media_unmountable_notification_message" product="nosdcard">USB storage is damaged. Try reformatting it.</string>
    <string name="ext_media_unmountable_notification_message" product="default">SD card is damaged. Try reformatting it.</string>

    <!-- Shown when external media is unsafely removed [CHAR LIMIT=30] -->
    <string name="ext_media_badremoval_notification_title" product="nosdcard">USB storage unexpectedly removed</string>
    <!-- Shown when external media is unsafely removed -->
    <string name="ext_media_badremoval_notification_title" product="default">SD card unexpectedly removed</string>
    <!-- Shown when external media is unsafely removed.  [CHAR LIMIT=NONE] -->
    <string name="ext_media_badremoval_notification_message" product="nosdcard">Unmount USB storage before removing to avoid data loss.</string>
    <string name="ext_media_badremoval_notification_message" product="default">Unmount SD card before removing to avoid data loss.</string>

    <!-- Shown when external media has been safely removed [CHAR LIMIT=30] -->
    <string name="ext_media_safe_unmount_notification_title" product="nosdcard">USB storage safe to remove</string>
    <!-- Shown when external media has been safely removed -->
    <string name="ext_media_safe_unmount_notification_title" product="default">SD card safe to remove</string>
    <!-- Shown when external media has been safely removed.  [CHAR LIMIT=NONE] -->
    <string name="ext_media_safe_unmount_notification_message" product="nosdcard">You can safely remove USB storage.</string>
    <string name="ext_media_safe_unmount_notification_message" product="default">You can safely remove SD card.</string>

    <!-- Shown when external media is missing [CHAR LIMIT=30] -->
    <string name="ext_media_nomedia_notification_title" product="nosdcard">Removed USB storage</string>
    <!-- Shown when external media is missing -->
    <string name="ext_media_nomedia_notification_title" product="default">Removed SD card</string>
    <!-- Shown when external media is missing.  [CHAR LIMIT=NONE] -->
    <string name="ext_media_nomedia_notification_message" product="nosdcard">USB storage removed. Insert new media.</string>
    <string name="ext_media_nomedia_notification_message" product="default">SD card removed. Insert a new one.</string>
    <skip />

    <!-- Notification title when external media is being checked [CHAR LIMIT=30] -->
    <string name="ext_media_checking_notification_title">Preparing <xliff:g id="name" example="SD card">%s</xliff:g></string>
    <!-- Notification body when external media is being checked [CHAR LIMIT=NONE] -->
    <string name="ext_media_checking_notification_message">Checking for errors</string>

    <!-- Notification body when new external media is detected [CHAR LIMIT=NONE] -->
    <string name="ext_media_new_notification_message">New <xliff:g id="name" example="SD card">%s</xliff:g> detected</string>
    <!-- Notification body when external media is ready for use [CHAR LIMIT=NONE] -->
    <string name="ext_media_ready_notification_message">For transferring photos and media</string>

    <!-- Notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] -->
    <string name="ext_media_unmountable_notification_title">Damaged <xliff:g id="name" example="SD card">%s</xliff:g></string>
    <!-- Notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
    <string name="ext_media_unmountable_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> is damaged; try reformatting it</string>

    <!-- Notification title when external media is unsafely removed [CHAR LIMIT=30] -->
    <string name="ext_media_badremoval_notification_title"><xliff:g id="name" example="SD card">%s</xliff:g> unexpectedly removed</string>
    <!-- Notification body when external media is unsafely removed [CHAR LIMIT=NONE] -->
    <string name="ext_media_badremoval_notification_message">Unmount <xliff:g id="name" example="SD card">%s</xliff:g> before removing to avoid data loss</string>

    <!-- Notification title when external media is missing [CHAR LIMIT=30] -->
    <string name="ext_media_nomedia_notification_title">Removed <xliff:g id="name" example="SD card">%s</xliff:g></string>
    <!-- Notification body when external media is missing [CHAR LIMIT=NONE] -->
    <string name="ext_media_nomedia_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> removed; insert a new one</string>

    <!-- Notification title when external media is unmounting [CHAR LIMIT=30] -->
    <string name="ext_media_unmounting_notification_title">Still ejecting <xliff:g id="name" example="SD card">%s</xliff:g>\u2026</string>
    <!-- Notification body when external media is unmounting [CHAR LIMIT=NONE] -->
    <string name="ext_media_unmounting_notification_message">Don\'t remove</string>

    <!-- Notification action to setup external media [CHAR LIMIT=20] -->
    <string name="ext_media_init_action">Setup</string>
    <!-- Notification action to unmount external media [CHAR LIMIT=20] -->
    <string name="ext_media_unmount_action">Eject</string>
    <!-- Notification action to browse external media [CHAR LIMIT=20] -->
    <string name="ext_media_browse_action">Explore</string>

    <!-- Shown in LauncherActivity when the requested target Intent didn't return any matching Activities, leaving the list empty. -->
    <string name="activity_list_empty">No matching activities found.</string>
+7 −4
Original line number Diff line number Diff line
@@ -1886,14 +1886,17 @@
  <java-symbol type="string" name="ext_media_badremoval_notification_title" />
  <java-symbol type="string" name="ext_media_checking_notification_message" />
  <java-symbol type="string" name="ext_media_checking_notification_title" />
  <java-symbol type="string" name="ext_media_nofs_notification_message" />
  <java-symbol type="string" name="ext_media_nofs_notification_title" />
  <java-symbol type="string" name="ext_media_nomedia_notification_message" />
  <java-symbol type="string" name="ext_media_nomedia_notification_title" />
  <java-symbol type="string" name="ext_media_safe_unmount_notification_message" />
  <java-symbol type="string" name="ext_media_safe_unmount_notification_title" />
  <java-symbol type="string" name="ext_media_unmountable_notification_message" />
  <java-symbol type="string" name="ext_media_unmountable_notification_title" />
  <java-symbol type="string" name="ext_media_unmounting_notification_message" />
  <java-symbol type="string" name="ext_media_unmounting_notification_title" />
  <java-symbol type="string" name="ext_media_new_notification_message" />
  <java-symbol type="string" name="ext_media_ready_notification_message" />
  <java-symbol type="string" name="ext_media_init_action" />
  <java-symbol type="string" name="ext_media_unmount_action" />
  <java-symbol type="string" name="ext_media_browse_action" />
  <java-symbol type="string" name="usb_storage_error_message" />
  <java-symbol type="string" name="usb_storage_message" />
  <java-symbol type="string" name="usb_storage_notification_message" />
Loading