diff options
| -rw-r--r-- | Android.mk | 2 | ||||
| -rw-r--r-- | core/java/android/os/storage/VolumeInfo.java | 30 | ||||
| -rw-r--r-- | services/core/Android.mk | 5 | ||||
| -rw-r--r-- | services/core/java/com/android/server/StorageManagerService.java | 235 |
4 files changed, 192 insertions, 80 deletions
diff --git a/Android.mk b/Android.mk index 76ca9b928aa2..9a4b19cb322b 100644 --- a/Android.mk +++ b/Android.mk @@ -567,6 +567,7 @@ LOCAL_SRC_FILES += \ LOCAL_SRC_FILES += \ ../../system/netd/server/binder/android/net/INetd.aidl \ ../../system/vold/binder/android/os/IVold.aidl \ + ../../system/vold/binder/android/os/IVoldListener.aidl \ ../native/cmds/installd/binder/android/os/IInstalld.aidl \ LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings @@ -591,6 +592,7 @@ LOCAL_AIDL_INCLUDES += \ frameworks/av/media/libaudioclient/aidl \ frameworks/native/aidl/gui \ system/netd/server/binder \ + system/vold/binder \ system/bt/binder LOCAL_INTERMEDIATE_SOURCES := \ diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index b8353d7ace02..76f79f13d9a7 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -76,21 +76,21 @@ 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 = 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 = 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 TYPE_PUBLIC = IVold.VOLUME_TYPE_PUBLIC; + public static final int TYPE_PRIVATE = IVold.VOLUME_TYPE_PRIVATE; + public static final int TYPE_EMULATED = IVold.VOLUME_TYPE_EMULATED; + public static final int TYPE_ASEC = IVold.VOLUME_TYPE_ASEC; + public static final int TYPE_OBB = IVold.VOLUME_TYPE_OBB; + + public static final int STATE_UNMOUNTED = IVold.VOLUME_STATE_UNMOUNTED; + public static final int STATE_CHECKING = IVold.VOLUME_STATE_CHECKING; + public static final int STATE_MOUNTED = IVold.VOLUME_STATE_MOUNTED; + public static final int STATE_MOUNTED_READ_ONLY = IVold.VOLUME_STATE_MOUNTED_READ_ONLY; + public static final int STATE_FORMATTING = IVold.VOLUME_STATE_FORMATTING; + public static final int STATE_EJECTING = IVold.VOLUME_STATE_EJECTING; + public static final int STATE_UNMOUNTABLE = IVold.VOLUME_STATE_UNMOUNTABLE; + public static final int STATE_REMOVED = IVold.VOLUME_STATE_REMOVED; + public static final int STATE_BAD_REMOVAL = IVold.VOLUME_STATE_BAD_REMOVAL; public static final int MOUNT_FLAG_PRIMARY = IVold.MOUNT_FLAG_PRIMARY; public static final int MOUNT_FLAG_VISIBLE = IVold.MOUNT_FLAG_VISIBLE; diff --git a/services/core/Android.mk b/services/core/Android.mk index 8b162aecf0f4..7776346ff55b 100644 --- a/services/core/Android.mk +++ b/services/core/Android.mk @@ -6,8 +6,8 @@ LOCAL_MODULE := services.core LOCAL_AIDL_INCLUDES := \ frameworks/native/aidl/binder \ - system/netd/server/binder - + system/netd/server/binder \ + system/vold/binder LOCAL_SRC_FILES += \ $(call all-java-files-under,java) \ @@ -16,6 +16,7 @@ LOCAL_SRC_FILES += \ ../../../../system/netd/server/binder/android/net/INetd.aidl \ ../../../../system/netd/server/binder/android/net/metrics/INetdEventListener.aidl \ ../../../../system/vold/binder/android/os/IVold.aidl \ + ../../../../system/vold/binder/android/os/IVoldListener.aidl \ ../../../native/cmds/installd/binder/android/os/IInstalld.aidl \ LOCAL_AIDL_INCLUDES += \ diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index ceb94ffff383..e2c0e326365f 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -57,6 +57,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.IVold; +import android.os.IVoldListener; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; @@ -1128,26 +1129,21 @@ class StorageManagerService extends IStorageManager.Stub @Override public boolean onEvent(int code, String raw, String[] cooked) { synchronized (mLock) { - return onEventLocked(code, raw, cooked); + try { + return onEventLocked(code, raw, cooked); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } } } - private boolean onEventLocked(int code, String raw, String[] cooked) { + private boolean onEventLocked(int code, String raw, String[] cooked) throws RemoteException { switch (code) { case VoldResponseCode.DISK_CREATED: { if (cooked.length != 3) break; - final String id = cooked[1]; - int flags = Integer.parseInt(cooked[2]); - if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false) - || mForceAdoptable) { - flags |= DiskInfo.FLAG_ADOPTABLE; - } - // Adoptable storage isn't currently supported on FBE devices - if (StorageManager.isFileEncryptedNativeOnly() - && !SystemProperties.getBoolean(StorageManager.PROP_ADOPTABLE_FBE, false)) { - flags &= ~DiskInfo.FLAG_ADOPTABLE; - } - mDisks.put(id, new DiskInfo(id, flags)); + final String diskId = cooked[1]; + final int flags = Integer.parseInt(cooked[2]); + mListener.onDiskCreated(diskId, flags); break; } case VoldResponseCode.DISK_SIZE_CHANGED: { @@ -1171,10 +1167,8 @@ class StorageManagerService extends IStorageManager.Stub } case VoldResponseCode.DISK_SCANNED: { if (cooked.length != 2) break; - final DiskInfo disk = mDisks.get(cooked[1]); - if (disk != null) { - onDiskScannedLocked(disk); - } + final String diskId = cooked[1]; + mListener.onDiskScanned(diskId); break; } case VoldResponseCode.DISK_SYS_PATH_CHANGED: { @@ -1187,34 +1181,24 @@ class StorageManagerService extends IStorageManager.Stub } case VoldResponseCode.DISK_DESTROYED: { if (cooked.length != 2) break; - final DiskInfo disk = mDisks.remove(cooked[1]); - if (disk != null) { - mCallbacks.notifyDiskDestroyed(disk); - } + final String diskId = cooked[1]; + mListener.onDiskDestroyed(diskId); break; } case VoldResponseCode.VOLUME_CREATED: { - final String id = cooked[1]; + final String volId = cooked[1]; final int type = Integer.parseInt(cooked[2]); final String diskId = TextUtils.nullIfEmpty(cooked[3]); final String partGuid = TextUtils.nullIfEmpty(cooked[4]); - - final DiskInfo disk = mDisks.get(diskId); - final VolumeInfo vol = new VolumeInfo(id, type, disk, partGuid); - mVolumes.put(id, vol); - onVolumeCreatedLocked(vol); + mListener.onVolumeCreated(volId, type, diskId, partGuid); break; } case VoldResponseCode.VOLUME_STATE_CHANGED: { if (cooked.length != 3) break; - final VolumeInfo vol = mVolumes.get(cooked[1]); - if (vol != null) { - final int oldState = vol.state; - final int newState = Integer.parseInt(cooked[2]); - vol.state = newState; - onVolumeStateChangedLocked(vol, oldState, newState); - } + final String volId = cooked[1]; + final int state = Integer.parseInt(cooked[2]); + mListener.onVolumeStateChanged(volId, state); break; } case VoldResponseCode.VOLUME_FS_TYPE_CHANGED: { @@ -1247,23 +1231,22 @@ class StorageManagerService extends IStorageManager.Stub } case VoldResponseCode.VOLUME_PATH_CHANGED: { if (cooked.length != 3) break; - final VolumeInfo vol = mVolumes.get(cooked[1]); - if (vol != null) { - vol.path = cooked[2]; - } + final String volId = cooked[1]; + final String path = cooked[2]; + mListener.onVolumePathChanged(volId, path); break; } case VoldResponseCode.VOLUME_INTERNAL_PATH_CHANGED: { if (cooked.length != 3) break; - final VolumeInfo vol = mVolumes.get(cooked[1]); - if (vol != null) { - vol.internalPath = cooked[2]; - } + final String volId = cooked[1]; + final String internalPath = cooked[2]; + mListener.onVolumeInternalPathChanged(volId, internalPath); break; } case VoldResponseCode.VOLUME_DESTROYED: { if (cooked.length != 2) break; - mVolumes.remove(cooked[1]); + final String volId = cooked[1]; + mListener.onVolumeDestroyed(volId); break; } @@ -1320,6 +1303,120 @@ class StorageManagerService extends IStorageManager.Stub return true; } + private final IVoldListener mListener = new IVoldListener.Stub() { + @Override + public void onDiskCreated(String diskId, int flags) { + synchronized (mLock) { + if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false) + || mForceAdoptable) { + flags |= DiskInfo.FLAG_ADOPTABLE; + } + // Adoptable storage isn't currently supported on FBE devices + if (StorageManager.isFileEncryptedNativeOnly() + && !SystemProperties.getBoolean(StorageManager.PROP_ADOPTABLE_FBE, false)) { + flags &= ~DiskInfo.FLAG_ADOPTABLE; + } + mDisks.put(diskId, new DiskInfo(diskId, flags)); + } + } + + @Override + public void onDiskScanned(String diskId) { + synchronized (mLock) { + final DiskInfo disk = mDisks.get(diskId); + if (disk != null) { + onDiskScannedLocked(disk); + } + } + } + + @Override + public void onDiskMetadataChanged(String diskId, long sizeBytes, String label, + String sysPath) { + synchronized (mLock) { + final DiskInfo disk = mDisks.get(diskId); + if (disk != null) { + disk.size = sizeBytes; + disk.label = label; + disk.sysPath = sysPath; + } + } + } + + @Override + public void onDiskDestroyed(String diskId) { + synchronized (mLock) { + final DiskInfo disk = mDisks.remove(diskId); + if (disk != null) { + mCallbacks.notifyDiskDestroyed(disk); + } + } + } + + @Override + public void onVolumeCreated(String volId, int type, String diskId, String partGuid) { + synchronized (mLock) { + final DiskInfo disk = mDisks.get(diskId); + final VolumeInfo vol = new VolumeInfo(volId, type, disk, partGuid); + mVolumes.put(volId, vol); + onVolumeCreatedLocked(vol); + } + } + + @Override + public void onVolumeStateChanged(String volId, int state) { + synchronized (mLock) { + final VolumeInfo vol = mVolumes.get(volId); + if (vol != null) { + final int oldState = vol.state; + final int newState = state; + vol.state = newState; + onVolumeStateChangedLocked(vol, oldState, newState); + } + } + } + + @Override + public void onVolumeMetadataChanged(String volId, String fsType, String fsUuid, + String fsLabel) { + synchronized (mLock) { + final VolumeInfo vol = mVolumes.get(volId); + if (vol != null) { + vol.fsType = fsType; + vol.fsUuid = fsUuid; + vol.fsLabel = fsLabel; + } + } + } + + @Override + public void onVolumePathChanged(String volId, String path) { + synchronized (mLock) { + final VolumeInfo vol = mVolumes.get(volId); + if (vol != null) { + vol.path = path; + } + } + } + + @Override + public void onVolumeInternalPathChanged(String volId, String internalPath) { + synchronized (mLock) { + final VolumeInfo vol = mVolumes.get(volId); + if (vol != null) { + vol.internalPath = internalPath; + } + } + } + + @Override + public void onVolumeDestroyed(String volId) { + synchronized (mLock) { + mVolumes.remove(volId); + } + } + }; + private void onDiskScannedLocked(DiskInfo disk) { int volumeCount = 0; for (int i = 0; i < mVolumes.size(); i++) { @@ -1661,12 +1758,19 @@ class StorageManagerService extends IStorageManager.Stub if (binder != null) { mVold = IVold.Stub.asInterface(binder); + try { + mVold.setListener(mListener); + return; + } catch (RemoteException e) { + Slog.w(TAG, "vold listener rejected; trying again", e); + } } else { Slog.w(TAG, "vold not found; trying again"); - BackgroundThread.getHandler().postDelayed(() -> { - connect(); - }, DateUtils.SECOND_IN_MILLIS); } + + BackgroundThread.getHandler().postDelayed(() -> { + connect(); + }, DateUtils.SECOND_IN_MILLIS); } private void systemReady() { @@ -2769,15 +2873,15 @@ class StorageManagerService extends IStorageManager.Stub @Override public int decryptStorage(String password) { - if (TextUtils.isEmpty(password)) { - throw new IllegalArgumentException("password cannot be empty"); - } - mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER, "no permission to access the crypt keeper"); waitForReady(); + if (TextUtils.isEmpty(password)) { + throw new IllegalArgumentException("password cannot be empty"); + } + if (DEBUG_EVENTS) { Slog.i(TAG, "decrypting storage..."); } @@ -2792,6 +2896,7 @@ class StorageManagerService extends IStorageManager.Stub Slog.wtf(TAG, e); } }, DateUtils.SECOND_IN_MILLIS); + return 0; } catch (Exception e) { Slog.wtf(TAG, e); return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN; @@ -2825,30 +2930,28 @@ class StorageManagerService extends IStorageManager.Stub } public int encryptStorage(int type, String password) { - if (TextUtils.isEmpty(password) && type != StorageManager.CRYPT_TYPE_DEFAULT) { - throw new IllegalArgumentException("password cannot be empty"); - } - mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER, "no permission to access the crypt keeper"); waitForReady(); + if (type == StorageManager.CRYPT_TYPE_DEFAULT) { + password = ""; + } else if (TextUtils.isEmpty(password)) { + throw new IllegalArgumentException("password cannot be empty"); + } + if (DEBUG_EVENTS) { Slog.i(TAG, "encrypting storage..."); } try { - if (type == StorageManager.CRYPT_TYPE_DEFAULT) { - if (ENABLE_BINDER) { - mVold.fdeEnable(type, null, IVold.ENCRYPTION_FLAG_IN_PLACE); - } else { + if (ENABLE_BINDER) { + mVold.fdeEnable(type, password, IVold.ENCRYPTION_FLAG_IN_PLACE); + } else { + if (type == StorageManager.CRYPT_TYPE_DEFAULT) { mCryptConnector.execute("cryptfs", "enablecrypto", "inplace", CRYPTO_TYPES[type]); - } - } else { - if (ENABLE_BINDER) { - mVold.fdeEnable(type, password, IVold.ENCRYPTION_FLAG_IN_PLACE); } else { mCryptConnector.execute("cryptfs", "enablecrypto", "inplace", CRYPTO_TYPES[type], new SensitiveArg(password)); @@ -2872,6 +2975,12 @@ class StorageManagerService extends IStorageManager.Stub waitForReady(); + if (type == StorageManager.CRYPT_TYPE_DEFAULT) { + password = ""; + } else if (TextUtils.isEmpty(password)) { + throw new IllegalArgumentException("password cannot be empty"); + } + if (DEBUG_EVENTS) { Slog.i(TAG, "changing encryption password..."); } |