summaryrefslogtreecommitdiffstats
path: root/services
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 /services
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
Diffstat (limited to 'services')
-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
4 files changed, 149 insertions, 49 deletions
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