diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index fc440d2b446b1..c21c65a706a36 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -2286,7 +2286,12 @@ public interface IMountService extends IInterface { /** * Determines the encryption state of the volume. - * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible values. + * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible + * values. + * Note that this has been replaced in most cases by the APIs in + * StorageManager (see isEncryptable and below) + * This is still useful to get the error state when encryption has failed + * and CryptKeeper needs to throw up a screen advising the user what to do */ public int getEncryptionState() throws RemoteException; diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 17df7080acf18..61e6b95cf89fd 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1025,21 +1025,119 @@ public class StorageManager { } } - /** {@hide} */ - public static boolean isFileBasedEncryptionEnabled() { - return isNativeFileBasedEncryptionEnabled() || isEmulatedFileBasedEncryptionEnabled(); + /** {@hide} + * Is this device encryptable or already encrypted? + * @return true for encryptable or encrypted + * false not encrypted and not encryptable + */ + public static boolean isEncryptable() { + final String state = SystemProperties.get("ro.crypto.state", "unsupported"); + return !"unsupported".equalsIgnoreCase(state); + } + + /** {@hide} + * Is this device already encrypted? + * @return true for encrypted. (Implies isEncryptable() == true) + * false not encrypted + */ + public static boolean isEncrypted() { + final String state = SystemProperties.get("ro.crypto.state", ""); + return "encrypted".equalsIgnoreCase(state); + } + + /** {@hide} + * Is this device file encrypted? + * @return true for file encrypted. (Implies isEncrypted() == true) + * false not encrypted or block encrypted + */ + public static boolean isFileEncryptedNativeOnly() { + if (!isEncrypted()) { + return false; + } + + final String status = SystemProperties.get("ro.crypto.type", ""); + return "file".equalsIgnoreCase(status); + } + + /** {@hide} + * Is this device block encrypted? + * @return true for block encrypted. (Implies isEncrypted() == true) + * false not encrypted or file encrypted + */ + public static boolean isBlockEncrypted() { + if (!isEncrypted()) { + return false; + } + final String status = SystemProperties.get("ro.crypto.type", ""); + return "block".equalsIgnoreCase(status); + } + + /** {@hide} + * Is this device block encrypted with credentials? + * @return true for crediential block encrypted. + * (Implies isBlockEncrypted() == true) + * false not encrypted, file encrypted or default block encrypted + */ + public static boolean isNonDefaultBlockEncrypted() { + if (!isBlockEncrypted()) { + return false; + } + + try { + IMountService mountService = IMountService.Stub.asInterface( + ServiceManager.getService("mount")); + return mountService.getPasswordType() != CRYPT_TYPE_DEFAULT; + } catch (RemoteException e) { + Log.e(TAG, "Error getting encryption type"); + return false; + } + } + + /** {@hide} + * Is this device in the process of being block encrypted? + * @return true for encrypting. + * false otherwise + * Whether device isEncrypted at this point is undefined + * Note that only system services and CryptKeeper will ever see this return + * true - no app will ever be launched in this state. + * Also note that this state will not change without a teardown of the + * framework, so no service needs to check for changes during their lifespan + */ + public static boolean isBlockEncrypting() { + final String state = SystemProperties.get("vold.encrypt_progress", ""); + return !"".equalsIgnoreCase(state); + } + + /** {@hide} + * Is this device non default block encrypted and in the process of + * prompting for credentials? + * @return true for prompting for credentials. + * (Implies isNonDefaultBlockEncrypted() == true) + * false otherwise + * Note that only system services and CryptKeeper will ever see this return + * true - no app will ever be launched in this state. + * Also note that this state will not change without a teardown of the + * framework, so no service needs to check for changes during their lifespan + */ + public static boolean inCryptKeeperBounce() { + final String status = SystemProperties.get("vold.decrypt"); + return "trigger_restart_min_framework".equals(status); } /** {@hide} */ - public static boolean isNativeFileBasedEncryptionEnabled() { - return "file".equals(SystemProperties.get("ro.crypto.type", "none")); - } - - /** {@hide} */ - public static boolean isEmulatedFileBasedEncryptionEnabled() { + public static boolean isFileEncryptedEmulatedOnly() { return SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false); } + /** {@hide} + * Is this device running in a file encrypted mode, either native or emulated? + * @return true for file encrypted, false otherwise + */ + public static boolean isFileEncryptedNativeOrEmulated() { + return isFileEncryptedNativeOnly() + || isFileEncryptedEmulatedOnly(); + } + /** {@hide} */ public static File maybeTranslateEmulatedPathToInternal(File path) { final IMountService mountService = IMountService.Stub.asInterface( diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 795012dab4d13..9d1447836b93d 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -887,8 +887,7 @@ public class LockPatternUtils { * @return true if device encryption is enabled */ public static boolean isDeviceEncryptionEnabled() { - final String status = SystemProperties.get("ro.crypto.state", "unsupported"); - return "encrypted".equalsIgnoreCase(status); + return StorageManager.isEncrypted(); } /** @@ -896,7 +895,7 @@ public class LockPatternUtils { * @return true if device is file encrypted */ public static boolean isFileEncryptionEnabled() { - return StorageManager.isFileBasedEncryptionEnabled(); + return StorageManager.isFileEncryptedNativeOrEmulated(); } /** diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java index ab75b7c2775c8..6d6c1622e5c24 100644 --- a/core/java/com/android/server/BootReceiver.java +++ b/core/java/com/android/server/BootReceiver.java @@ -29,6 +29,7 @@ import android.os.RecoverySystem; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; +import android.os.storage.StorageManager; import android.provider.Downloads; import android.util.AtomicFile; import android.util.Slog; @@ -143,8 +144,7 @@ public class BootReceiver extends BroadcastReceiver { HashMap timestamps = readTimestamps(); if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) { - if ("encrypted".equals(SystemProperties.get("ro.crypto.state")) - && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))) { + if (StorageManager.inCryptKeeperBounce()) { // Encrypted, first boot to get PIN/pattern/password so data is tmpfs // Don't set ro.runtime.firstboot so that we will do this again // when data is properly mounted diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 6029c23ab30b0..312d3c5dc650f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -684,7 +684,7 @@ public class KeyguardViewMediator extends SystemUI { doKeyguardLocked(null); mUpdateMonitor.registerCallback(mUpdateCallback); } - mIsPerUserLock = StorageManager.isFileBasedEncryptionEnabled(); + mIsPerUserLock = StorageManager.isFileEncryptedNativeOrEmulated(); // Most services aren't available until the system reaches the ready state, so we // send it here when the device first boots. maybeSendUserPresentBroadcast(); diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java index 93131488f5093..8ca675a904c41 100644 --- a/services/core/java/com/android/server/DiskStatsService.java +++ b/services/core/java/com/android/server/DiskStatsService.java @@ -80,7 +80,7 @@ public class DiskStatsService extends Binder { reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw); reportFreeSpace(new File("/system"), "System", pw); - if (StorageManager.isNativeFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOnly()) { pw.println("File-based Encryption: true"); } diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index a3322fc996772..4536e048df9da 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -839,11 +839,11 @@ class MountService extends IMountService.Stub Slog.d(TAG, "Thinking about init, mSystemReady=" + mSystemReady + ", mDaemonConnected=" + mDaemonConnected); if (mSystemReady && mDaemonConnected - && !StorageManager.isNativeFileBasedEncryptionEnabled()) { + && !StorageManager.isFileEncryptedNativeOnly()) { // 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 boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly(); Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked); final List users = mContext.getSystemService(UserManager.class).getUsers(); for (UserInfo user : users) { @@ -1940,7 +1940,7 @@ class MountService extends IMountService.Stub waitForReady(); if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) { - if (StorageManager.isNativeFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOnly()) { throw new IllegalStateException( "Emulation not available on device with native FBE"); } @@ -2811,7 +2811,7 @@ class MountService extends IMountService.Stub @Override public boolean isUserKeyUnlocked(int userId) { - if (StorageManager.isFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { synchronized (mLock) { return ArrayUtils.contains(mLocalUnlockedUsers, userId); } diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java index 73d8bddc5e609..30e0ceb52af30 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -446,7 +446,7 @@ public class SystemConfig { // Some devices can be field-converted to FBE, so offer to splice in // those features if not already defined by the static config - if (StorageManager.isNativeFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOnly()) { addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0); addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f07c1d05e29ac..7ff3e6673862f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -10886,7 +10886,7 @@ public final class ActivityManagerService extends ActivityManagerNative * belonging to any running apps. */ private void installEncryptionUnawareProviders(int userId) { - if (!StorageManager.isFileBasedEncryptionEnabled()) { + if (!StorageManager.isFileEncryptedNativeOrEmulated()) { // TODO: eventually pivot this back to look at current user state, // similar to the comment in UserManager.isUserUnlocked(), but for // now, if we started apps when "unlocked" then unaware providers diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 4a5df7a42f25f..59c2682bdb0ff 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -584,7 +584,7 @@ final class UserController { } } else { Slog.w(TAG, "Mount service not published; guessing locked state based on property"); - return !StorageManager.isFileBasedEncryptionEnabled(); + return !StorageManager.isFileEncryptedNativeOrEmulated(); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index e180e0501d983..debe072b7b98b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2449,7 +2449,7 @@ public class PackageManagerService extends IPackageManager.Stub { // since core system apps like SettingsProvider and SystemUI // can't wait for user to start final int storageFlags; - if (StorageManager.isFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { storageFlags = StorageManager.FLAG_STORAGE_DE; } else { storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; @@ -3231,7 +3231,7 @@ public class PackageManagerService extends IPackageManager.Stub { * Return if the user key is currently unlocked. */ private boolean isUserKeyUnlocked(int userId) { - if (StorageManager.isFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { final IMountService mount = IMountService.Stub .asInterface(ServiceManager.getService("mount")); if (mount == null) { @@ -18313,7 +18313,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); * the app. */ private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { - if (pkg.isSystemApp() && !StorageManager.isFileBasedEncryptionEnabled() + if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) { final int storageTarget = pkg.applicationInfo.isForceDeviceEncrypted() ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 4831db5f3dc3b..9a75dc98e6c0e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1637,9 +1637,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } // Still at the first stage of CryptKeeper double bounce, mOwners.hasDeviceOwner is // always false at this point. - if ("encrypted".equals(mInjector.systemPropertiesGet("ro.crypto.state")) - && "trigger_restart_min_framework".equals( - mInjector.systemPropertiesGet("vold.decrypt"))){ + if (StorageManager.inCryptKeeperBounce()) { return; } @@ -4864,17 +4862,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}. */ private int getEncryptionStatus() { - String status = mInjector.systemPropertiesGet("ro.crypto.state", "unsupported"); - if ("encrypted".equalsIgnoreCase(status)) { - final long token = mInjector.binderClearCallingIdentity(); - try { - return LockPatternUtils.isDeviceEncrypted() - ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE - : DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY; - } finally { - mInjector.binderRestoreCallingIdentity(token); - } - } else if ("unencrypted".equalsIgnoreCase(status)) { + if (!StorageManager.isNonDefaultBlockEncrypted()) { + return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY; + } else if (StorageManager.isEncrypted()) { + return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE; + } else if (StorageManager.isEncryptable()) { return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE; } else { return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;