Move "volume" commands over to Binder.

Keep the old socket-based commands intact for awhile so we can
rapidly disable this change using the ENABLE_BINDER feature flag.

Define constants in AIDL to keep Java and C++ in sync.

Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.ExternalStorageHostTest
Test: cts-tradefed run commandAndExit cts-dev --abi armeabi-v7a -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.AdoptableHostTest
Bug: 13758960
Change-Id: Ie0d917c921b0b826e6bdf55a5d678b247ef352a6
This commit is contained in:
Jeff Sharkey
2017-09-07 15:27:33 -06:00
parent 1019de990a
commit ace874b15b
4 changed files with 157 additions and 86 deletions

View File

@@ -566,6 +566,7 @@ LOCAL_SRC_FILES += \
LOCAL_SRC_FILES += \
../../system/netd/server/binder/android/net/INetd.aidl \
../../system/vold/binder/android/os/IVold.aidl \
../native/cmds/installd/binder/android/os/IInstalld.aidl \
LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings

View File

@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Environment;
import android.os.IVold;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
@@ -75,24 +76,24 @@ public class VolumeInfo implements Parcelable {
/** Real volume representing internal emulated storage */
public static final String ID_EMULATED_INTERNAL = "emulated";
public static final int TYPE_PUBLIC = 0;
public static final int TYPE_PRIVATE = 1;
public static final int TYPE_EMULATED = 2;
public static final int TYPE_ASEC = 3;
public static final int TYPE_OBB = 4;
public static final int TYPE_PUBLIC = IVold.TYPE_PUBLIC;
public static final int TYPE_PRIVATE = IVold.TYPE_PRIVATE;
public static final int TYPE_EMULATED = IVold.TYPE_EMULATED;
public static final int TYPE_ASEC = IVold.TYPE_ASEC;
public static final int TYPE_OBB = IVold.TYPE_OBB;
public static final int STATE_UNMOUNTED = 0;
public static final int STATE_CHECKING = 1;
public static final int STATE_MOUNTED = 2;
public static final int STATE_MOUNTED_READ_ONLY = 3;
public static final int STATE_FORMATTING = 4;
public static final int STATE_EJECTING = 5;
public static final int STATE_UNMOUNTABLE = 6;
public static final int STATE_REMOVED = 7;
public static final int STATE_BAD_REMOVAL = 8;
public static final int STATE_UNMOUNTED = IVold.STATE_UNMOUNTED;
public static final int STATE_CHECKING = IVold.STATE_CHECKING;
public static final int STATE_MOUNTED = IVold.STATE_MOUNTED;
public static final int STATE_MOUNTED_READ_ONLY = IVold.STATE_MOUNTED_READ_ONLY;
public static final int STATE_FORMATTING = IVold.STATE_FORMATTING;
public static final int STATE_EJECTING = IVold.STATE_EJECTING;
public static final int STATE_UNMOUNTABLE = IVold.STATE_UNMOUNTABLE;
public static final int STATE_REMOVED = IVold.STATE_REMOVED;
public static final int STATE_BAD_REMOVAL = IVold.STATE_BAD_REMOVAL;
public static final int MOUNT_FLAG_PRIMARY = 1 << 0;
public static final int MOUNT_FLAG_VISIBLE = 1 << 1;
public static final int MOUNT_FLAG_PRIMARY = IVold.MOUNT_FLAG_PRIMARY;
public static final int MOUNT_FLAG_VISIBLE = IVold.MOUNT_FLAG_VISIBLE;
private static SparseArray<String> sStateToEnvironment = new SparseArray<>();
private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>();

View File

@@ -16,14 +16,12 @@
package com.android.internal.os;
import android.os.IVold;
import android.os.Trace;
import dalvik.system.ZygoteHooks;
import android.system.ErrnoException;
import android.system.Os;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import dalvik.system.ZygoteHooks;
/** @hide */
public final class Zygote {
@@ -52,13 +50,13 @@ public final class Zygote {
public static final int DEBUG_JAVA_DEBUGGABLE = 1 << 8;
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = 0;
public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
/** Default external storage should be mounted. */
public static final int MOUNT_EXTERNAL_DEFAULT = 1;
public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
/** Read-only external storage should be mounted. */
public static final int MOUNT_EXTERNAL_READ = 2;
public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
/** Read-write external storage should be mounted. */
public static final int MOUNT_EXTERNAL_WRITE = 3;
public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();

View File

@@ -681,13 +681,18 @@ class StorageManagerService extends IStorageManager.Stub
final IStorageShutdownObserver obs = (IStorageShutdownObserver) msg.obj;
boolean success = false;
try {
success = mConnector.execute("volume", "shutdown").isClassOk();
} catch (NativeDaemonConnectorException ignored) {
if (ENABLE_BINDER) {
mVold.shutdown();
} else {
success = mConnector.execute("volume", "shutdown").isClassOk();
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
if (obs != null) {
try {
obs.onShutDownComplete(success ? 0 : -1);
} catch (RemoteException ignored) {
} catch (Exception ignored) {
}
}
break;
@@ -699,9 +704,14 @@ class StorageManagerService extends IStorageManager.Stub
break;
}
try {
mConnector.execute("volume", "mount", vol.id, vol.mountFlags,
vol.mountUserId);
} catch (NativeDaemonConnectorException ignored) {
if (ENABLE_BINDER) {
mVold.mount(vol.id, vol.mountFlags, vol.mountUserId);
} else {
mConnector.execute("volume", "mount", vol.id, vol.mountFlags,
vol.mountUserId);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
break;
}
@@ -761,7 +771,11 @@ class StorageManagerService extends IStorageManager.Stub
if (Intent.ACTION_USER_ADDED.equals(action)) {
final UserManager um = mContext.getSystemService(UserManager.class);
final int userSerialNumber = um.getUserSerialNumber(userId);
mConnector.execute("volume", "user_added", userId, userSerialNumber);
if (ENABLE_BINDER) {
mVold.onUserAdded(userId, userSerialNumber);
} else {
mConnector.execute("volume", "user_added", userId, userSerialNumber);
}
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
synchronized (mVolumes) {
final int size = mVolumes.size();
@@ -773,10 +787,14 @@ class StorageManagerService extends IStorageManager.Stub
}
}
}
mConnector.execute("volume", "user_removed", userId);
if (ENABLE_BINDER) {
mVold.onUserRemoved(userId);
} else {
mConnector.execute("volume", "user_removed", userId);
}
}
} catch (NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to send user details to vold", e);
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
};
@@ -930,13 +948,21 @@ class StorageManagerService extends IStorageManager.Stub
// Tell vold about all existing and started users
for (UserInfo user : users) {
mConnector.execute("volume", "user_added", user.id, user.serialNumber);
if (ENABLE_BINDER) {
mVold.onUserAdded(user.id, user.serialNumber);
} else {
mConnector.execute("volume", "user_added", user.id, user.serialNumber);
}
}
for (int userId : systemUnlockedUsers) {
mConnector.execute("volume", "user_started", userId);
if (ENABLE_BINDER) {
mVold.onUserStarted(userId);
} else {
mConnector.execute("volume", "user_started", userId);
}
}
} catch (RemoteException | NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to reset vold", e);
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
}
@@ -948,8 +974,13 @@ class StorageManagerService extends IStorageManager.Stub
// staging area is ready so it's ready for zygote-forked apps to
// bind mount against.
try {
mConnector.execute("volume", "user_started", userId);
} catch (NativeDaemonConnectorException ignored) {
if (ENABLE_BINDER) {
mVold.onUserStarted(userId);
} else {
mConnector.execute("volume", "user_started", userId);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
// Record user as started so newly mounted volumes kick off events
@@ -973,8 +1004,13 @@ class StorageManagerService extends IStorageManager.Stub
Slog.d(TAG, "onCleanupUser " + userId);
try {
mConnector.execute("volume", "user_stopped", userId);
} catch (NativeDaemonConnectorException ignored) {
if (ENABLE_BINDER) {
mVold.onUserStopped(userId);
} else {
mConnector.execute("volume", "user_stopped", userId);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
synchronized (mLock) {
@@ -1804,9 +1840,13 @@ class StorageManagerService extends IStorageManager.Stub
throw new SecurityException("Mounting " + volId + " restricted by policy");
}
try {
mConnector.execute("volume", "mount", vol.id, vol.mountFlags, vol.mountUserId);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
if (ENABLE_BINDER) {
mVold.mount(vol.id, vol.mountFlags, vol.mountUserId);
} else {
mConnector.execute("volume", "mount", vol.id, vol.mountFlags, vol.mountUserId);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -1833,9 +1873,13 @@ class StorageManagerService extends IStorageManager.Stub
}
try {
mConnector.execute("volume", "unmount", vol.id);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
if (ENABLE_BINDER) {
mVold.unmount(vol.id);
} else {
mConnector.execute("volume", "unmount", vol.id);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -1846,9 +1890,13 @@ class StorageManagerService extends IStorageManager.Stub
final VolumeInfo vol = findVolumeByIdOrThrow(volId);
try {
mConnector.execute("volume", "format", vol.id, "auto");
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
if (ENABLE_BINDER) {
mVold.format(vol.id, "auto");
} else {
mConnector.execute("volume", "format", vol.id, "auto");
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -1859,13 +1907,16 @@ class StorageManagerService extends IStorageManager.Stub
try {
// TODO: make benchmark async so we don't block other commands
final NativeDaemonEvent res = mConnector.execute(3 * DateUtils.MINUTE_IN_MILLIS,
"volume", "benchmark", volId);
return Long.parseLong(res.getMessage());
} catch (NativeDaemonTimeoutException e) {
if (ENABLE_BINDER) {
return mVold.benchmark(volId);
} else {
final NativeDaemonEvent res = mConnector.execute(3 * DateUtils.MINUTE_IN_MILLIS,
"volume", "benchmark", volId);
return Long.parseLong(res.getMessage());
}
} catch (Exception e) {
Slog.wtf(TAG, e);
return Long.MAX_VALUE;
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
@@ -1876,12 +1927,14 @@ class StorageManagerService extends IStorageManager.Stub
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
try {
mConnector.execute("volume", "partition", diskId, "public");
if (ENABLE_BINDER) {
mVold.partition(diskId, IVold.PARTITION_TYPE_PUBLIC, -1);
} else {
mConnector.execute("volume", "partition", diskId, "public");
}
waitForLatch(latch, "partitionPublic", 3 * DateUtils.MINUTE_IN_MILLIS);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
} catch (TimeoutException e) {
throw new IllegalStateException(e);
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -1893,12 +1946,14 @@ class StorageManagerService extends IStorageManager.Stub
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
try {
mConnector.execute("volume", "partition", diskId, "private");
if (ENABLE_BINDER) {
mVold.partition(diskId, IVold.PARTITION_TYPE_PRIVATE, -1);
} else {
mConnector.execute("volume", "partition", diskId, "private");
}
waitForLatch(latch, "partitionPrivate", 3 * DateUtils.MINUTE_IN_MILLIS);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
} catch (TimeoutException e) {
throw new IllegalStateException(e);
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -1910,12 +1965,14 @@ class StorageManagerService extends IStorageManager.Stub
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
try {
mConnector.execute("volume", "partition", diskId, "mixed", ratio);
if (ENABLE_BINDER) {
mVold.partition(diskId, IVold.PARTITION_TYPE_MIXED, ratio);
} else {
mConnector.execute("volume", "partition", diskId, "mixed", ratio);
}
waitForLatch(latch, "partitionMixed", 3 * DateUtils.MINUTE_IN_MILLIS);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
} catch (TimeoutException e) {
throw new IllegalStateException(e);
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -1999,9 +2056,13 @@ class StorageManagerService extends IStorageManager.Stub
private void forgetPartition(String partGuid) {
try {
mConnector.execute("volume", "forget_partition", partGuid);
} catch (NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to forget key for " + partGuid + ": " + e);
if (ENABLE_BINDER) {
mVold.forgetPartition(partGuid);
} else {
mConnector.execute("volume", "forget_partition", partGuid);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -2035,20 +2096,22 @@ class StorageManagerService extends IStorageManager.Stub
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, modeName);
} catch (NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to remount UID " + uid + " as " + modeName + ": " + e);
if (ENABLE_BINDER) {
mVold.remountUid(uid, mode);
} else {
mConnector.execute("volume", "remount_uid", uid, modeName);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -2199,9 +2262,13 @@ class StorageManagerService extends IStorageManager.Stub
}
try {
mConnector.execute("volume", "move_storage", from.id, to.id);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
if (ENABLE_BINDER) {
mVold.moveStorage(from.id, to.id);
} else {
mConnector.execute("volume", "move_storage", from.id, to.id);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
@@ -3185,10 +3252,14 @@ class StorageManagerService extends IStorageManager.Stub
}
try {
mConnector.execute("volume", "mkdirs", appPath);
if (ENABLE_BINDER) {
mVold.mkdirs(appPath);
} else {
mConnector.execute("volume", "mkdirs", appPath);
}
return 0;
} catch (NativeDaemonConnectorException e) {
return e.getCode();
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}