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

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

Merge "Give secondary users read-only physical cards." into mnc-dev

parents 02022b70 46349876
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -80,7 +80,8 @@ public class Environment {
        }

        public File[] getExternalDirs() {
            final StorageVolume[] volumes = StorageManager.getVolumeList(mUserId);
            final StorageVolume[] volumes = StorageManager.getVolumeList(mUserId,
                    StorageManager.FLAG_FOR_WRITE);
            final File[] files = new File[volumes.length];
            for (int i = 0; i < volumes.length; i++) {
                files[i] = volumes[i].getPathFile();
+5 −3
Original line number Diff line number Diff line
@@ -758,7 +758,7 @@ public interface IMountService extends IInterface {
                return _result;
            }

            public StorageVolume[] getVolumeList(int uid, String packageName)
            public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
                    throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
@@ -767,6 +767,7 @@ public interface IMountService extends IInterface {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(uid);
                    _data.writeString(packageName);
                    _data.writeInt(flags);
                    mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.createTypedArray(StorageVolume.CREATOR);
@@ -1609,7 +1610,8 @@ public interface IMountService extends IInterface {
                    data.enforceInterface(DESCRIPTOR);
                    int uid = data.readInt();
                    String packageName = data.readString();
                    StorageVolume[] result = getVolumeList(uid, packageName);
                    int _flags = data.readInt();
                    StorageVolume[] result = getVolumeList(uid, packageName, _flags);
                    reply.writeNoException();
                    reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    return true;
@@ -2059,7 +2061,7 @@ public interface IMountService extends IInterface {
    /**
     * Returns list of all mountable volumes.
     */
    public StorageVolume[] getVolumeList(int uid, String packageName) throws RemoteException;
    public StorageVolume[] getVolumeList(int uid, String packageName, int flags) throws RemoteException;

    /**
     * Gets the path on the filesystem for the ASEC container itself.
+7 −4
Original line number Diff line number Diff line
@@ -86,6 +86,9 @@ public class StorageManager {
    /** {@hide} */
    public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;

    /** {@hide} */
    public static final int FLAG_FOR_WRITE = 1 << 0;

    private final Context mContext;
    private final ContentResolver mResolver;

@@ -812,7 +815,7 @@ public class StorageManager {

    /** {@hide} */
    public static @Nullable StorageVolume getStorageVolume(File file, int userId) {
        return getStorageVolume(getVolumeList(userId), file);
        return getStorageVolume(getVolumeList(userId, 0), file);
    }

    /** {@hide} */
@@ -852,11 +855,11 @@ public class StorageManager {

    /** {@hide} */
    public @NonNull StorageVolume[] getVolumeList() {
        return getVolumeList(mContext.getUserId());
        return getVolumeList(mContext.getUserId(), 0);
    }

    /** {@hide} */
    public static @NonNull StorageVolume[] getVolumeList(int userId) {
    public static @NonNull StorageVolume[] getVolumeList(int userId, int flags) {
        final IMountService mountService = IMountService.Stub.asInterface(
                ServiceManager.getService("mount"));
        try {
@@ -877,7 +880,7 @@ public class StorageManager {
            if (uid <= 0) {
                return new StorageVolume[0];
            }
            return mountService.getVolumeList(uid, packageName);
            return mountService.getVolumeList(uid, packageName, flags);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
+32 −3
Original line number Diff line number Diff line
@@ -46,6 +46,19 @@ import java.util.Objects;
 * Information about a storage volume that may be mounted. A volume may be a
 * partition on a physical {@link DiskInfo}, an emulated volume above some other
 * storage medium, or a standalone container like an ASEC or OBB.
 * <p>
 * Volumes may be mounted with various flags:
 * <ul>
 * <li>{@link #MOUNT_FLAG_PRIMARY} means the volume provides primary external
 * storage, historically found at {@code /sdcard}.
 * <li>{@link #MOUNT_FLAG_VISIBLE} means the volume is visible to third-party
 * apps for direct filesystem access. The system should send out relevant
 * storage broadcasts and index any media on visible volumes. Visible volumes
 * are considered a more stable part of the device, which is why we take the
 * time to index them. In particular, transient volumes like USB OTG devices
 * <em>should not</em> be marked as visible; their contents should be surfaced
 * to apps through the Storage Access Framework.
 * </ul>
 *
 * @hide
 */
@@ -255,8 +268,23 @@ public class VolumeInfo implements Parcelable {
        return (mountFlags & MOUNT_FLAG_VISIBLE) != 0;
    }

    public boolean isVisibleToUser(int userId) {
        if (type == TYPE_PUBLIC && userId == this.mountUserId) {
    public boolean isVisibleForRead(int userId) {
        if (type == TYPE_PUBLIC) {
            if (isPrimary() && mountUserId != userId) {
                // Primary physical is only visible to single user
                return false;
            } else {
                return isVisible();
            }
        } else if (type == TYPE_EMULATED) {
            return isVisible();
        } else {
            return false;
        }
    }

    public boolean isVisibleForWrite(int userId) {
        if (type == TYPE_PUBLIC && mountUserId == userId) {
            return isVisible();
        } else if (type == TYPE_EMULATED) {
            return isVisible();
@@ -276,7 +304,7 @@ public class VolumeInfo implements Parcelable {
    public File getPathForUser(int userId) {
        if (path == null) {
            return null;
        } else if (type == TYPE_PUBLIC && userId == this.mountUserId) {
        } else if (type == TYPE_PUBLIC) {
            return new File(path);
        } else if (type == TYPE_EMULATED) {
            return new File(path, Integer.toString(userId));
@@ -306,6 +334,7 @@ public class VolumeInfo implements Parcelable {
        final boolean allowMassStorage = false;
        final String envState = reportUnmounted
                ? Environment.MEDIA_UNMOUNTED : getEnvironmentForState(state);

        File userPath = getPathForUser(userId);
        if (userPath == null) {
            userPath = new File("/dev/null");
+6 −6
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ import android.os.storage.IMountServiceListener;
import android.os.storage.IMountShutdownObserver;
import android.os.storage.IObbActionListener;
import android.os.storage.MountServiceInternal;
import android.os.storage.MountServiceInternal.ExternalStorageMountPolicy;
import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageManager;
import android.os.storage.StorageResultCode;
@@ -809,7 +808,7 @@ class MountService extends IMountService.Stub
        synchronized (mVolumes) {
            for (int i = 0; i < mVolumes.size(); i++) {
                final VolumeInfo vol = mVolumes.valueAt(i);
                if (vol.isVisibleToUser(userId) && vol.isMountedReadable()) {
                if (vol.isVisibleForRead(userId) && vol.isMountedReadable()) {
                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
                    mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();

@@ -1252,7 +1251,7 @@ class MountService extends IMountService.Stub
            // started after this point will trigger additional
            // user-specific broadcasts.
            for (int userId : mStartedUsers) {
                if (vol.isVisibleToUser(userId)) {
                if (vol.isVisibleForRead(userId)) {
                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
                    mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();

@@ -2610,13 +2609,14 @@ class MountService extends IMountService.Stub
    }

    @Override
    public StorageVolume[] getVolumeList(int uid, String packageName) {
    public StorageVolume[] getVolumeList(int uid, String packageName, int flags) {
        final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0;

        final ArrayList<StorageVolume> res = new ArrayList<>();
        boolean foundPrimary = false;

        final int userId = UserHandle.getUserId(uid);
        final boolean reportUnmounted;

        final long identity = Binder.clearCallingIdentity();
        try {
            reportUnmounted = !mMountServiceInternal.hasExternalStorage(
@@ -2628,7 +2628,7 @@ class MountService extends IMountService.Stub
        synchronized (mLock) {
            for (int i = 0; i < mVolumes.size(); i++) {
                final VolumeInfo vol = mVolumes.valueAt(i);
                if (vol.isVisibleToUser(userId)) {
                if (forWrite ? vol.isVisibleForWrite(userId) : vol.isVisibleForRead(userId)) {
                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
                            reportUnmounted);
                    if (vol.isPrimary()) {