diff options
author | Svet Ganov <svetoslavganov@google.com> | 2015-07-14 01:24:34 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-07-14 01:24:37 +0000 |
commit | 8cee6587e0efb2d8e63f1505b057a1e328525017 (patch) | |
tree | 18030af7a69474b903bfdd2b7705ad06e4a8dc4e | |
parent | 4b9b3e4731ffb962daf0f5029450001a8a6e7c00 (diff) | |
parent | 6ee871e59812fea4525c50231f677c4bd10c74b8 (diff) | |
download | frameworks_base-8cee6587e0efb2d8e63f1505b057a1e328525017.zip frameworks_base-8cee6587e0efb2d8e63f1505b057a1e328525017.tar.gz frameworks_base-8cee6587e0efb2d8e63f1505b057a1e328525017.tar.bz2 |
Merge "Teach storage appops." into mnc-dev
9 files changed, 247 insertions, 97 deletions
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 103ee29..ceb610a 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -502,9 +502,6 @@ interface IPackageManager { void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); - - int getMountExternalMode(int uid); - void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId); boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId); diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 84a879c..c3b098b 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -758,13 +758,15 @@ public interface IMountService extends IInterface { return _result; } - public StorageVolume[] getVolumeList(int userId) throws RemoteException { + public StorageVolume[] getVolumeList(int uid, String packageName) + throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); StorageVolume[] _result; try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(userId); + _data.writeInt(uid); + _data.writeString(packageName); mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArray(StorageVolume.CREATOR); @@ -1177,21 +1179,6 @@ public interface IMountService extends IInterface { _data.recycle(); } } - - @Override - public void remountUid(int uid) throws RemoteException { - Parcel _data = Parcel.obtain(); - Parcel _reply = Parcel.obtain(); - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(uid); - mRemote.transact(Stub.TRANSACTION_remountUid, _data, _reply, 0); - _reply.readException(); - } finally { - _reply.recycle(); - _data.recycle(); - } - } } private static final String DESCRIPTOR = "IMountService"; @@ -1307,8 +1294,6 @@ public interface IMountService extends IInterface { static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59; static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60; - static final int TRANSACTION_remountUid = IBinder.FIRST_CALL_TRANSACTION + 61; - /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1622,8 +1607,9 @@ public interface IMountService extends IInterface { } case TRANSACTION_getVolumeList: { data.enforceInterface(DESCRIPTOR); - int userId = data.readInt(); - StorageVolume[] result = getVolumeList(userId); + int uid = data.readInt(); + String packageName = data.readString(); + StorageVolume[] result = getVolumeList(uid, packageName); reply.writeNoException(); reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; @@ -1862,13 +1848,6 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } - case TRANSACTION_remountUid: { - data.enforceInterface(DESCRIPTOR); - int uid = data.readInt(); - remountUid(uid); - reply.writeNoException(); - return true; - } } return super.onTransact(code, data, reply, flags); } @@ -2080,11 +2059,11 @@ public interface IMountService extends IInterface { /** * Returns list of all mountable volumes. */ - public StorageVolume[] getVolumeList(int userId) throws RemoteException; + public StorageVolume[] getVolumeList(int uid, String packageName) throws RemoteException; /** * Gets the path on the filesystem for the ASEC container itself. - * + * * @param cid ASEC container ID * @return path to filesystem or {@code null} if it's not found * @throws RemoteException @@ -2178,6 +2157,4 @@ public interface IMountService extends IInterface { public String getPrimaryStorageUuid() throws RemoteException; public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) throws RemoteException; - - public void remountUid(int uid) throws RemoteException; } diff --git a/core/java/android/os/storage/MountServiceInternal.java b/core/java/android/os/storage/MountServiceInternal.java new file mode 100644 index 0000000..17aaef9 --- /dev/null +++ b/core/java/android/os/storage/MountServiceInternal.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.storage; + +/** + * Mount service local interface. + * + * @hide Only for use within the system server. + */ +public abstract class MountServiceInternal { + + /** + * Policy that influences how external storage is mounted and reported. + */ + public interface ExternalStorageMountPolicy { + /** + * Gets the external storage mount mode for the given uid. + * + * @param uid The UID for which to determine mount mode. + * @param packageName The package in the UID for making the call. + * @return The mount mode. + * + * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_NONE + * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_DEFAULT + * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_READ + * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_WRITE + */ + public int getMountMode(int uid, String packageName); + + /** + * Gets whether external storage should be reported to the given UID. + * + * @param uid The UID for which to determine whether it has external storage. + * @param packageName The package in the UID for making the call. + * @return Weather to report external storage. + * @return True to report the state of external storage, false to + * report it as unmounted. + */ + public boolean hasExternalStorage(int uid, String packageName); + } + + /** + * Adds a policy for determining how external storage is mounted and reported. + * The mount mode is the most conservative result from querying all registered + * policies. Similarly, the reported state is the most conservative result from + * querying all registered policies. + * + * @param policy The policy to add. + */ + public abstract void addExternalStoragePolicy(ExternalStorageMountPolicy policy); + + /** + * Notify the mount service that the mount policy for a UID changed. + * @param uid The UID for which policy changed. + * @param packageName The package in the UID for making the call. + */ + public abstract void onExternalStoragePolicyChanged(int uid, String packageName); + + /** + * Gets the mount mode to use for a given UID as determined by consultin all + * policies. + * + * @param uid The UID for which to get mount mode. + * @param packageName The package in the UID for making the call. + * @return The mount mode. + */ + public abstract int getExternalStorageMountMode(int uid, String packageName); +} diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index f03e04e..140f317 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -20,6 +20,7 @@ import static android.net.TrafficStats.MB_IN_BYTES; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityThread; import android.content.ContentResolver; import android.content.Context; import android.content.pm.IPackageMoveObserver; @@ -857,7 +858,9 @@ public class StorageManager { final IMountService mountService = IMountService.Stub.asInterface( ServiceManager.getService("mount")); try { - return mountService.getVolumeList(userId); + final String packageName = ActivityThread.currentOpPackageName(); + final int uid = ActivityThread.getPackageManager().getPackageUid(packageName, userId); + return mountService.getVolumeList(uid, packageName); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } @@ -894,15 +897,6 @@ public class StorageManager { } /** {@hide} */ - public void remountUid(int uid) { - try { - mMountService.remountUid(uid); - } catch (RemoteException e) { - throw e.rethrowAsRuntimeException(); - } - } - - /** {@hide} */ private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10; private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES; private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES; diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 32f7bc9..8d603a1 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -298,14 +298,14 @@ public class VolumeInfo implements Parcelable { } } - public StorageVolume buildStorageVolume(Context context, int userId) { + public StorageVolume buildStorageVolume(Context context, int userId, boolean reportUnmounted) { final StorageManager storage = context.getSystemService(StorageManager.class); final boolean removable; final boolean emulated; final boolean allowMassStorage = false; - final String envState = getEnvironmentForState(state); - + final String envState = reportUnmounted + ? Environment.MEDIA_UNMOUNTED : getEnvironmentForState(state); File userPath = getPathForUser(userId); if (userPath == null) { userPath = new File("/dev/null"); diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index f0fc399..417f18d 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -48,6 +48,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.os.storage.MountServiceInternal; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; @@ -60,6 +61,7 @@ import android.util.Xml; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsCallback; +import com.android.internal.os.Zygote; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; @@ -245,6 +247,34 @@ public class AppOpsService extends IAppOpsService.Stub { scheduleFastWriteLocked(); } } + + MountServiceInternal mountServiceInternal = LocalServices.getService( + MountServiceInternal.class); + mountServiceInternal.addExternalStoragePolicy( + new MountServiceInternal.ExternalStorageMountPolicy() { + @Override + public int getMountMode(int uid, String packageName) { + if (Process.isIsolated(uid)) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid, + packageName) != AppOpsManager.MODE_ALLOWED) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid, + packageName) != AppOpsManager.MODE_ALLOWED) { + return Zygote.MOUNT_EXTERNAL_READ; + } + return Zygote.MOUNT_EXTERNAL_WRITE; + } + + @Override + public boolean hasExternalStorage(int uid, String packageName) { + final int mountMode = getMountMode(uid, packageName); + return mountMode == Zygote.MOUNT_EXTERNAL_READ + || mountMode == Zygote.MOUNT_EXTERNAL_WRITE; + } + }); } public void packageRemoved(int uid, String packageName) { diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index da552dd..bc61c3d 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -68,6 +68,8 @@ import android.os.storage.IMountService; 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; @@ -127,6 +129,7 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -307,16 +310,6 @@ class MountService extends IMountService.Stub @GuardedBy("mLock") private String mMoveTargetUuid; - private DiskInfo findDiskById(String id) { - synchronized (mLock) { - final DiskInfo disk = mDisks.get(id); - if (disk != null) { - return disk; - } - } - throw new IllegalArgumentException("No disk found for ID " + id); - } - private VolumeInfo findVolumeByIdOrThrow(String id) { synchronized (mLock) { final VolumeInfo vol = mVolumes.get(id); @@ -456,6 +449,9 @@ class MountService extends IMountService.Stub /** Map from raw paths to {@link ObbState}. */ final private Map<String, ObbState> mObbPathToStateMap = new HashMap<String, ObbState>(); + // Not guarded by a lock. + private final MountServiceInternalImpl mMountServiceInternal = new MountServiceInternalImpl(); + class ObbState implements IBinder.DeathRecipient { public ObbState(String rawPath, String canonicalPath, int callingUid, IObbActionListener token, int nonce) { @@ -807,7 +803,7 @@ class MountService extends IMountService.Stub for (int i = 0; i < mVolumes.size(); i++) { final VolumeInfo vol = mVolumes.valueAt(i); if (vol.isVisibleToUser(userId) && vol.isMountedReadable()) { - final StorageVolume userVol = vol.buildStorageVolume(mContext, userId); + final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false); mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget(); final String envState = VolumeInfo.getEnvironmentForState(vol.getState()); @@ -1250,7 +1246,7 @@ class MountService extends IMountService.Stub // user-specific broadcasts. for (int userId : mStartedUsers) { if (vol.isVisibleToUser(userId)) { - final StorageVolume userVol = vol.buildStorageVolume(mContext, userId); + final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false); mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget(); mCallbacks.notifyStorageStateChanged(userVol.getPath(), oldStateEnv, @@ -1370,6 +1366,8 @@ class MountService extends IMountService.Stub readSettingsLocked(); } + LocalServices.addService(MountServiceInternal.class, mMountServiceInternal); + /* * Create the connection to vold with a maximum queue of twice the * amount of containers we'd ever expect to have. This keeps an @@ -1787,27 +1785,28 @@ class MountService extends IMountService.Stub } } - @Override - public void remountUid(int uid) { - enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); + private void remountUidExternalStorage(int uid, int mode) { waitForReady(); - final int mountExternal = mPms.getMountExternalMode(uid); - final String mode; - if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) { - mode = "default"; - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) { - mode = "read"; - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) { - mode = "write"; - } else { - mode = "none"; + String modeName = "none"; + switch (mode) { + case Zygote.MOUNT_EXTERNAL_DEFAULT: { + modeName = "default"; + } break; + + case Zygote.MOUNT_EXTERNAL_READ: { + modeName = "read"; + } break; + + case Zygote.MOUNT_EXTERNAL_WRITE: { + modeName = "write"; + } break; } try { - mConnector.execute("volume", "remount_uid", uid, mode); + mConnector.execute("volume", "remount_uid", uid, modeName); } catch (NativeDaemonConnectorException e) { - Slog.w(TAG, "Failed to remount UID " + uid + " as " + mode + ": " + e); + Slog.w(TAG, "Failed to remount UID " + uid + " as " + modeName + ": " + e); } } @@ -2598,15 +2597,20 @@ class MountService extends IMountService.Stub } @Override - public StorageVolume[] getVolumeList(int userId) { + public StorageVolume[] getVolumeList(int uid, String packageName) { final ArrayList<StorageVolume> res = new ArrayList<>(); boolean foundPrimary = false; + final int userId = UserHandle.getUserId(uid); + final boolean reportUnmounted = !mMountServiceInternal.hasExternalStorage( + uid, packageName); + synchronized (mLock) { for (int i = 0; i < mVolumes.size(); i++) { final VolumeInfo vol = mVolumes.valueAt(i); if (vol.isVisibleToUser(userId)) { - final StorageVolume userVol = vol.buildStorageVolume(mContext, userId); + final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, + reportUnmounted); if (vol.isPrimary()) { res.add(0, userVol); foundPrimary = true; @@ -3379,4 +3383,50 @@ class MountService extends IMountService.Stub mCryptConnector.monitor(); } } + + private final class MountServiceInternalImpl extends MountServiceInternal { + // Not guarded by a lock. + private final CopyOnWriteArrayList<ExternalStorageMountPolicy> mPolicies = + new CopyOnWriteArrayList<>(); + + @Override + public void addExternalStoragePolicy(ExternalStorageMountPolicy policy) { + // No locking - CopyOnWriteArrayList + mPolicies.add(policy); + } + + @Override + public void onExternalStoragePolicyChanged(int uid, String packageName) { + final int mountMode = getExternalStorageMountMode(uid, packageName); + remountUidExternalStorage(uid, mountMode); + } + + @Override + public int getExternalStorageMountMode(int uid, String packageName) { + // No locking - CopyOnWriteArrayList + int mountMode = Integer.MAX_VALUE; + for (ExternalStorageMountPolicy policy : mPolicies) { + final int policyMode = policy.getMountMode(uid, packageName); + if (policyMode == Zygote.MOUNT_EXTERNAL_NONE) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + mountMode = Math.min(mountMode, policyMode); + } + if (mountMode == Integer.MAX_VALUE) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + return mountMode; + } + + public boolean hasExternalStorage(int uid, String packageName) { + // No locking - CopyOnWriteArrayList + for (ExternalStorageMountPolicy policy : mPolicies) { + final boolean policyHasStorage = policy.hasExternalStorage(uid, packageName); + if (!policyHasStorage) { + return false; + } + } + return true; + } + } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 6e94647..5bfca10 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -18,7 +18,10 @@ package com.android.server.am; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; +import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; +import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; +import static android.Manifest.permission.WRITE_MEDIA_STORAGE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; @@ -62,6 +65,7 @@ import android.os.Trace; import android.os.TransactionTooLargeException; import android.os.WorkSource; import android.os.storage.IMountService; +import android.os.storage.MountServiceInternal; import android.os.storage.StorageManager; import android.service.voice.IVoiceInteractionSession; import android.util.ArrayMap; @@ -3219,7 +3223,10 @@ public final class ActivityManagerService extends ActivityManagerNative checkTime(startTime, "startProcess: getting gids from package manager"); final IPackageManager pm = AppGlobals.getPackageManager(); permGids = pm.getPackageGids(app.info.packageName, app.userId); - mountExternal = pm.getMountExternalMode(uid); + MountServiceInternal mountServiceInternal = LocalServices.getService( + MountServiceInternal.class); + mountExternal = mountServiceInternal.getExternalStorageMountMode(uid, + app.info.packageName); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index bf250ce..24f3f7f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -62,6 +62,7 @@ import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; +import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageParser.isApkFile; import static android.os.Process.PACKAGE_INFO_GID; @@ -165,6 +166,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.IMountService; +import android.os.storage.MountServiceInternal; import android.os.storage.StorageEventListener; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; @@ -2726,23 +2728,6 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } - @Override - public int getMountExternalMode(int uid) { - if (Process.isIsolated(uid)) { - return Zygote.MOUNT_EXTERNAL_NONE; - } else { - if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { - return Zygote.MOUNT_EXTERNAL_DEFAULT; - } else if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) { - return Zygote.MOUNT_EXTERNAL_WRITE; - } else if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) { - return Zygote.MOUNT_EXTERNAL_READ; - } else { - return Zygote.MOUNT_EXTERNAL_DEFAULT; - } - } - } - static PermissionInfo generatePermissionInfo( BasePermission bp, int flags) { if (bp.perm != null) { @@ -3465,8 +3450,9 @@ public class PackageManagerService extends IPackageManager.Stub { final long token = Binder.clearCallingIdentity(); try { if (sUserManager.isInitialized(userId)) { - final StorageManager storage = mContext.getSystemService(StorageManager.class); - storage.remountUid(uid); + MountServiceInternal mountServiceInternal = LocalServices.getService( + MountServiceInternal.class); + mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); } } finally { Binder.restoreCallingIdentity(token); @@ -14466,6 +14452,33 @@ public class PackageManagerService extends IPackageManager.Stub { mInstallerService.systemReady(); mPackageDexOptimizer.systemReady(); + + MountServiceInternal mountServiceInternal = LocalServices.getService( + MountServiceInternal.class); + mountServiceInternal.addExternalStoragePolicy( + new MountServiceInternal.ExternalStorageMountPolicy() { + @Override + public int getMountMode(int uid, String packageName) { + if (Process.isIsolated(uid)) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { + return Zygote.MOUNT_EXTERNAL_DEFAULT; + } + if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { + return Zygote.MOUNT_EXTERNAL_DEFAULT; + } + if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { + return Zygote.MOUNT_EXTERNAL_READ; + } + return Zygote.MOUNT_EXTERNAL_WRITE; + } + + @Override + public boolean hasExternalStorage(int uid, String packageName) { + return true; + } + }); } @Override |