Merge "Mount storage after unlock, fix leaving emulation."
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index db12564..7f36a98 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1021,8 +1021,17 @@
/** {@hide} */
public static boolean isFileBasedEncryptionEnabled() {
- return "file".equals(SystemProperties.get("ro.crypto.type", "none"))
- || SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false);
+ return isNativeFileBasedEncryptionEnabled() || isEmulatedFileBasedEncryptionEnabled();
+ }
+
+ /** {@hide} */
+ public static boolean isNativeFileBasedEncryptionEnabled() {
+ return "file".equals(SystemProperties.get("ro.crypto.type", "none"));
+ }
+
+ /** {@hide} */
+ public static boolean isEmulatedFileBasedEncryptionEnabled() {
+ return SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false);
}
/** {@hide} */
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 807c0d6..473eff6 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -57,6 +57,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -175,8 +176,8 @@
}
@Override
- public void onStartUser(int userHandle) {
- mMountService.onStartUser(userHandle);
+ public void onUnlockUser(int userHandle) {
+ mMountService.onUnlockUser(userHandle);
}
@Override
@@ -286,10 +287,12 @@
*/
private final Object mLock = new Object();
+ /** Set of users that we know are unlocked. */
@GuardedBy("mLock")
- private int[] mStartedUsers = EmptyArray.INT;
+ private int[] mLocalUnlockedUsers = EmptyArray.INT;
+ /** Set of users that system knows are unlocked. */
@GuardedBy("mLock")
- private int[] mUnlockedUsers = EmptyArray.INT;
+ private int[] mSystemUnlockedUsers = EmptyArray.INT;
/** Map from disk ID to disk */
@GuardedBy("mLock")
@@ -834,12 +837,21 @@
private void initIfReadyAndConnected() {
Slog.d(TAG, "Thinking about init, mSystemReady=" + mSystemReady
+ ", mDaemonConnected=" + mDaemonConnected);
- if (mSystemReady && mDaemonConnected && StorageManager.isFileBasedEncryptionEnabled()) {
- final List<UserInfo> users = mContext.getSystemService(UserManager.class)
- .getUsers();
+ if (mSystemReady && mDaemonConnected
+ && !StorageManager.isNativeFileBasedEncryptionEnabled()) {
+ // When booting a device without native support, make sure that our
+ // user directories are locked or unlocked based on the current
+ // emulation status.
+ final boolean initLocked = StorageManager.isEmulatedFileBasedEncryptionEnabled();
+ final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
for (UserInfo user : users) {
try {
- mCryptConnector.execute("cryptfs", "lock_user_key", user.id);
+ if (initLocked) {
+ mCryptConnector.execute("cryptfs", "lock_user_key", user.id);
+ } else {
+ mCryptConnector.execute("cryptfs", "unlock_user_key", user.id,
+ user.serialNumber, "!");
+ }
} catch (NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to init vold", e);
}
@@ -854,9 +866,9 @@
final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
killMediaProvider(users);
- final int[] startedUsers;
+ final int[] systemUnlockedUsers;
synchronized (mLock) {
- startedUsers = mStartedUsers;
+ systemUnlockedUsers = mSystemUnlockedUsers;
mDisks.clear();
mVolumes.clear();
@@ -871,7 +883,7 @@
for (UserInfo user : users) {
mConnector.execute("volume", "user_added", user.id, user.serialNumber);
}
- for (int userId : startedUsers) {
+ for (int userId : systemUnlockedUsers) {
mConnector.execute("volume", "user_started", userId);
}
} catch (NativeDaemonConnectorException e) {
@@ -880,8 +892,8 @@
}
}
- private void onStartUser(int userId) {
- Slog.d(TAG, "onStartUser " + userId);
+ private void onUnlockUser(int userId) {
+ Slog.d(TAG, "onUnlockUser " + userId);
// We purposefully block here to make sure that user-specific
// staging area is ready so it's ready for zygote-forked apps to
@@ -904,7 +916,7 @@
mCallbacks.notifyStorageStateChanged(userVol.getPath(), envState, envState);
}
}
- mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userId);
+ mSystemUnlockedUsers = ArrayUtils.appendInt(mSystemUnlockedUsers, userId);
}
}
@@ -917,7 +929,7 @@
}
synchronized (mVolumes) {
- mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userId);
+ mSystemUnlockedUsers = ArrayUtils.removeInt(mSystemUnlockedUsers, userId);
}
}
@@ -1337,7 +1349,7 @@
// Kick state changed event towards all started users. Any users
// started after this point will trigger additional
// user-specific broadcasts.
- for (int userId : mStartedUsers) {
+ for (int userId : mSystemUnlockedUsers) {
if (vol.isVisibleForRead(userId)) {
final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
@@ -1926,8 +1938,16 @@
waitForReady();
if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) {
+ if (StorageManager.isNativeFileBasedEncryptionEnabled()) {
+ throw new IllegalStateException(
+ "Emulation not available on device with native FBE");
+ }
+
final boolean emulateFbe = (flags & StorageManager.DEBUG_EMULATE_FBE) != 0;
SystemProperties.set(StorageManager.PROP_EMULATE_FBE, Boolean.toString(emulateFbe));
+
+ // Perform hard reboot to kick policy into place
+ mContext.getSystemService(PowerManager.class).reboot(null);
}
if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) {
@@ -2745,7 +2765,7 @@
}
synchronized (mLock) {
- mUnlockedUsers = ArrayUtils.appendInt(mUnlockedUsers, userId);
+ mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId);
}
}
@@ -2761,7 +2781,7 @@
}
synchronized (mLock) {
- mUnlockedUsers = ArrayUtils.removeInt(mUnlockedUsers, userId);
+ mLocalUnlockedUsers = ArrayUtils.removeInt(mLocalUnlockedUsers, userId);
}
}
@@ -2769,7 +2789,7 @@
public boolean isUserKeyUnlocked(int userId) {
if (StorageManager.isFileBasedEncryptionEnabled()) {
synchronized (mLock) {
- return ArrayUtils.contains(mUnlockedUsers, userId);
+ return ArrayUtils.contains(mLocalUnlockedUsers, userId);
}
} else {
return true;
@@ -2836,21 +2856,25 @@
@Override
public StorageVolume[] getVolumeList(int uid, String packageName, int flags) {
+ final int userId = UserHandle.getUserId(uid);
final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0;
- final ArrayList<StorageVolume> res = new ArrayList<>();
+ boolean reportUnmounted = false;
boolean foundPrimary = false;
- final int userId = UserHandle.getUserId(uid);
- final boolean reportUnmounted;
final long identity = Binder.clearCallingIdentity();
try {
- reportUnmounted = !mMountServiceInternal.hasExternalStorage(
- uid, packageName);
+ if (!mMountServiceInternal.hasExternalStorage(uid, packageName)) {
+ reportUnmounted = true;
+ }
+ if (!isUserKeyUnlocked(userId)) {
+ reportUnmounted = true;
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
+ final ArrayList<StorageVolume> res = new ArrayList<>();
synchronized (mLock) {
for (int i = 0; i < mVolumes.size(); i++) {
final VolumeInfo vol = mVolumes.valueAt(i);
@@ -3530,8 +3554,8 @@
pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
pw.println("Force adoptable: " + mForceAdoptable);
pw.println();
- pw.println("Started users: " + Arrays.toString(mStartedUsers));
- pw.println("Unlocked users: " + Arrays.toString(mUnlockedUsers));
+ pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers));
+ pw.println("System unlocked users: " + Arrays.toString(mSystemUnlockedUsers));
}
synchronized (mObbMounts) {