am d2c41457
: Merge "Let\'s reinvent storage, yet again!" into mnc-dev
* commit 'd2c414573242fc59a2d34f66f1dfb610ec7d59a3': Let's reinvent storage, yet again!
This commit is contained in:
@ -504,4 +504,5 @@ interface IPackageManager {
|
|||||||
|
|
||||||
void grantDefaultPermissions(int userId);
|
void grantDefaultPermissions(int userId);
|
||||||
void setCarrierAppPackagesProvider(in IPackagesProvider provider);
|
void setCarrierAppPackagesProvider(in IPackagesProvider provider);
|
||||||
|
int getMountExternalMode(int uid);
|
||||||
}
|
}
|
||||||
|
@ -643,6 +643,10 @@ public class Process {
|
|||||||
}
|
}
|
||||||
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
|
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
|
||||||
argsForZygote.add("--mount-external-default");
|
argsForZygote.add("--mount-external-default");
|
||||||
|
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
|
||||||
|
argsForZygote.add("--mount-external-read");
|
||||||
|
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
|
||||||
|
argsForZygote.add("--mount-external-write");
|
||||||
}
|
}
|
||||||
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
|
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
|
||||||
|
|
||||||
@ -802,7 +806,12 @@ public class Process {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final boolean isIsolated() {
|
public static final boolean isIsolated() {
|
||||||
int uid = UserHandle.getAppId(myUid());
|
return isIsolated(myUid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public static final boolean isIsolated(int uid) {
|
||||||
|
uid = UserHandle.getAppId(uid);
|
||||||
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
|
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,6 +1177,21 @@ public interface IMountService extends IInterface {
|
|||||||
_data.recycle();
|
_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";
|
private static final String DESCRIPTOR = "IMountService";
|
||||||
@ -1292,6 +1307,8 @@ public interface IMountService extends IInterface {
|
|||||||
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
|
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
|
||||||
static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
|
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
|
* Cast an IBinder object into an IMountService interface, generating a
|
||||||
* proxy if needed.
|
* proxy if needed.
|
||||||
@ -1845,6 +1862,13 @@ public interface IMountService extends IInterface {
|
|||||||
reply.writeNoException();
|
reply.writeNoException();
|
||||||
return true;
|
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);
|
return super.onTransact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
@ -2154,4 +2178,6 @@ public interface IMountService extends IInterface {
|
|||||||
public String getPrimaryStorageUuid() throws RemoteException;
|
public String getPrimaryStorageUuid() throws RemoteException;
|
||||||
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
|
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
|
||||||
throws RemoteException;
|
throws RemoteException;
|
||||||
|
|
||||||
|
public void remountUid(int uid) throws RemoteException;
|
||||||
}
|
}
|
||||||
|
@ -870,6 +870,15 @@ public class StorageManager {
|
|||||||
throw new IllegalStateException("Missing primary storage");
|
throw new IllegalStateException("Missing primary storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public void remountUid(int uid) {
|
||||||
|
try {
|
||||||
|
mMountService.remountUid(uid);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowAsRuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
|
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_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
|
||||||
|
@ -46,8 +46,12 @@ public final class Zygote {
|
|||||||
|
|
||||||
/** No external storage should be mounted. */
|
/** No external storage should be mounted. */
|
||||||
public static final int MOUNT_EXTERNAL_NONE = 0;
|
public static final int MOUNT_EXTERNAL_NONE = 0;
|
||||||
/** Default user-specific external storage should be mounted. */
|
/** Default external storage should be mounted. */
|
||||||
public static final int MOUNT_EXTERNAL_DEFAULT = 1;
|
public static final int MOUNT_EXTERNAL_DEFAULT = 1;
|
||||||
|
/** Read-only external storage should be mounted. */
|
||||||
|
public static final int MOUNT_EXTERNAL_READ = 2;
|
||||||
|
/** Read-write external storage should be mounted. */
|
||||||
|
public static final int MOUNT_EXTERNAL_WRITE = 3;
|
||||||
|
|
||||||
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
|
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
|
||||||
|
|
||||||
|
@ -519,6 +519,10 @@ class ZygoteConnection {
|
|||||||
niceName = arg.substring(arg.indexOf('=') + 1);
|
niceName = arg.substring(arg.indexOf('=') + 1);
|
||||||
} else if (arg.equals("--mount-external-default")) {
|
} else if (arg.equals("--mount-external-default")) {
|
||||||
mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
|
mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
|
||||||
|
} else if (arg.equals("--mount-external-read")) {
|
||||||
|
mountExternal = Zygote.MOUNT_EXTERNAL_READ;
|
||||||
|
} else if (arg.equals("--mount-external-write")) {
|
||||||
|
mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
|
||||||
} else if (arg.equals("--query-abi-list")) {
|
} else if (arg.equals("--query-abi-list")) {
|
||||||
abiListQuery = true;
|
abiListQuery = true;
|
||||||
} else if (arg.startsWith("--instruction-set=")) {
|
} else if (arg.startsWith("--instruction-set=")) {
|
||||||
|
@ -66,6 +66,8 @@ static jmethodID gCallPostForkChildHooks;
|
|||||||
enum MountExternalKind {
|
enum MountExternalKind {
|
||||||
MOUNT_EXTERNAL_NONE = 0,
|
MOUNT_EXTERNAL_NONE = 0,
|
||||||
MOUNT_EXTERNAL_DEFAULT = 1,
|
MOUNT_EXTERNAL_DEFAULT = 1,
|
||||||
|
MOUNT_EXTERNAL_READ = 2,
|
||||||
|
MOUNT_EXTERNAL_WRITE = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void RuntimeAbort(JNIEnv* env) {
|
static void RuntimeAbort(JNIEnv* env) {
|
||||||
@ -249,38 +251,49 @@ static void SetSchedulerPolicy(JNIEnv* env) {
|
|||||||
|
|
||||||
// Create a private mount namespace and bind mount appropriate emulated
|
// Create a private mount namespace and bind mount appropriate emulated
|
||||||
// storage for the given user.
|
// storage for the given user.
|
||||||
static bool MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace) {
|
static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
|
||||||
if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
|
bool force_mount_namespace) {
|
||||||
|
// See storage config details at http://source.android.com/tech/storage/
|
||||||
|
|
||||||
|
// Create a second private mount namespace for our process
|
||||||
|
if (unshare(CLONE_NEWNS) == -1) {
|
||||||
|
ALOGW("Failed to unshare(): %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmount storage provided by root namespace and mount requested view
|
||||||
|
umount2("/storage", MNT_FORCE);
|
||||||
|
|
||||||
|
String8 storageSource;
|
||||||
|
if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
|
||||||
|
storageSource = "/mnt/runtime_default";
|
||||||
|
} else if (mount_mode == MOUNT_EXTERNAL_READ) {
|
||||||
|
storageSource = "/mnt/runtime_read";
|
||||||
|
} else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
|
||||||
|
storageSource = "/mnt/runtime_write";
|
||||||
|
} else {
|
||||||
|
// Sane default of no storage visible
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
|
||||||
|
NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
|
||||||
|
ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount user-specific symlink helpers into place
|
||||||
|
userid_t user_id = multiuser_get_user_id(uid);
|
||||||
|
const String8 userSource(String8::format("/mnt/user/%d", user_id));
|
||||||
|
if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
|
||||||
|
NULL, MS_BIND, NULL)) == -1) {
|
||||||
|
ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// Create a second private mount namespace for our process
|
|
||||||
if (unshare(CLONE_NEWNS) == -1) {
|
|
||||||
ALOGW("Failed to unshare(): %s", strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mount_mode == MOUNT_EXTERNAL_NONE) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See storage config details at http://source.android.com/tech/storage/
|
|
||||||
userid_t user_id = multiuser_get_user_id(uid);
|
|
||||||
|
|
||||||
// Bind mount user-specific storage into place
|
|
||||||
const String8 source(String8::format("/mnt/user/%d", user_id));
|
|
||||||
const String8 target(String8::format("/storage/self"));
|
|
||||||
|
|
||||||
if (fs_prepare_dir(source.string(), 0755, 0, 0) == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TEMP_FAILURE_RETRY(mount(source.string(), target.string(), NULL, MS_BIND, NULL)) == -1) {
|
|
||||||
ALOGW("Failed to mount %s to %s: %s", source.string(), target.string(), strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool NeedsNoRandomizeWorkaround() {
|
static bool NeedsNoRandomizeWorkaround() {
|
||||||
@ -543,7 +556,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
|
|||||||
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
|
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
|
||||||
debug_flags, rlimits,
|
debug_flags, rlimits,
|
||||||
permittedCapabilities, effectiveCapabilities,
|
permittedCapabilities, effectiveCapabilities,
|
||||||
MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,
|
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
// The zygote process checks whether the child process has died or not.
|
// The zygote process checks whether the child process has died or not.
|
||||||
|
@ -58,21 +58,6 @@
|
|||||||
<group gid="log" />
|
<group gid="log" />
|
||||||
</permission>
|
</permission>
|
||||||
|
|
||||||
<permission name="android.permission.READ_EXTERNAL_STORAGE" perUser="true" >
|
|
||||||
<group gid="sdcard_r" />
|
|
||||||
</permission>
|
|
||||||
|
|
||||||
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" perUser="true" >
|
|
||||||
<group gid="sdcard_r" />
|
|
||||||
<group gid="sdcard_rw" />
|
|
||||||
</permission>
|
|
||||||
|
|
||||||
<permission name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" >
|
|
||||||
<group gid="sdcard_r" />
|
|
||||||
<group gid="sdcard_rw" />
|
|
||||||
<group gid="sdcard_all" />
|
|
||||||
</permission>
|
|
||||||
|
|
||||||
<permission name="android.permission.WRITE_MEDIA_STORAGE" >
|
<permission name="android.permission.WRITE_MEDIA_STORAGE" >
|
||||||
<group gid="media_rw" />
|
<group gid="media_rw" />
|
||||||
</permission>
|
</permission>
|
||||||
|
@ -50,7 +50,9 @@ import android.os.Handler;
|
|||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.Process;
|
||||||
import android.os.RemoteCallbackList;
|
import android.os.RemoteCallbackList;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
@ -84,6 +86,7 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.app.IMediaContainerService;
|
import com.android.internal.app.IMediaContainerService;
|
||||||
import com.android.internal.os.SomeArgs;
|
import com.android.internal.os.SomeArgs;
|
||||||
|
import com.android.internal.os.Zygote;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.internal.util.FastXmlSerializer;
|
import com.android.internal.util.FastXmlSerializer;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
@ -675,13 +678,15 @@ class MountService extends IMountService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleSystemReady() {
|
private void handleSystemReady() {
|
||||||
resetIfReadyAndConnected();
|
synchronized (mLock) {
|
||||||
|
resetIfReadyAndConnectedLocked();
|
||||||
|
}
|
||||||
|
|
||||||
// Start scheduling nominally-daily fstrim operations
|
// Start scheduling nominally-daily fstrim operations
|
||||||
MountServiceIdler.scheduleIdlePass(mContext);
|
MountServiceIdler.scheduleIdlePass(mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetIfReadyAndConnected() {
|
private void resetIfReadyAndConnectedLocked() {
|
||||||
Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady
|
Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady
|
||||||
+ ", mDaemonConnected=" + mDaemonConnected);
|
+ ", mDaemonConnected=" + mDaemonConnected);
|
||||||
if (mSystemReady && mDaemonConnected) {
|
if (mSystemReady && mDaemonConnected) {
|
||||||
@ -780,7 +785,9 @@ class MountService extends IMountService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleDaemonConnected() {
|
private void handleDaemonConnected() {
|
||||||
resetIfReadyAndConnected();
|
synchronized (mLock) {
|
||||||
|
resetIfReadyAndConnectedLocked();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that we've done our initialization, release
|
* Now that we've done our initialization, release
|
||||||
@ -1600,7 +1607,7 @@ class MountService extends IMountService.Stub
|
|||||||
// reset vold so we bind into new volume into place.
|
// reset vold so we bind into new volume into place.
|
||||||
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
|
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
|
||||||
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
|
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
|
||||||
resetIfReadyAndConnected();
|
resetIfReadyAndConnectedLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
writeSettingsLocked();
|
writeSettingsLocked();
|
||||||
@ -1628,7 +1635,7 @@ class MountService extends IMountService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeSettingsLocked();
|
writeSettingsLocked();
|
||||||
resetIfReadyAndConnected();
|
resetIfReadyAndConnectedLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1640,6 +1647,30 @@ class MountService extends IMountService.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remountUid(int uid) {
|
||||||
|
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
mConnector.execute("volume", "remount_uid", uid, mode);
|
||||||
|
} catch (NativeDaemonConnectorException e) {
|
||||||
|
Slog.w(TAG, "Failed to remount UID " + uid + " as " + mode + ": " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDebugFlags(int flags, int mask) {
|
public void setDebugFlags(int flags, int mask) {
|
||||||
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
|
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
|
||||||
@ -1651,7 +1682,7 @@ class MountService extends IMountService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeSettingsLocked();
|
writeSettingsLocked();
|
||||||
resetIfReadyAndConnected();
|
resetIfReadyAndConnectedLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1688,7 +1719,7 @@ class MountService extends IMountService.Stub
|
|||||||
Slog.d(TAG, "Skipping move to/from primary physical");
|
Slog.d(TAG, "Skipping move to/from primary physical");
|
||||||
onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
|
onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
|
||||||
onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
|
onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
|
||||||
resetIfReadyAndConnected();
|
resetIfReadyAndConnectedLocked();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
final VolumeInfo from = Preconditions.checkNotNull(
|
final VolumeInfo from = Preconditions.checkNotNull(
|
||||||
@ -2022,7 +2053,7 @@ class MountService extends IMountService.Stub
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishMediaUpdate() {
|
public void finishMediaUpdate() {
|
||||||
if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
|
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
|
||||||
throw new SecurityException("no permission to call finishMediaUpdate()");
|
throw new SecurityException("no permission to call finishMediaUpdate()");
|
||||||
}
|
}
|
||||||
if (mUnmountSignal != null) {
|
if (mUnmountSignal != null) {
|
||||||
|
@ -18,7 +18,9 @@ package com.android.server.am;
|
|||||||
|
|
||||||
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
|
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
|
||||||
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
|
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.START_TASKS_FROM_RECENTS;
|
||||||
|
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
|
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
|
||||||
import static com.android.internal.util.XmlUtils.readIntAttribute;
|
import static com.android.internal.util.XmlUtils.readIntAttribute;
|
||||||
@ -3209,13 +3211,14 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
|
|
||||||
int uid = app.uid;
|
int uid = app.uid;
|
||||||
int[] gids = null;
|
int[] gids = null;
|
||||||
int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
|
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
|
||||||
if (!app.isolated) {
|
if (!app.isolated) {
|
||||||
int[] permGids = null;
|
int[] permGids = null;
|
||||||
try {
|
try {
|
||||||
checkTime(startTime, "startProcess: getting gids from package manager");
|
checkTime(startTime, "startProcess: getting gids from package manager");
|
||||||
permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
|
final IPackageManager pm = AppGlobals.getPackageManager();
|
||||||
app.userId);
|
permGids = pm.getPackageGids(app.info.packageName, app.userId);
|
||||||
|
mountExternal = pm.getMountExternalMode(uid);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowAsRuntimeException();
|
throw e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package com.android.server.pm;
|
|||||||
|
|
||||||
import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
|
import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
|
||||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||||
|
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||||
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
|
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
|
||||||
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
|
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
|
||||||
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
|
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
|
||||||
@ -54,6 +55,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_INTERNAL_ERROR;
|
||||||
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
|
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.MOVE_FAILED_SYSTEM_PACKAGE;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.content.pm.PackageParser.isApkFile;
|
import static android.content.pm.PackageParser.isApkFile;
|
||||||
import static android.os.Process.PACKAGE_INFO_GID;
|
import static android.os.Process.PACKAGE_INFO_GID;
|
||||||
import static android.os.Process.SYSTEM_UID;
|
import static android.os.Process.SYSTEM_UID;
|
||||||
@ -196,6 +198,7 @@ import com.android.internal.content.NativeLibraryHelper;
|
|||||||
import com.android.internal.content.PackageHelper;
|
import com.android.internal.content.PackageHelper;
|
||||||
import com.android.internal.os.IParcelFileDescriptorFactory;
|
import com.android.internal.os.IParcelFileDescriptorFactory;
|
||||||
import com.android.internal.os.SomeArgs;
|
import com.android.internal.os.SomeArgs;
|
||||||
|
import com.android.internal.os.Zygote;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.internal.util.FastPrintWriter;
|
import com.android.internal.util.FastPrintWriter;
|
||||||
import com.android.internal.util.FastXmlSerializer;
|
import com.android.internal.util.FastXmlSerializer;
|
||||||
@ -208,8 +211,8 @@ import com.android.server.LocalServices;
|
|||||||
import com.android.server.ServiceThread;
|
import com.android.server.ServiceThread;
|
||||||
import com.android.server.SystemConfig;
|
import com.android.server.SystemConfig;
|
||||||
import com.android.server.Watchdog;
|
import com.android.server.Watchdog;
|
||||||
import com.android.server.pm.Settings.DatabaseVersion;
|
|
||||||
import com.android.server.pm.PermissionsState.PermissionState;
|
import com.android.server.pm.PermissionsState.PermissionState;
|
||||||
|
import com.android.server.pm.Settings.DatabaseVersion;
|
||||||
import com.android.server.storage.DeviceStorageMonitorInternal;
|
import com.android.server.storage.DeviceStorageMonitorInternal;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
@ -2562,6 +2565,21 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMountExternalMode(int uid) {
|
||||||
|
if (Process.isIsolated(uid)) {
|
||||||
|
return Zygote.MOUNT_EXTERNAL_NONE;
|
||||||
|
} 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(
|
static PermissionInfo generatePermissionInfo(
|
||||||
BasePermission bp, int flags) {
|
BasePermission bp, int flags) {
|
||||||
if (bp.perm != null) {
|
if (bp.perm != null) {
|
||||||
@ -3201,6 +3219,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
|
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
|
||||||
"grantRuntimePermission");
|
"grantRuntimePermission");
|
||||||
|
|
||||||
|
final int uid;
|
||||||
final SettingBase sb;
|
final SettingBase sb;
|
||||||
|
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
@ -3216,6 +3235,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
|
|
||||||
enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
|
enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
|
||||||
|
|
||||||
|
uid = pkg.applicationInfo.uid;
|
||||||
sb = (SettingBase) pkg.mExtras;
|
sb = (SettingBase) pkg.mExtras;
|
||||||
if (sb == null) {
|
if (sb == null) {
|
||||||
throw new IllegalArgumentException("Unknown package: " + packageName);
|
throw new IllegalArgumentException("Unknown package: " + packageName);
|
||||||
@ -3245,11 +3265,22 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
|
mOnPermissionChangeListeners.onPermissionsChanged(uid);
|
||||||
|
|
||||||
// Not critical if that is lost - app has to request again.
|
// Not critical if that is lost - app has to request again.
|
||||||
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
|
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (READ_EXTERNAL_STORAGE.equals(name)
|
||||||
|
|| WRITE_EXTERNAL_STORAGE.equals(name)) {
|
||||||
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
final StorageManager storage = mContext.getSystemService(StorageManager.class);
|
||||||
|
storage.remountUid(uid);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user