summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvet Ganov <svetoslavganov@google.com>2015-07-14 01:24:34 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-07-14 01:24:37 +0000
commit8cee6587e0efb2d8e63f1505b057a1e328525017 (patch)
tree18030af7a69474b903bfdd2b7705ad06e4a8dc4e
parent4b9b3e4731ffb962daf0f5029450001a8a6e7c00 (diff)
parent6ee871e59812fea4525c50231f677c4bd10c74b8 (diff)
downloadframeworks_base-8cee6587e0efb2d8e63f1505b057a1e328525017.zip
frameworks_base-8cee6587e0efb2d8e63f1505b057a1e328525017.tar.gz
frameworks_base-8cee6587e0efb2d8e63f1505b057a1e328525017.tar.bz2
Merge "Teach storage appops." into mnc-dev
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/os/storage/IMountService.java41
-rw-r--r--core/java/android/os/storage/MountServiceInternal.java82
-rw-r--r--core/java/android/os/storage/StorageManager.java14
-rw-r--r--core/java/android/os/storage/VolumeInfo.java6
-rw-r--r--services/core/java/com/android/server/AppOpsService.java30
-rw-r--r--services/core/java/com/android/server/MountService.java108
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java51
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