summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2015-07-10 17:44:53 -0700
committerChristopher Tate <ctate@google.com>2015-07-13 17:01:14 -0700
commitf0d6cb38c47ee37583034dc3a68238ed13c91742 (patch)
tree697334197a4e363bccb6561029bbda7f6adb695a /services/core/java/com/android/server
parentc09544bb88ada53494d4a955d0450a22985b4799 (diff)
downloadframeworks_base-f0d6cb38c47ee37583034dc3a68238ed13c91742.zip
frameworks_base-f0d6cb38c47ee37583034dc3a68238ed13c91742.tar.gz
frameworks_base-f0d6cb38c47ee37583034dc3a68238ed13c91742.tar.bz2
Prioritize most-recently-enabled link-handling app
In the case when multiple apps handle a given web-link action, all of which have been marked as "launch the app instead of a browser" and so are otherwise ambiguous, always prefer the app that was most recently placed into the always-handle-links state. Bug 22051035 Change-Id: I3f43c19b0d7b74e9843445e41971bb5433affb1c
Diffstat (limited to 'services/core/java/com/android/server')
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java37
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java23
-rw-r--r--services/core/java/com/android/server/pm/Settings.java39
3 files changed, 75 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 13aca79..2f5b1f0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -284,7 +284,7 @@ public class PackageManagerService extends IPackageManager.Stub {
static final boolean DEBUG_PREFERRED = false;
static final boolean DEBUG_UPGRADE = false;
static final boolean DEBUG_DOMAIN_VERIFICATION = false;
- private static final boolean DEBUG_BACKUP = true;
+ private static final boolean DEBUG_BACKUP = false;
private static final boolean DEBUG_INSTALL = false;
private static final boolean DEBUG_REMOVE = false;
private static final boolean DEBUG_BROADCASTS = false;
@@ -4581,7 +4581,8 @@ public class PackageManagerService extends IPackageManager.Stub {
if (ps == null) {
continue;
}
- int status = getDomainVerificationStatusLPr(ps, parentUserId);
+ long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
+ int status = (int)(verificationState >> 32);
if (result == null) {
result = new CrossProfileDomainInfo();
result.resolveInfo =
@@ -4678,11 +4679,17 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
// Try to get the status from User settings first
- int status = getDomainVerificationStatusLPr(ps, userId);
+ long packedStatus = getDomainVerificationStatusLPr(ps, userId);
+ int status = (int)(packedStatus >> 32);
+ int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.i(TAG, " + always: " + info.activityInfo.packageName);
+ Slog.i(TAG, " + always: " + info.activityInfo.packageName
+ + " : linkgen=" + linkGeneration);
}
+ // Use link-enabled generation as preferredOrder, i.e.
+ // prefer newly-enabled over earlier-enabled.
+ info.preferredOrder = linkGeneration;
alwaysList.add(info);
} else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
if (DEBUG_DOMAIN_VERIFICATION) {
@@ -4698,7 +4705,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
- // First try to add the "always" resolution for the current user if there is any
+ // First try to add the "always" resolution(s) for the current user, if any
if (alwaysList.size() > 0) {
result.addAll(alwaysList);
// if there is an "always" for the parent user, add it.
@@ -4759,15 +4766,19 @@ public class PackageManagerService extends IPackageManager.Stub {
return result;
}
- private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
- int status = ps.getDomainVerificationStatusForUser(userId);
+ // Returns a packed value as a long:
+ //
+ // high 'int'-sized word: link status: undefined/ask/never/always.
+ // low 'int'-sized word: relative priority among 'always' results.
+ private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
+ long result = ps.getDomainVerificationStatusForUser(userId);
// if none available, get the master status
- if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
+ if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
if (ps.getIntentFilterVerificationInfo() != null) {
- status = ps.getIntentFilterVerificationInfo().getStatus();
+ result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
}
}
- return status;
+ return result;
}
private ResolveInfo querySkipCurrentProfileIntents(
@@ -12963,7 +12974,7 @@ public class PackageManagerService extends IPackageManager.Stub {
false, //hidden
null, null, null,
false, // blockUninstall
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+ INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
if (!isSystemApp(ps)) {
if (ps.isAnyInstalled(sUserManager.getUserIds())) {
// Other user still have this package installed, so all
@@ -14886,8 +14897,8 @@ public class PackageManagerService extends IPackageManager.Stub {
pw.println();
count = 0;
for (PackageSetting ps : allPackageSettings) {
- final int status = ps.getDomainVerificationStatusForUser(userId);
- if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
+ final long status = ps.getDomainVerificationStatusForUser(userId);
+ if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
continue;
}
pw.println(prefix + "Package: " + ps.name);
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 6f46f69..4faf75a 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -341,7 +341,8 @@ abstract class PackageSettingBase extends SettingBase {
void setUserState(int userId, int enabled, boolean installed, boolean stopped,
boolean notLaunched, boolean hidden,
String lastDisableAppCaller, ArraySet<String> enabledComponents,
- ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState) {
+ ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
+ int linkGeneration) {
PackageUserState state = modifyUserState(userId);
state.enabled = enabled;
state.installed = installed;
@@ -353,6 +354,7 @@ abstract class PackageSettingBase extends SettingBase {
state.disabledComponents = disabledComponents;
state.blockUninstall = blockUninstall;
state.domainVerificationStatus = domainVerifState;
+ state.appLinkGeneration = linkGeneration;
}
ArraySet<String> getEnabledComponents(int userId) {
@@ -449,12 +451,23 @@ abstract class PackageSettingBase extends SettingBase {
verificationInfo = info;
}
- int getDomainVerificationStatusForUser(int userId) {
- return readUserState(userId).domainVerificationStatus;
+ // Returns a packed value as a long:
+ //
+ // high 'int'-sized word: link status: undefined/ask/never/always.
+ // low 'int'-sized word: relative priority among 'always' results.
+ long getDomainVerificationStatusForUser(int userId) {
+ PackageUserState state = readUserState(userId);
+ long result = (long) state.appLinkGeneration;
+ result |= ((long) state.domainVerificationStatus) << 32;
+ return result;
}
- void setDomainVerificationStatusForUser(int status, int userId) {
- modifyUserState(userId).domainVerificationStatus = status;
+ void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
+ PackageUserState state = modifyUserState(userId);
+ state.domainVerificationStatus = status;
+ if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
+ state.appLinkGeneration = generation;
+ }
}
void clearDomainVerificationStatusForUser(int userId) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index bdcd714..312b7b3 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -87,6 +87,7 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.Xml;
import java.io.BufferedOutputStream;
@@ -196,6 +197,7 @@ final class Settings {
private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
private static final String ATTR_PACKAGE_NAME= "packageName";
private static final String ATTR_FINGERPRINT = "fingerprint";
+ private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
private final Object mLock;
@@ -294,6 +296,9 @@ final class Settings {
// For every user, it is used to find the package name of the default Browser App.
final SparseArray<String> mDefaultBrowserApp = new SparseArray<String>();
+ // App-link priority tracking, per-user
+ final SparseIntArray mNextAppLinkGeneration = new SparseIntArray();
+
final StringBuilder mReadMessages = new StringBuilder();
/**
@@ -624,7 +629,7 @@ final class Settings {
false, // hidden
null, null, null,
false, // blockUninstall
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+ INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
writePackageRestrictionsLPr(user.id);
}
}
@@ -1051,7 +1056,7 @@ final class Settings {
}
return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
}
- int status = ps.getDomainVerificationStatusForUser(userId);
+ int status = (int)(ps.getDomainVerificationStatusForUser(userId) >> 32);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
if (ps.getIntentFilterVerificationInfo() != null) {
status = ps.getIntentFilterVerificationInfo().getStatus();
@@ -1060,7 +1065,7 @@ final class Settings {
return status;
}
- boolean updateIntentFilterVerificationStatusLPw(String packageName, int status, int userId) {
+ boolean updateIntentFilterVerificationStatusLPw(String packageName, final int status, int userId) {
// Update the status for the current package
PackageSetting current = mPackages.get(packageName);
if (current == null) {
@@ -1070,7 +1075,15 @@ final class Settings {
return false;
}
- current.setDomainVerificationStatusForUser(status, userId);
+ final int alwaysGeneration;
+ if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
+ alwaysGeneration = mNextAppLinkGeneration.get(userId) + 1;
+ mNextAppLinkGeneration.put(userId, alwaysGeneration);
+ } else {
+ alwaysGeneration = 0;
+ }
+
+ current.setDomainVerificationStatusForUser(status, alwaysGeneration, userId);
return true;
}
@@ -1382,7 +1395,7 @@ final class Settings {
false, // hidden
null, null, null,
false, // blockUninstall
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+ INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
}
return;
}
@@ -1404,6 +1417,8 @@ final class Settings {
return;
}
+ int maxAppLinkGeneration = 0;
+
int outerDepth = parser.getDepth();
PackageSetting ps = null;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1457,6 +1472,12 @@ final class Settings {
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED :
Integer.parseInt(verifStateStr);
+ final String linkGenStr = parser.getAttributeValue(null, ATTR_APP_LINK_GENERATION);
+ final int linkGeneration = linkGenStr == null ? 0 : Integer.parseInt(linkGenStr);
+ if (linkGeneration > maxAppLinkGeneration) {
+ maxAppLinkGeneration = linkGeneration;
+ }
+
ArraySet<String> enabledComponents = null;
ArraySet<String> disabledComponents = null;
@@ -1478,7 +1499,7 @@ final class Settings {
ps.setUserState(userId, enabled, installed, stopped, notLaunched, hidden,
enabledCaller, enabledComponents, disabledComponents, blockUninstall,
- verifState);
+ verifState, linkGeneration);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
} else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
@@ -1496,6 +1517,8 @@ final class Settings {
str.close();
+ mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1);
+
} catch (XmlPullParserException e) {
mReadMessages.append("Error reading: " + e.toString());
PackageManagerService.reportSettingsProblem(Log.ERROR,
@@ -1749,6 +1772,10 @@ final class Settings {
serializer.attribute(null, ATTR_DOMAIN_VERIFICATON_STATE,
Integer.toString(ustate.domainVerificationStatus));
}
+ if (ustate.appLinkGeneration != 0) {
+ serializer.attribute(null, ATTR_APP_LINK_GENERATION,
+ Integer.toString(ustate.appLinkGeneration));
+ }
if (ustate.enabledComponents != null
&& ustate.enabledComponents.size() > 0) {
serializer.startTag(null, TAG_ENABLED_COMPONENTS);