Merge "More APIs for encryption-aware apps."
diff --git a/api/current.txt b/api/current.txt
index d330dad..5eb08da 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9062,6 +9062,7 @@
field public android.content.pm.ApplicationInfo applicationInfo;
field public int descriptionRes;
field public boolean enabled;
+ field public boolean encryptionAware;
field public boolean exported;
field public java.lang.String processName;
}
@@ -9483,6 +9484,7 @@
field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
field public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
field public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
+ field public static final int GET_ENCRYPTION_UNAWARE_COMPONENTS = 262144; // 0x40000
field public static final int GET_GIDS = 256; // 0x100
field public static final int GET_INSTRUMENTATION = 16; // 0x10
field public static final int GET_INTENT_FILTERS = 32; // 0x20
diff --git a/api/system-current.txt b/api/system-current.txt
index f101856..dd2e67d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9322,6 +9322,7 @@
field public android.content.pm.ApplicationInfo applicationInfo;
field public int descriptionRes;
field public boolean enabled;
+ field public boolean encryptionAware;
field public boolean exported;
field public java.lang.String processName;
}
@@ -9780,6 +9781,7 @@
field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
field public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
field public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
+ field public static final int GET_ENCRYPTION_UNAWARE_COMPONENTS = 262144; // 0x40000
field public static final int GET_GIDS = 256; // 0x100
field public static final int GET_INSTRUMENTATION = 16; // 0x10
field public static final int GET_INTENT_FILTERS = 32; // 0x20
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b809baa..ac54960 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2952,6 +2952,11 @@
}
}
+ /** {@hide} */
+ public static final int FLAG_OR_STOPPED = 1 << 0;
+ /** {@hide} */
+ public static final int FLAG_WITH_AMNESIA = 1 << 1;
+
/**
* Return whether the given user is actively running. This means that
* the user is in the "started" state, not "stopped" -- it is currently
@@ -2963,7 +2968,7 @@
*/
public boolean isUserRunning(int userid) {
try {
- return ActivityManagerNative.getDefault().isUserRunning(userid, false);
+ return ActivityManagerNative.getDefault().isUserRunning(userid, 0);
} catch (RemoteException e) {
return false;
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 2ac6cf9..4449e4f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1984,8 +1984,8 @@
case IS_USER_RUNNING_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int userid = data.readInt();
- boolean orStopping = data.readInt() != 0;
- boolean result = isUserRunning(userid, orStopping);
+ int _flags = data.readInt();
+ boolean result = isUserRunning(userid, _flags);
reply.writeNoException();
reply.writeInt(result ? 1 : 0);
return true;
@@ -5265,12 +5265,12 @@
return userInfo;
}
- public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException {
+ public boolean isUserRunning(int userid, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(userid);
- data.writeInt(orStopping ? 1 : 0);
+ data.writeInt(flags);
mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
reply.readException();
boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index fcc040b..b69a480 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -392,7 +392,7 @@
public boolean startUserInBackground(int userid) throws RemoteException;
public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
public UserInfo getCurrentUser() throws RemoteException;
- public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
+ public boolean isUserRunning(int userid, int flags) throws RemoteException;
public int[] getRunningUserIds() throws RemoteException;
public boolean removeTask(int taskId) throws RemoteException;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6bc2ac3..52c2f9b 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -466,7 +466,7 @@
*
* @hide
*/
- public static final int PRIVATE_FLAG_DEVICE_ENCRYPTED = 1 << 5;
+ public static final int PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED = 1 << 5;
/**
* Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
@@ -963,7 +963,7 @@
.getDataUserCredentialEncryptedPackageDirectory(volumeUuid, userId, packageName)
.getAbsolutePath();
- if ((privateFlags & PRIVATE_FLAG_DEVICE_ENCRYPTED) != 0) {
+ if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0) {
dataDir = deviceEncryptedDataDir;
} else {
dataDir = credentialEncryptedDataDir;
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index f27fc2a..ad7ebe5 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -63,7 +63,14 @@
* <provider> tag.
*/
public boolean exported = false;
-
+
+ /**
+ * Indicate if this component is aware of encryption lifecycle, and can be
+ * safely run before the user has entered their credentials (such as a lock
+ * pattern or PIN).
+ */
+ public boolean encryptionAware = false;
+
public ComponentInfo() {
}
@@ -74,6 +81,7 @@
descriptionRes = orig.descriptionRes;
enabled = orig.enabled;
exported = orig.exported;
+ encryptionAware = orig.encryptionAware;
}
@Override public CharSequence loadLabel(PackageManager pm) {
@@ -143,7 +151,7 @@
protected void dumpFront(Printer pw, String prefix) {
super.dumpFront(pw, prefix);
pw.println(prefix + "enabled=" + enabled + " exported=" + exported
- + " processName=" + processName);
+ + " encryptionAware=" + encryptionAware + " processName=" + processName);
if (descriptionRes != 0) {
pw.println(prefix + "description=" + descriptionRes);
}
@@ -171,6 +179,7 @@
dest.writeInt(descriptionRes);
dest.writeInt(enabled ? 1 : 0);
dest.writeInt(exported ? 1 : 0);
+ dest.writeInt(encryptionAware ? 1 : 0);
}
protected ComponentInfo(Parcel source) {
@@ -183,6 +192,7 @@
descriptionRes = source.readInt();
enabled = (source.readInt() != 0);
exported = (source.readInt() != 0);
+ encryptionAware = (source.readInt() != 0);
}
/**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c57fc89..566de4e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -234,6 +234,24 @@
public static final int MATCH_ALL = 0x00020000;
/**
+ * {@link PackageInfo} flag: include components which aren't encryption
+ * aware in the returned info, regardless of the current user state.
+ */
+ public static final int GET_ENCRYPTION_UNAWARE_COMPONENTS = 0x00040000;
+
+ /**
+ * {@link PackageInfo} flag: return components as if the given user is
+ * running with amnesia. This typically limits the component to only those
+ * marked as {@link ComponentInfo#encryptionAware}, unless
+ * {@link #GET_ENCRYPTION_UNAWARE_COMPONENTS} is also specified.
+ * <p>
+ * This flag is for internal use only.
+ *
+ * @hide
+ */
+ public static final int FLAG_USER_RUNNING_WITH_AMNESIA = 0x00080000;
+
+ /**
* Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
* when resolving an intent that matches the {@link CrossProfileIntentFilter}, the current
* profile will be skipped.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 20e76d6..f176d89 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2632,6 +2632,11 @@
ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
}
+ if (sa.getBoolean(R.styleable.AndroidManifestApplication_forceDeviceEncrypted, false)
+ && (flags & PARSE_IS_SYSTEM) != 0) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED;
+ }
+
String str;
str = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
@@ -3229,6 +3234,9 @@
a.info.lockTaskLaunchMode =
sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
+
+ a.info.encryptionAware = sa.getBoolean(
+ R.styleable.AndroidManifestActivity_encryptionAware, false);
} else {
a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
a.info.configChanges = 0;
@@ -3243,6 +3251,9 @@
setExported = true;
}
}
+
+ a.info.encryptionAware = sa.getBoolean(
+ R.styleable.AndroidManifestActivity_encryptionAware, false);
}
sa.recycle();
@@ -3643,6 +3654,9 @@
}
}
+ p.info.encryptionAware = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_encryptionAware, false);
+
sa.recycle();
if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
@@ -3923,6 +3937,9 @@
}
}
+ s.info.encryptionAware = sa.getBoolean(
+ R.styleable.AndroidManifestService_encryptionAware, false);
+
sa.recycle();
if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index e892349..aff90b7 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -718,7 +718,7 @@
public boolean isUserRunning(UserHandle user) {
try {
return ActivityManagerNative.getDefault().isUserRunning(
- user.getIdentifier(), false);
+ user.getIdentifier(), 0);
} catch (RemoteException e) {
return false;
}
@@ -733,8 +733,9 @@
*/
public boolean isUserRunningOrStopping(UserHandle user) {
try {
+ // TODO: reconcile stopped vs stopping?
return ActivityManagerNative.getDefault().isUserRunning(
- user.getIdentifier(), true);
+ user.getIdentifier(), ActivityManager.FLAG_OR_STOPPED);
} catch (RemoteException e) {
return false;
}
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 07ac471..184f2ab 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -571,6 +571,11 @@
single integer, with higher numbers considered to be better. -->
<attr name="priority" format="integer" />
+ <!-- Indicate if this component is aware of encryption lifecycle, and can be
+ safely run before the user has entered their credentials (such as a lock
+ pattern or PIN). -->
+ <attr name="encryptionAware" format="boolean" />
+
<!-- Specify how an activity should be launched. See the
<a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
Stack</a> document for important information on how these options impact
@@ -1277,6 +1282,7 @@
<attr name="usesCleartextTraffic" />
<attr name="multiArch" />
<attr name="extractNativeLibs" />
+ <attr name="forceDeviceEncrypted" format="boolean" />
</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
@@ -1652,6 +1658,7 @@
<attr name="enabled" />
<attr name="exported" />
<attr name="singleUser" />
+ <attr name="encryptionAware" />
</declare-styleable>
<!-- Attributes that can be supplied in an AndroidManifest.xml
@@ -1735,6 +1742,7 @@
with it is through the Service API (binding and starting). -->
<attr name="isolatedProcess" format="boolean" />
<attr name="singleUser" />
+ <attr name="encryptionAware" />
</declare-styleable>
<!-- The <code>receiver</code> tag declares an
@@ -1770,6 +1778,7 @@
<attr name="enabled" />
<attr name="exported" />
<attr name="singleUser" />
+ <attr name="encryptionAware" />
</declare-styleable>
<!-- The <code>activity</code> tag declares an
@@ -1842,6 +1851,7 @@
<attr name="supportsPictureInPicture" />
<attr name="lockTaskMode" />
<attr name="showForAllUsers" />
+ <attr name="encryptionAware" />
</declare-styleable>
<!-- The <code>activity-alias</code> tag declares a new
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 1ff13b2..9ac4ba3 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -980,7 +980,7 @@
if (user.isRestricted() && (parentUserId == user.restrictedProfileParentId)) {
addSharedAccountAsUser(account, user.id);
try {
- if (ActivityManagerNative.getDefault().isUserRunning(user.id, false)) {
+ if (ActivityManagerNative.getDefault().isUserRunning(user.id, 0)) {
mMessageHandler.sendMessage(mMessageHandler.obtainMessage(
MESSAGE_COPY_SHARED_ACCOUNT, parentUserId, user.id, account));
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index befaaef..2820216 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2334,7 +2334,7 @@
sr.userId, sr.crashCount, sr.shortName, app.pid);
bringDownServiceLocked(sr);
} else if (!allowRestart
- || !mAm.mUserController.isUserRunningLocked(sr.userId, false)) {
+ || !mAm.mUserController.isUserRunningLocked(sr.userId, 0)) {
bringDownServiceLocked(sr);
} else {
boolean canceled = scheduleServiceRestartLocked(sr, true);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 13401cd..4998b57 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5328,7 +5328,7 @@
Slog.w(TAG, "Failed trying to unstop package "
+ packageName + ": " + e);
}
- if (mUserController.isUserRunningLocked(user, false)) {
+ if (mUserController.isUserRunningLocked(user, 0)) {
forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
}
}
@@ -9812,7 +9812,7 @@
// Make sure that the user who owns this provider is running. If not,
// we don't want to allow it to run.
- if (!mUserController.isUserRunningLocked(userId, false)) {
+ if (!mUserController.isUserRunningLocked(userId, 0)) {
Slog.w(TAG, "Unable to launch app "
+ cpi.applicationInfo.packageName + "/"
+ cpi.applicationInfo.uid + " for provider "
@@ -16640,7 +16640,7 @@
// If not, we will just skip it. Make an exception for shutdown broadcasts
// and upgrade steps.
- if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, false)) {
+ if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
if ((callingUid != Process.SYSTEM_UID
|| (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
&& !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
@@ -19991,7 +19991,7 @@
}
@Override
- public boolean isUserRunning(int userId, boolean orStopped) {
+ public boolean isUserRunning(int userId, int flags) {
if (checkCallingPermission(INTERACT_ACROSS_USERS)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: isUserRunning() from pid="
@@ -20002,7 +20002,7 @@
throw new SecurityException(msg);
}
synchronized (this) {
- return mUserController.isUserRunningLocked(userId, orStopped);
+ return mUserController.isUserRunningLocked(userId, flags);
}
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 4085489..cbc13fe 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -947,14 +947,18 @@
return mStartedUserArray;
}
- boolean isUserRunningLocked(int userId, boolean orStopped) {
+ boolean isUserRunningLocked(int userId, int flags) {
UserState state = getStartedUserStateLocked(userId);
if (state == null) {
return false;
}
- if (orStopped) {
+ if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
return true;
}
+ if ((flags & ActivityManager.FLAG_WITH_AMNESIA) != 0) {
+ // TODO: add in amnesia lifecycle
+ return false;
+ }
return state.mState != UserState.STATE_STOPPING
&& state.mState != UserState.STATE_SHUTDOWN;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 11fa38c..09efefa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3053,15 +3053,40 @@
}
}
+ /**
+ * Augment the given flags depending on current user running state. This is
+ * purposefully done before acquiring {@link #mPackages} lock.
+ */
+ private int augmentFlagsForUser(int flags, int userId) {
+ 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);
+ }
+ return flags;
+ }
+
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
- if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
+ if (a != null && mSettings.isEnabledAndVisibleLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
@@ -3100,12 +3125,13 @@
@Override
public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
synchronized (mPackages) {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
- if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
+ if (a != null && mSettings.isEnabledAndVisibleLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
@@ -3118,12 +3144,13 @@
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getServiceInfo " + component + ": " + s);
- if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
+ if (s != null && mSettings.isEnabledAndVisibleLPr(s.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
@@ -3136,12 +3163,13 @@
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
synchronized (mPackages) {
PackageParser.Provider p = mProviders.mProviders.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getProviderInfo " + component + ": " + p);
- if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
+ if (p != null && mSettings.isEnabledAndVisibleLPr(p.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
@@ -4233,6 +4261,7 @@
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
@@ -4374,10 +4403,12 @@
return null;
}
+ // TODO: handle preferred activities missing while user has amnesia
ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
List<ResolveInfo> query, int priority, boolean always,
boolean removeMatches, boolean debug, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
// writer
synchronized (mPackages) {
if (intent.getSelector() != null) {
@@ -4576,6 +4607,7 @@
public List<ResolveInfo> queryIntentActivities(Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
ComponentName comp = intent.getComponent();
if (comp == null) {
@@ -5041,6 +5073,7 @@
Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
+ flags = augmentFlagsForUser(flags, userId);
enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
false, "query intent activity options");
final String resultsAction = intent.getAction();
@@ -5213,6 +5246,7 @@
public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
+ flags = augmentFlagsForUser(flags, userId);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -5248,8 +5282,9 @@
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
- List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
+ List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
if (query != null) {
if (query.size() >= 1) {
// If there is more than one service with the same priority,
@@ -5264,6 +5299,7 @@
public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
+ flags = augmentFlagsForUser(flags, userId);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -5301,6 +5337,7 @@
public List<ResolveInfo> queryIntentContentProviders(
Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
+ flags = augmentFlagsForUser(flags, userId);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -5417,6 +5454,7 @@
public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
String[] permissions, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
@@ -5444,6 +5482,7 @@
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
@@ -5510,6 +5549,7 @@
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
// reader
synchronized (mPackages) {
final PackageParser.Provider provider = mProvidersByAuthority.get(name);
@@ -5517,7 +5557,7 @@
? mSettings.mPackages.get(provider.owner.packageName)
: null;
return ps != null
- && mSettings.isEnabledLPr(provider.info, flags, userId)
+ && mSettings.isEnabledAndVisibleLPr(provider.info, flags, userId)
&& (!mSafeMode || (provider.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)
? PackageParser.generateProviderInfo(provider, flags,
@@ -5558,12 +5598,15 @@
@Override
public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
int uid, int flags) {
+ final int userId = processName != null ? UserHandle.getUserId(uid)
+ : UserHandle.getCallingUserId();
+ if (!sUserManager.exists(userId)) return null;
+ flags = augmentFlagsForUser(flags, userId);
+
ArrayList<ProviderInfo> finalList = null;
// reader
synchronized (mPackages) {
final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
- final int userId = processName != null ?
- UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Provider p = i.next();
PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
@@ -5571,7 +5614,7 @@
&& (processName == null
|| (p.info.processName.equals(processName)
&& UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
- && mSettings.isEnabledLPr(p.info, flags, userId)
+ && mSettings.isEnabledAndVisibleLPr(p.info, flags, userId)
&& (!mSafeMode
|| (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
if (finalList == null) {
@@ -8975,7 +9018,7 @@
protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
int match, int userId) {
if (!sUserManager.exists(userId)) return null;
- if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
+ if (!mSettings.isEnabledAndVisibleLPr(info.activity.info, mFlags, userId)) {
return null;
}
final PackageParser.Activity activity = info.activity;
@@ -9199,7 +9242,7 @@
int match, int userId) {
if (!sUserManager.exists(userId)) return null;
final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
- if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
+ if (!mSettings.isEnabledAndVisibleLPr(info.service.info, mFlags, userId)) {
return null;
}
final PackageParser.Service service = info.service;
@@ -9422,7 +9465,7 @@
if (!sUserManager.exists(userId))
return null;
final PackageParser.ProviderIntentInfo info = filter;
- if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
+ if (!mSettings.isEnabledAndVisibleLPr(info.provider.info, mFlags, userId)) {
return null;
}
final PackageParser.Provider provider = info.provider;
@@ -9761,7 +9804,7 @@
IActivityManager am = ActivityManagerNative.getDefault();
final boolean isSystem =
isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
- if (isSystem && am.isUserRunning(userId, false)) {
+ if (isSystem && am.isUserRunning(userId, 0)) {
// The just-installed/enabled app is bundled on the system, so presumed
// to be able to run automatically without needing an explicit launch.
// Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8b99305..de14739 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2248,7 +2248,8 @@
StringBuilder sb = new StringBuilder();
for (final PackageSetting pkg : mPackages.values()) {
- if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
+ if (pkg.pkg == null || pkg.pkg.applicationInfo == null
+ || pkg.pkg.applicationInfo.dataDir == null) {
Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
continue;
}
@@ -3750,8 +3751,13 @@
private String compToString(ArraySet<String> cmp) {
return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
}
-
- boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
+
+ boolean isEnabledAndVisibleLPr(ComponentInfo componentInfo, int flags, int userId) {
+ return isEnabledLPr(componentInfo, flags, userId)
+ && isVisibleLPr(componentInfo, flags);
+ }
+
+ private boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
return true;
}
@@ -3792,6 +3798,17 @@
return componentInfo.enabled;
}
+ private boolean isVisibleLPr(ComponentInfo componentInfo, int flags) {
+ if ((flags & PackageManager.GET_ENCRYPTION_UNAWARE_COMPONENTS) != 0) {
+ return true;
+ }
+ if ((flags & PackageManager.FLAG_USER_RUNNING_WITH_AMNESIA) != 0) {
+ // When running with amnesia, we can only run encryption-aware apps
+ return componentInfo.encryptionAware;
+ }
+ return true;
+ }
+
String getInstallerPackageNameLPr(String packageName) {
final PackageSetting pkg = mPackages.get(packageName);
if (pkg == null) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4929960..3eb2d11 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2286,7 +2286,7 @@
} else {
pw.println("Users:");
for (int i = 0; i < users.size(); i++) {
- String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
+ String running = am.isUserRunning(users.get(i).id, 0) ? " running" : "";
pw.println("\t" + users.get(i).toString() + running);
}
return 0;