summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--cmds/sm/src/com/android/commands/sm/Sm.java10
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java18
-rw-r--r--core/java/android/content/pm/PackageParser.java16
-rw-r--r--core/java/android/os/storage/IMountService.java170
-rw-r--r--core/java/android/os/storage/StorageManager.java50
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java7
-rw-r--r--core/res/AndroidManifest.xml8
-rw-r--r--core/res/res/values/attrs_manifest.xml1
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--packages/DefaultContainerService/AndroidManifest.xml4
-rw-r--r--packages/FakeOemFeatures/AndroidManifest.xml4
-rw-r--r--packages/FusedLocation/AndroidManifest.xml6
-rw-r--r--packages/InputDevices/AndroidManifest.xml4
-rw-r--r--packages/Keyguard/AndroidManifest.xml4
-rw-r--r--packages/SettingsProvider/AndroidManifest.xml9
-rw-r--r--packages/Shell/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/AndroidManifest.xml4
-rw-r--r--packages/services/Proxy/AndroidManifest.xml4
-rw-r--r--services/core/java/com/android/server/MountService.java125
-rw-r--r--services/core/java/com/android/server/am/UserController.java37
-rw-r--r--services/core/java/com/android/server/am/UserState.java8
-rw-r--r--services/core/java/com/android/server/pm/Installer.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java39
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java17
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java9
27 files changed, 428 insertions, 145 deletions
diff --git a/api/current.txt b/api/current.txt
index c161242260d0..dabc08491173 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -499,6 +499,7 @@ package android {
field public static final int ellipsize = 16842923; // 0x10100ab
field public static final int ems = 16843096; // 0x1010158
field public static final int enabled = 16842766; // 0x101000e
+ field public static final int encryptionAware = 16844038; // 0x1010506
field public static final int end = 16843996; // 0x10104dc
field public static final int endColor = 16843166; // 0x101019e
field public static final deprecated int endYear = 16843133; // 0x101017d
@@ -559,6 +560,7 @@ package android {
field public static final int fontFamily = 16843692; // 0x10103ac
field public static final int fontFeatureSettings = 16843959; // 0x10104b7
field public static final int footerDividersEnabled = 16843311; // 0x101022f
+ field public static final int forceDeviceEncrypted = 16844037; // 0x1010505
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int foregroundTint = 16843885; // 0x101046d
diff --git a/api/system-current.txt b/api/system-current.txt
index 8729d84295b0..19d9aa2c484c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -591,6 +591,7 @@ package android {
field public static final int ellipsize = 16842923; // 0x10100ab
field public static final int ems = 16843096; // 0x1010158
field public static final int enabled = 16842766; // 0x101000e
+ field public static final int encryptionAware = 16844038; // 0x1010506
field public static final int end = 16843996; // 0x10104dc
field public static final int endColor = 16843166; // 0x101019e
field public static final deprecated int endYear = 16843133; // 0x101017d
@@ -651,6 +652,7 @@ package android {
field public static final int fontFamily = 16843692; // 0x10103ac
field public static final int fontFeatureSettings = 16843959; // 0x10104b7
field public static final int footerDividersEnabled = 16843311; // 0x101022f
+ field public static final int forceDeviceEncrypted = 16844037; // 0x1010505
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int foregroundTint = 16843885; // 0x101046d
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 1ee60b068694..b208e438f171 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -86,6 +86,8 @@ public final class Sm {
runBenchmark();
} else if ("forget".equals(op)) {
runForget();
+ } else if ("set-emulate-fbe".equals(op)) {
+ runSetEmulateFbe();
} else {
throw new IllegalArgumentException();
}
@@ -137,6 +139,12 @@ public final class Sm {
StorageManager.DEBUG_FORCE_ADOPTABLE);
}
+ public void runSetEmulateFbe() throws RemoteException {
+ final boolean emulateFbe = Boolean.parseBoolean(nextArg());
+ mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0,
+ StorageManager.DEBUG_EMULATE_FBE);
+ }
+
public void runPartition() throws RemoteException {
final String diskId = nextArg();
final String type = nextArg();
@@ -205,6 +213,8 @@ public final class Sm {
System.err.println("");
System.err.println(" sm forget [UUID|all]");
System.err.println("");
+ System.err.println(" sm set-emulate-fbe [true|false]");
+ System.err.println("");
return 1;
}
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 52c2f9bb4914..9c880d3591c3 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -22,7 +22,9 @@ import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Printer;
@@ -469,6 +471,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED = 1 << 5;
/**
+ * When set, assume that all components under the given app are encryption
+ * aware, unless otherwise specified.
+ *
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_ENCRYPTION_AWARE = 1 << 6;
+
+ /**
* Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
* {@hide}
*/
@@ -963,7 +973,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
.getDataUserCredentialEncryptedPackageDirectory(volumeUuid, userId, packageName)
.getAbsolutePath();
- if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0) {
+ if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0
+ && SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false)) {
dataDir = deviceEncryptedDataDir;
} else {
dataDir = credentialEncryptedDataDir;
@@ -1030,6 +1041,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
&& (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
+ /** @hide */
+ public boolean isEncryptionAware() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_ENCRYPTION_AWARE) != 0;
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f176d89925ea..838da37c365d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2636,6 +2636,10 @@ public class PackageParser {
&& (flags & PARSE_IS_SYSTEM) != 0) {
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED;
}
+ if (sa.getBoolean(R.styleable.AndroidManifestApplication_encryptionAware, false)
+ && (flags & PARSE_IS_SYSTEM) != 0) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ENCRYPTION_AWARE;
+ }
String str;
str = sa.getNonConfigurationString(
@@ -3236,7 +3240,8 @@ public class PackageParser {
sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
a.info.encryptionAware = sa.getBoolean(
- R.styleable.AndroidManifestActivity_encryptionAware, false);
+ R.styleable.AndroidManifestActivity_encryptionAware,
+ owner.applicationInfo.isEncryptionAware());
} else {
a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
a.info.configChanges = 0;
@@ -3253,7 +3258,8 @@ public class PackageParser {
}
a.info.encryptionAware = sa.getBoolean(
- R.styleable.AndroidManifestActivity_encryptionAware, false);
+ R.styleable.AndroidManifestActivity_encryptionAware,
+ owner.applicationInfo.isEncryptionAware());
}
sa.recycle();
@@ -3655,7 +3661,8 @@ public class PackageParser {
}
p.info.encryptionAware = sa.getBoolean(
- R.styleable.AndroidManifestProvider_encryptionAware, false);
+ R.styleable.AndroidManifestProvider_encryptionAware,
+ owner.applicationInfo.isEncryptionAware());
sa.recycle();
@@ -3938,7 +3945,8 @@ public class PackageParser {
}
s.info.encryptionAware = sa.getBoolean(
- R.styleable.AndroidManifestService_encryptionAware, false);
+ R.styleable.AndroidManifestService_encryptionAware,
+ owner.applicationInfo.isEncryptionAware());
sa.recycle();
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 5d45ade4e041..d19c7c979501 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1198,29 +1198,97 @@ public interface IMountService extends IInterface {
}
@Override
- public void createNewUserDir(int userHandle, String path) throws RemoteException {
+ public void createUserKey(int userId, int serialNumber) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userHandle);
- _data.writeString(path);
- mRemote.transact(Stub.TRANSACTION_createNewUserDir, _data, _reply, 0);
+ _data.writeInt(userId);
+ _data.writeInt(serialNumber);
+ mRemote.transact(Stub.TRANSACTION_createUserKey, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
+ public void destroyUserKey(int userId) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(userId);
+ mRemote.transact(Stub.TRANSACTION_destroyUserKey, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
+ public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(userId);
+ _data.writeInt(serialNumber);
+ _data.writeByteArray(token);
+ mRemote.transact(Stub.TRANSACTION_unlockUserKey, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
+ public void lockUserKey(int userId) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(userId);
+ mRemote.transact(Stub.TRANSACTION_lockUserKey, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
+ public boolean isUserKeyUnlocked(int userId) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ boolean _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(userId);
+ mRemote.transact(Stub.TRANSACTION_isUserKeyUnlocked, _data, _reply, 0);
_reply.readException();
+ _result = 0 != _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
+ return _result;
}
@Override
- public void deleteUserKey(int userHandle) throws RemoteException {
+ public void prepareUserStorage(String volumeUuid, int userId, int serialNumber)
+ throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userHandle);
- mRemote.transact(Stub.TRANSACTION_deleteUserKey, _data, _reply, 0);
+ _data.writeString(volumeUuid);
+ _data.writeInt(userId);
+ _data.writeInt(serialNumber);
+ mRemote.transact(Stub.TRANSACTION_prepareUserStorage, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
@@ -1359,13 +1427,17 @@ public interface IMountService extends IInterface {
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
- static final int TRANSACTION_createNewUserDir = IBinder.FIRST_CALL_TRANSACTION + 62;
+ static final int TRANSACTION_createUserKey = IBinder.FIRST_CALL_TRANSACTION + 61;
+ static final int TRANSACTION_destroyUserKey = IBinder.FIRST_CALL_TRANSACTION + 62;
- static final int TRANSACTION_deleteUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
+ static final int TRANSACTION_unlockUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
+ static final int TRANSACTION_lockUserKey = IBinder.FIRST_CALL_TRANSACTION + 64;
+ static final int TRANSACTION_isUserKeyUnlocked = IBinder.FIRST_CALL_TRANSACTION + 65;
- static final int TRANSACTION_isPerUserEncryptionEnabled = IBinder.FIRST_CALL_TRANSACTION + 64;
+ static final int TRANSACTION_prepareUserStorage = IBinder.FIRST_CALL_TRANSACTION + 66;
- static final int TRANSACTION_isConvertibleToFBE = IBinder.FIRST_CALL_TRANSACTION + 65;
+ static final int TRANSACTION_isPerUserEncryptionEnabled = IBinder.FIRST_CALL_TRANSACTION + 67;
+ static final int TRANSACTION_isConvertibleToFBE = IBinder.FIRST_CALL_TRANSACTION + 68;
/**
* Cast an IBinder object into an IMountService interface, generating a
@@ -1929,18 +2001,51 @@ public interface IMountService extends IInterface {
reply.writeNoException();
return true;
}
- case TRANSACTION_createNewUserDir: {
+ case TRANSACTION_createUserKey: {
data.enforceInterface(DESCRIPTOR);
- int userHandle = data.readInt();
- String path = data.readString();
- createNewUserDir(userHandle, path);
+ int userId = data.readInt();
+ int serialNumber = data.readInt();
+ createUserKey(userId, serialNumber);
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_destroyUserKey: {
+ data.enforceInterface(DESCRIPTOR);
+ int userId = data.readInt();
+ destroyUserKey(userId);
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_unlockUserKey: {
+ data.enforceInterface(DESCRIPTOR);
+ int userId = data.readInt();
+ int serialNumber = data.readInt();
+ byte[] token = data.createByteArray();
+ unlockUserKey(userId, serialNumber, token);
reply.writeNoException();
return true;
}
- case TRANSACTION_deleteUserKey: {
+ case TRANSACTION_lockUserKey: {
data.enforceInterface(DESCRIPTOR);
- int userHandle = data.readInt();
- deleteUserKey(userHandle);
+ int userId = data.readInt();
+ lockUserKey(userId);
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_isUserKeyUnlocked: {
+ data.enforceInterface(DESCRIPTOR);
+ int userId = data.readInt();
+ boolean result = isUserKeyUnlocked(userId);
+ reply.writeNoException();
+ reply.writeInt(result ? 1 : 0);
+ return true;
+ }
+ case TRANSACTION_prepareUserStorage: {
+ data.enforceInterface(DESCRIPTOR);
+ String volumeUuid = data.readString();
+ int userId = data.readInt();
+ int serialNumber = data.readInt();
+ prepareUserStorage(volumeUuid, userId, serialNumber);
reply.writeNoException();
return true;
}
@@ -1948,7 +2053,7 @@ public interface IMountService extends IInterface {
data.enforceInterface(DESCRIPTOR);
boolean result = isPerUserEncryptionEnabled();
reply.writeNoException();
- reply.writeInt((result ? 1 : 0));
+ reply.writeInt(result ? 1 : 0);
return true;
}
}
@@ -2263,24 +2368,15 @@ public interface IMountService extends IInterface {
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
throws RemoteException;
- /**
- * Creates the user data directory, possibly encrypted
- * @param userHandle Handle of the user whose directory we are creating
- * @param path Path at which to create the directory.
- */
- public void createNewUserDir(int userHandle, String path)
- throws RemoteException;
+ public void createUserKey(int userId, int serialNumber) throws RemoteException;
+ public void destroyUserKey(int userId) throws RemoteException;
- /**
- * Securely delete the user's encryption key
- * @param userHandle Handle of the user whose key we are deleting
- */
- public void deleteUserKey(int userHandle)
- throws RemoteException;
+ public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException;
+ public void lockUserKey(int userId) throws RemoteException;
+ public boolean isUserKeyUnlocked(int userId) throws RemoteException;
- /**
- * Returns whether the current encryption type is per user.
- */
- public boolean isPerUserEncryptionEnabled()
- throws RemoteException;
+ public void prepareUserStorage(String volumeUuid, int userId, int serialNumber)
+ throws RemoteException;
+
+ public boolean isPerUserEncryptionEnabled() throws RemoteException;
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 2ca0b206ef7b..27df46d7ee0e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -76,7 +76,11 @@ public class StorageManager {
/** {@hide} */
public static final String PROP_HAS_ADOPTABLE = "vold.has_adoptable";
/** {@hide} */
+ public static final String PROP_HAS_FBE = "vold.has_fbe";
+ /** {@hide} */
public static final String PROP_FORCE_ADOPTABLE = "persist.fw.force_adoptable";
+ /** {@hide} */
+ public static final String PROP_EMULATE_FBE = "vold.emulate_fbe";
/** {@hide} */
public static final String UUID_PRIVATE_INTERNAL = null;
@@ -85,6 +89,8 @@ public class StorageManager {
/** {@hide} */
public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
+ /** {@hide} */
+ public static final int DEBUG_EMULATE_FBE = 1 << 1;
/** {@hide} */
public static final int FLAG_FOR_WRITE = 1 << 0;
@@ -960,18 +966,54 @@ public class StorageManager {
}
/** {@hide} */
- public void createNewUserDir(int userHandle, File path) {
+ public void createUserKey(int userId, int serialNumber) {
+ try {
+ mMountService.createUserKey(userId, serialNumber);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
+ public void destroyUserKey(int userId) {
+ try {
+ mMountService.destroyUserKey(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
+ public void unlockUserKey(int userId, int serialNumber, byte[] token) {
+ try {
+ mMountService.unlockUserKey(userId, serialNumber, token);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
+ public void lockUserKey(int userId) {
+ try {
+ mMountService.lockUserKey(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
+ public void prepareUserStorage(String volumeUuid, int userId, int serialNumber) {
try {
- mMountService.createNewUserDir(userHandle, path.getAbsolutePath());
+ mMountService.prepareUserStorage(volumeUuid, userId, serialNumber);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
/** {@hide} */
- public void deleteUserKey(int userHandle) {
+ public boolean isUserKeyUnlocked(int userId) {
try {
- mMountService.deleteUserKey(userHandle);
+ return mMountService.isUserKeyUnlocked(userId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index f190d8cf9f0a..e8970bc9bbb1 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -144,6 +144,13 @@ public class ArrayUtils {
}
/**
+ * Checks if given array is null or has zero elements.
+ */
+ public static boolean isEmpty(byte[] array) {
+ return array == null || array.length == 0;
+ }
+
+ /**
* Checks that value is present as at least one of the elements of the array.
* @param array the array to check in
* @param value the value to check for
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 561bcbc26d0c..6bdf71bdba6f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1683,6 +1683,10 @@
<permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
android:protectionLevel="system|signature" />
+ <!-- @hide -->
+ <permission android:name="android.permission.STORAGE_INTERNAL"
+ android:protectionLevel="signature" />
+
<!-- Allows access to ASEC non-destructive API calls
@hide -->
<permission android:name="android.permission.ASEC_ACCESS"
@@ -2702,7 +2706,9 @@
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_android"
android:supportsRtl="true"
- android:theme="@style/Theme.Material.DayNight.DarkActionBar">
+ android:theme="@style/Theme.Material.DayNight.DarkActionBar"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<activity android:name="com.android.internal.app.ChooserActivity"
android:theme="@style/Theme.DeviceDefault.Resolver"
android:finishOnCloseSystemDialogs="true"
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 184f2ab96a8c..e3769031810e 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1283,6 +1283,7 @@
<attr name="multiArch" />
<attr name="extractNativeLibs" />
<attr name="forceDeviceEncrypted" format="boolean" />
+ <attr name="encryptionAware" />
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
used to control access from other packages to specific components or
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 037f1c43d745..43a6acd9761a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2679,6 +2679,8 @@
<public type="attr" name="contextPopupMenuStyle" />
<public type="attr" name="textAppearancePopupMenuHeader" />
<public type="attr" name="windowBackgroundFallback" />
+ <public type="attr" name="forceDeviceEncrypted" />
+ <public type="attr" name="encryptionAware" />
<public type="style" name="Theme.Material.DayNight" />
<public type="style" name="Theme.Material.DayNight.DarkActionBar" />
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index e67c5542d40a..ccf1501602fe 100644
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -12,7 +12,9 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<application android:label="@string/service_name"
- android:allowBackup="false">
+ android:allowBackup="false"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<service android:name=".DefaultContainerService"
android:enabled="true"
diff --git a/packages/FakeOemFeatures/AndroidManifest.xml b/packages/FakeOemFeatures/AndroidManifest.xml
index 93b8b47db761..fe74ad87ac1d 100644
--- a/packages/FakeOemFeatures/AndroidManifest.xml
+++ b/packages/FakeOemFeatures/AndroidManifest.xml
@@ -11,7 +11,9 @@
android:allowClearUserData="false"
android:allowBackup="false"
android:hardwareAccelerated="true"
- android:label="Fake OEM Features">
+ android:label="Fake OEM Features"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<service android:name=".FakeCoreService" android:process=":core"
android:label="Fake OEM Core Service" />
diff --git a/packages/FusedLocation/AndroidManifest.xml b/packages/FusedLocation/AndroidManifest.xml
index 6a4d4bfc856a..ed84c0d3126c 100644
--- a/packages/FusedLocation/AndroidManifest.xml
+++ b/packages/FusedLocation/AndroidManifest.xml
@@ -28,7 +28,9 @@
<application
android:label="@string/app_label"
- android:process="system">
+ android:process="system"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<uses-library android:name="com.android.location.provider" />
@@ -37,7 +39,7 @@
version. -->
<service android:name="com.android.location.fused.FusedLocationService"
android:exported="true"
- android:permission="android.permission.WRITE_SECURE_SETTINGS" >
+ android:permission="android.permission.WRITE_SECURE_SETTINGS">
<intent-filter>
<action android:name="com.android.location.service.FusedLocationProvider" />
</intent-filter>
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
index f0e4abcb58bf..07885ea6f04b 100644
--- a/packages/InputDevices/AndroidManifest.xml
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -6,7 +6,9 @@
<application
android:allowClearUserData="false"
android:label="@string/app_label"
- android:process="system">
+ android:process="system"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<receiver android:name=".InputDeviceReceiver"
android:label="@string/keyboard_layouts_label">
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
index e19246cdd561..54972b4bae29 100644
--- a/packages/Keyguard/AndroidManifest.xml
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -45,7 +45,9 @@
<application android:label="@string/app_name"
android:process="com.android.systemui"
android:persistent="true"
- android:supportsRtl="true">
+ android:supportsRtl="true"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
</application>
</manifest>
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 71aefad935fe..ba991fbe44f8 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -8,11 +8,12 @@
android:process="system"
android:backupAgent="SettingsBackupAgent"
android:killAfterRestore="false"
- android:icon="@mipmap/ic_launcher_settings">
-
- <!-- todo add: android:neverEncrypt="true" -->
+ android:icon="@mipmap/ic_launcher_settings"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
- <provider android:name="SettingsProvider" android:authorities="settings"
+ <provider android:name="SettingsProvider"
+ android:authorities="settings"
android:multiprocess="false"
android:exported="true"
android:singleUser="true"
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 05591cc9bc00..8c39ee654e6d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -108,7 +108,9 @@
<uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
<uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
- <application android:label="@string/app_label">
+ <application android:label="@string/app_label"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.android.shell"
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index be5c0fe143b2..6fda2c69b4ac 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -145,7 +145,9 @@
android:icon="@drawable/icon"
android:process="com.android.systemui"
android:supportsRtl="true"
- android:theme="@style/systemui_theme">
+ android:theme="@style/systemui_theme"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<!-- Keep theme in sync with SystemUIApplication.onCreate().
Setting the theme on the application does not affect views inflated by services.
The application theme is set again from onCreate to take effect for those views. -->
diff --git a/packages/services/Proxy/AndroidManifest.xml b/packages/services/Proxy/AndroidManifest.xml
index bbcd6b93bbb0..88f83813fe7f 100644
--- a/packages/services/Proxy/AndroidManifest.xml
+++ b/packages/services/Proxy/AndroidManifest.xml
@@ -7,7 +7,9 @@
<application
android:label="@string/app_label"
- android:process="com.android.proxyhandler">
+ android:process="com.android.proxyhandler"
+ android:forceDeviceEncrypted="true"
+ android:encryptionAware="true">
<service android:name=".ProxyService"
android:exported="true">
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 6e4f2388f478..37dd884c8dc7 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -96,6 +96,7 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.NativeDaemonConnector.Command;
@@ -119,6 +120,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -284,6 +286,8 @@ class MountService extends IMountService.Stub
@GuardedBy("mLock")
private int[] mStartedUsers = EmptyArray.INT;
+ @GuardedBy("mLock")
+ private int[] mUnlockedUsers = EmptyArray.INT;
/** Map from disk ID to disk */
@GuardedBy("mLock")
@@ -402,6 +406,17 @@ class MountService extends IMountService.Stub
}
}
+ private static String escapeNull(String arg) {
+ if (TextUtils.isEmpty(arg)) {
+ return "!";
+ } else {
+ if (arg.indexOf('\0') != -1 || arg.indexOf(' ') != -1) {
+ throw new IllegalArgumentException(arg);
+ }
+ return arg;
+ }
+ }
+
/** List of crypto types.
* These must match CRYPT_TYPE_XXX in cryptfs.h AND their
* corresponding commands in CommandListener.cpp */
@@ -1892,6 +1907,9 @@ class MountService extends IMountService.Stub
if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) {
mForceAdoptable = (flags & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0;
}
+ if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) {
+ // TODO: persist through vold and reboot
+ }
writeSettingsLocked();
mHandler.obtainMessage(H_RESET).sendToTarget();
@@ -2654,65 +2672,99 @@ class MountService extends IMountService.Stub
}
@Override
- public void createNewUserDir(int userHandle, String path) {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Only SYSTEM_UID can create user directories");
+ public void createUserKey(int userId, int serialNumber) {
+ enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+ waitForReady();
+
+ try {
+ mCryptConnector.execute("cryptfs", "create_user_key", userId, serialNumber);
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
}
+ }
+ @Override
+ public void destroyUserKey(int userId) {
+ enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
waitForReady();
- if (DEBUG_EVENTS) {
- Slog.i(TAG, "Creating new user dir");
+ try {
+ mCryptConnector.execute("cryptfs", "destroy_user_key", userId);
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+ @Override
+ public void unlockUserKey(int userId, int serialNumber, byte[] token) {
+ enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+ waitForReady();
+
+ final String encodedToken;
+ if (ArrayUtils.isEmpty(token)) {
+ encodedToken = "!";
+ } else {
+ encodedToken = HexDump.toHexString(token);
}
try {
- NativeDaemonEvent event = mCryptConnector.execute(
- "cryptfs", "createnewuserdir", userHandle, path);
- if (!"0".equals(event.getMessage())) {
- String error = "createnewuserdir sent unexpected message: "
- + event.getMessage();
- Slog.e(TAG, error);
- // ext4enc:TODO is this the right exception?
- throw new RuntimeException(error);
- }
+ mCryptConnector.execute("cryptfs", "unlock_user_key", userId, serialNumber,
+ new SensitiveArg(encodedToken));
} catch (NativeDaemonConnectorException e) {
- Slog.e(TAG, "createnewuserdir threw exception", e);
- throw new RuntimeException("createnewuserdir threw exception", e);
+ throw e.rethrowAsParcelableException();
+ }
+
+ synchronized (mLock) {
+ mUnlockedUsers = ArrayUtils.appendInt(mUnlockedUsers, userId);
}
}
- // ext4enc:TODO duplication between this and createNewUserDir is nasty
@Override
- public void deleteUserKey(int userHandle) {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Only SYSTEM_UID can delete user keys");
+ public void lockUserKey(int userId) {
+ enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+ waitForReady();
+
+ try {
+ mCryptConnector.execute("cryptfs", "lock_user_key", userId);
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
}
- waitForReady();
+ synchronized (mLock) {
+ mUnlockedUsers = ArrayUtils.removeInt(mUnlockedUsers, userId);
+ }
+ }
- if (DEBUG_EVENTS) {
- Slog.i(TAG, "Deleting user key");
+ @Override
+ public boolean isUserKeyUnlocked(int userId) {
+ if (SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false)) {
+ synchronized (mLock) {
+ return ArrayUtils.contains(mUnlockedUsers, userId);
+ }
+ } else {
+ return true;
}
+ }
+
+ @Override
+ public void prepareUserStorage(String volumeUuid, int userId, int serialNumber) {
+ enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+ waitForReady();
try {
- NativeDaemonEvent event = mCryptConnector.execute(
- "cryptfs", "deleteuserkey", userHandle);
- if (!"0".equals(event.getMessage())) {
- String error = "deleteuserkey sent unexpected message: "
- + event.getMessage();
- Slog.e(TAG, error);
- // ext4enc:TODO is this the right exception?
- throw new RuntimeException(error);
- }
+ mCryptConnector.execute("cryptfs", "prepare_user_storage", escapeNull(volumeUuid),
+ userId, serialNumber);
} catch (NativeDaemonConnectorException e) {
- Slog.e(TAG, "deleteuserkey threw exception", e);
- throw new RuntimeException("deleteuserkey threw exception", e);
+ throw e.rethrowAsParcelableException();
}
}
@Override
public boolean isPerUserEncryptionEnabled() {
- return "file".equals(SystemProperties.get("ro.crypto.type", "none"));
+ // TODO: switch this over to a single property; currently using two to
+ // handle the emulated case
+ return "file".equals(SystemProperties.get("ro.crypto.type", "none"))
+ || SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false);
}
@Override
@@ -3449,6 +3501,9 @@ class MountService extends IMountService.Stub
pw.println();
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));
}
synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index cbc13fee63dd..d6fced6a2b9a 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -18,7 +18,6 @@ package com.android.server.am;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-
import static android.app.ActivityManager.USER_OP_IS_CURRENT;
import static android.app.ActivityManager.USER_OP_SUCCESS;
import static android.os.Process.SYSTEM_UID;
@@ -57,8 +56,11 @@ import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -134,7 +136,9 @@ final class UserController {
mService = service;
mHandler = mService.mHandler;
// User 0 is the first and only user that runs at boot.
- mStartedUsers.put(UserHandle.USER_SYSTEM, new UserState(UserHandle.SYSTEM, true));
+ final UserState uss = new UserState(UserHandle.SYSTEM);
+ mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
+ updateUserUnlockedState(uss);
mUserLru.add(UserHandle.USER_SYSTEM);
updateStartedUserArrayLocked();
}
@@ -409,6 +413,21 @@ final class UserController {
return userManager;
}
+ private void updateUserUnlockedState(UserState uss) {
+ final IMountService mountService = IMountService.Stub
+ .asInterface(ServiceManager.getService(Context.STORAGE_SERVICE));
+ if (mountService != null) {
+ try {
+ uss.unlocked = mountService.isUserKeyUnlocked(uss.mHandle.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ } else {
+ // System isn't fully booted yet, so guess based on property
+ uss.unlocked = !SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false);
+ }
+ }
+
boolean startUser(final int userId, final boolean foreground) {
if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
@@ -453,11 +472,14 @@ final class UserController {
// If the user we are switching to is not currently started, then
// we need to start it now.
if (mStartedUsers.get(userId) == null) {
- mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
+ mStartedUsers.put(userId, new UserState(new UserHandle(userId)));
updateStartedUserArrayLocked();
needStart = true;
}
+ final UserState uss = mStartedUsers.get(userId);
+ updateUserUnlockedState(uss);
+
final Integer userIdInt = userId;
mUserLru.remove(userIdInt);
mUserLru.add(userIdInt);
@@ -479,8 +501,6 @@ final class UserController {
mUserLru.add(currentUserIdInt);
}
- final UserState uss = mStartedUsers.get(userId);
-
// Make sure user is in the started state. If it is currently
// stopping, we need to knock that off.
if (uss.mState == UserState.STATE_STOPPING) {
@@ -956,8 +976,11 @@ final class UserController {
return true;
}
if ((flags & ActivityManager.FLAG_WITH_AMNESIA) != 0) {
- // TODO: add in amnesia lifecycle
- return false;
+ // If user is currently locked, we fall through to default "running"
+ // behavior below
+ if (state.unlocked) {
+ return false;
+ }
}
return state.mState != UserState.STATE_STOPPING
&& state.mState != UserState.STATE_SHUTDOWN;
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index b3d82bca2de8..b5b5c1d06f6f 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -40,6 +40,7 @@ public final class UserState {
public int mState = STATE_BOOTING;
public boolean switching;
public boolean initializing;
+ public boolean unlocked;
/**
* The last time that a provider was reported to usage stats as being brought to important
@@ -47,7 +48,7 @@ public final class UserState {
*/
public final ArrayMap<String,Long> mProviderLastReportedFg = new ArrayMap<>();
- public UserState(UserHandle handle, boolean initial) {
+ public UserState(UserHandle handle) {
mHandle = handle;
}
@@ -62,6 +63,11 @@ public final class UserState {
}
if (switching) pw.print(" SWITCHING");
if (initializing) pw.print(" INITIALIZING");
+ if (unlocked) {
+ pw.print(" UNLOCKED");
+ } else {
+ pw.print(" LOCKED");
+ }
pw.println();
}
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 150c84932aca..99a051af1717 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -185,15 +185,6 @@ public final class Installer extends SystemService {
return mInstaller.execute(builder.toString());
}
- public int rename(String oldname, String newname) {
- StringBuilder builder = new StringBuilder("rename");
- builder.append(' ');
- builder.append(oldname);
- builder.append(' ');
- builder.append(newname);
- return mInstaller.execute(builder.toString());
- }
-
@Deprecated
public int fixUid(String name, int uid, int gid) {
return fixUid(null, name, uid, gid);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ad1cbe6172f7..64628aafbaa2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2981,23 +2981,25 @@ public class PackageManagerService extends IPackageManager.Stub {
* purposefully done before acquiring {@link #mPackages} lock.
*/
private int augmentFlagsForUser(int flags, int userId) {
- // TODO: bring back once locking fixed
-// final IActivityManager am = ActivityManagerNative.getDefault();
-// if (am == null) {
-// // We must be early in boot, so the best we can do is assume the
-// // user is fully running.
-// return flags;
-// }
-// final long token = Binder.clearCallingIdentity();
-// try {
-// if (am.isUserRunning(userId, ActivityManager.FLAG_WITH_AMNESIA)) {
-// flags |= PackageManager.FLAG_USER_RUNNING_WITH_AMNESIA;
-// }
-// } catch (RemoteException e) {
-// throw e.rethrowAsRuntimeException();
-// } finally {
-// Binder.restoreCallingIdentity(token);
-// }
+ if (SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false)) {
+ final IMountService mount = IMountService.Stub
+ .asInterface(ServiceManager.getService(Context.STORAGE_SERVICE));
+ if (mount == null) {
+ // We must be early in boot, so the best we can do is assume the
+ // user is fully running.
+ return flags;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ if (!mount.isUserKeyUnlocked(userId)) {
+ flags |= PackageManager.FLAG_USER_RUNNING_WITH_AMNESIA;
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
return flags;
}
@@ -15918,13 +15920,14 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ final StorageManager sm = mContext.getSystemService(StorageManager.class);
final UserManager um = mContext.getSystemService(UserManager.class);
for (UserInfo user : um.getUsers()) {
final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
if (userDir.exists()) continue;
try {
- UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id);
+ sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber);
UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
} catch (IOException e) {
Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 9a87abe09f0e..3a1d2de0d37c 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1563,13 +1563,15 @@ public class UserManagerService extends IUserManager.Stub {
userInfo.restrictedProfileParentId = parent.restrictedProfileParentId;
}
}
+
final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ storage.createUserKey(userId, userInfo.serialNumber);
for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
final String volumeUuid = vol.getFsUuid();
try {
final File userDir = Environment.getDataUserDirectory(volumeUuid,
userId);
- prepareUserDirectory(mContext, volumeUuid, userId);
+ storage.prepareUserStorage(volumeUuid, userId, userInfo.serialNumber);
enforceSerialNumber(userDir, userInfo.serialNumber);
} catch (IOException e) {
Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
@@ -1797,8 +1799,7 @@ public class UserManagerService extends IUserManager.Stub {
}
private void removeUserStateLILP(final int userHandle) {
- mContext.getSystemService(StorageManager.class)
- .deleteUserKey(userHandle);
+ mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
// Cleanup package manager settings
mPm.cleanUpUserLILPw(this, userHandle);
@@ -2183,16 +2184,6 @@ public class UserManagerService extends IUserManager.Stub {
}
/**
- * Create new {@code /data/user/[id]} directory and sets default
- * permissions.
- */
- public static void prepareUserDirectory(Context context, String volumeUuid, int userId) {
- final StorageManager storage = context.getSystemService(StorageManager.class);
- final File userDir = Environment.getDataUserDirectory(volumeUuid, userId);
- storage.createNewUserDir(userId, userDir);
- }
-
- /**
* Enforce that serial number stored in user directory inode matches the
* given expected value. Gracefully sets the serial number if currently
* undefined.
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index a96c164b545e..f396c2dbc5f0 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -291,21 +291,26 @@ public class VoiceInteractionManagerService extends SystemService {
String curService = Settings.Secure.getStringForUser(
mResolver, Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser);
ComponentName serviceComponent = null;
+ ServiceInfo serviceInfo = null;
if (curService != null && !curService.isEmpty()) {
try {
serviceComponent = ComponentName.unflattenFromString(curService);
- } catch (RuntimeException e) {
+ serviceInfo = AppGlobals.getPackageManager()
+ .getServiceInfo(serviceComponent, 0, mCurUser);
+ } catch (RuntimeException | RemoteException e) {
Slog.wtf(TAG, "Bad voice interaction service name " + curService, e);
serviceComponent = null;
+ serviceInfo = null;
}
}
+
if (force || mImpl == null || mImpl.mUser != mCurUser
|| !mImpl.mComponent.equals(serviceComponent)) {
mSoundTriggerHelper.stopAllRecognitions();
if (mImpl != null) {
mImpl.shutdownLocked();
}
- if (serviceComponent != null) {
+ if (serviceComponent != null && serviceInfo != null) {
mImpl = new VoiceInteractionManagerServiceImpl(mContext,
UiThread.getHandler(), this, mCurUser, serviceComponent);
mImpl.startLocked();