am 1a7cb969: Merge "Fix issue #16662560: SingleTop activity is getting instantiated multiple time" into lmp-dev
* commit '1a7cb969b833be16632cbcadc498a1fb978ca659':
Fix issue #16662560: SingleTop activity is getting instantiated multiple time
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e224ac0..a3f48f8 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -550,10 +550,10 @@
if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
+ taskIntent.getComponent().flattenToShortString()
- + "/aff=" + r.task.affinity + " to new cls="
+ + "/aff=" + r.task.rootAffinity + " to new cls="
+ intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
- if (!isDocument && !taskIsDocument && task.affinity != null) {
- if (task.affinity.equals(target.taskAffinity)) {
+ if (!isDocument && !taskIsDocument && task.rootAffinity != null) {
+ if (task.rootAffinity.equals(target.taskAffinity)) {
if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
return r;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 071db97..4de7367 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -58,6 +58,7 @@
private static final String ATTR_ORIGACTIVITY = "orig_activity";
private static final String TAG_ACTIVITY = "activity";
private static final String ATTR_AFFINITY = "affinity";
+ private static final String ATTR_ROOT_AFFINITY = "root_affinity";
private static final String ATTR_ROOTHASRESET = "root_has_reset";
private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
@@ -84,7 +85,8 @@
static final boolean IGNORE_RETURN_TO_RECENTS = true;
final int taskId; // Unique identifier for this task.
- String affinity; // The affinity name for this task, or null.
+ String affinity; // The affinity name for this task, or null; may change identity.
+ String rootAffinity; // Initial base affinity, or null; does not change from initial root.
final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
final IVoiceInteractor voiceInteractor; // Associated interactor to provide to app
Intent intent; // The original intent that started the task.
@@ -208,9 +210,9 @@
}
TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
- String _affinity, ComponentName _realActivity, ComponentName _origActivity,
- boolean _rootWasReset, boolean _autoRemoveRecents, boolean _askedCompatMode,
- int _taskType, int _userId, int _effectiveUid,
+ String _affinity, String _rootAffinity, ComponentName _realActivity,
+ ComponentName _origActivity, boolean _rootWasReset, boolean _autoRemoveRecents,
+ boolean _askedCompatMode, int _taskType, int _userId, int _effectiveUid,
String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
@@ -224,6 +226,7 @@
intent = _intent;
affinityIntent = _affinityIntent;
affinity = _affinity;
+ rootAffinity = _affinity;
voiceSession = null;
voiceInteractor = null;
realActivity = _realActivity;
@@ -279,6 +282,12 @@
}
affinity = info.taskAffinity;
+ if (intent == null) {
+ // If this task already has an intent associated with it, don't set the root
+ // affinity -- we don't want it changing after initially set, but the initially
+ // set value may be null.
+ rootAffinity = affinity;
+ }
effectiveUid = info.applicationInfo.uid;
stringName = null;
@@ -840,8 +849,17 @@
if (origActivity != null) {
out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
}
+ // Write affinity, and root affinity if it is different from affinity.
+ // We use the special string "@" for a null root affinity, so we can identify
+ // later whether we were given a root affinity or should just make it the
+ // same as the affinity.
if (affinity != null) {
out.attribute(null, ATTR_AFFINITY, affinity);
+ if (!affinity.equals(rootAffinity)) {
+ out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
+ }
+ } else if (rootAffinity != null) {
+ out.attribute(null, ATTR_ROOT_AFFINITY, rootAffinity != null ? rootAffinity : "@");
}
out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
@@ -901,6 +919,8 @@
ComponentName realActivity = null;
ComponentName origActivity = null;
String affinity = null;
+ String rootAffinity = null;
+ boolean hasRootAffinity = false;
boolean rootHasReset = false;
boolean autoRemoveRecents = false;
boolean askedCompatMode = false;
@@ -935,6 +955,9 @@
origActivity = ComponentName.unflattenFromString(attrValue);
} else if (ATTR_AFFINITY.equals(attrName)) {
affinity = attrValue;
+ } else if (ATTR_ROOT_AFFINITY.equals(attrName)) {
+ rootAffinity = attrValue;
+ hasRootAffinity = true;
} else if (ATTR_ROOTHASRESET.equals(attrName)) {
rootHasReset = Boolean.valueOf(attrValue);
} else if (ATTR_AUTOREMOVERECENTS.equals(attrName)) {
@@ -1007,6 +1030,12 @@
createLastTaskDescriptionIconFilename(taskId, lastActiveTime)));
}
+ if (!hasRootAffinity) {
+ rootAffinity = affinity;
+ } else if ("@".equals(rootAffinity)) {
+ rootAffinity = null;
+ }
+
if (effectiveUid <= 0) {
Intent checkIntent = intent != null ? intent : affinityIntent;
effectiveUid = 0;
@@ -1028,7 +1057,7 @@
}
final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
- affinityIntent, affinity, realActivity, origActivity, rootHasReset,
+ affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
@@ -1047,8 +1076,13 @@
pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
pw.print(" mCallingPackage="); pw.println(mCallingPackage);
- if (affinity != null) {
- pw.print(prefix); pw.print("affinity="); pw.println(affinity);
+ if (affinity != null || rootAffinity != null) {
+ pw.print(prefix); pw.print("affinity="); pw.print(affinity);
+ if (affinity == null || !affinity.equals(rootAffinity)) {
+ pw.print(" root="); pw.println(rootAffinity);
+ } else {
+ pw.println();
+ }
}
if (voiceSession != null || voiceInteractor != null) {
pw.print(prefix); pw.print("VOICE: session=0x");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d87fc2e..79c9955 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4311,7 +4311,7 @@
* grantPermissions will assume the package update is trying to
* expand its permissions.
*/
- grantPermissionsLPw(pkg, true);
+ grantPermissionsLPw(pkg, true, pkg.packageName);
mSettings.disableSystemPackageLPw(pkg.packageName);
}
}
@@ -6696,17 +6696,19 @@
if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
for (PackageParser.Package pkg : mPackages.values()) {
if (pkg != pkgInfo) {
- grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
+ grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
+ changingPkg);
}
}
}
if (pkgInfo != null) {
- grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
+ grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
}
}
- private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
+ private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
+ String packageOfInterest) {
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
@@ -6740,8 +6742,10 @@
}
if (bp == null || bp.packageSetting == null) {
- Slog.w(TAG, "Unknown permission " + name
- + " in package " + pkg.packageName);
+ if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+ Slog.w(TAG, "Unknown permission " + name
+ + " in package " + pkg.packageName);
+ }
continue;
}
@@ -6806,9 +6810,11 @@
gp.gids = appendInts(gp.gids, bp.gids);
}
} else {
- Slog.w(TAG, "Not granting permission " + perm
- + " to package " + pkg.packageName
- + " because it was previously installed without");
+ if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+ Slog.w(TAG, "Not granting permission " + perm
+ + " to package " + pkg.packageName
+ + " because it was previously installed without");
+ }
}
} else {
if (gp.grantedPermissions.remove(perm)) {
@@ -6822,11 +6828,13 @@
} else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
// Don't print warning for app op permissions, since it is fine for them
// not to be granted, there is a UI for the user to decide.
- Slog.w(TAG, "Not granting permission " + perm
- + " to package " + pkg.packageName
- + " (protectionLevel=" + bp.protectionLevel
- + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
- + ")");
+ if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+ Slog.w(TAG, "Not granting permission " + perm
+ + " to package " + pkg.packageName
+ + " (protectionLevel=" + bp.protectionLevel
+ + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ + ")");
+ }
}
}
}