Merge "Add Default Browser App support and relax Hosts validation for AppLinks"
diff --git a/api/current.txt b/api/current.txt
index 0d6c7b6..fcbfa04 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30711,6 +30711,7 @@
method public android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public int getComponentEnabledSetting(android.content.ComponentName);
method public android.graphics.drawable.Drawable getDefaultActivityIcon();
+ method public java.lang.String getDefaultBrowserPackageName(int);
method public android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
@@ -30758,6 +30759,7 @@
method public android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
method public void setApplicationEnabledSetting(java.lang.String, int, int);
method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
+ method public boolean setDefaultBrowserPackageName(java.lang.String, int);
method public void setInstallerPackageName(java.lang.String, java.lang.String);
method public void verifyPendingInstall(int, int);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index ff8c50f..5351778 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -33322,6 +33322,7 @@
method public android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public int getComponentEnabledSetting(android.content.ComponentName);
method public android.graphics.drawable.Drawable getDefaultActivityIcon();
+ method public java.lang.String getDefaultBrowserPackageName(int);
method public android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
@@ -33371,6 +33372,7 @@
method public void revokePermission(java.lang.String, java.lang.String, android.os.UserHandle);
method public void setApplicationEnabledSetting(java.lang.String, int, int);
method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
+ method public boolean setDefaultBrowserPackageName(java.lang.String, int);
method public void setInstallerPackageName(java.lang.String, java.lang.String);
method public void verifyPendingInstall(int, int);
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index ffdc81d..9ddfd88 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1359,6 +1359,26 @@
}
@Override
+ public String getDefaultBrowserPackageName(int userId) {
+ try {
+ return mPM.getDefaultBrowserPackageName(userId);
+ } catch (RemoteException e) {
+ // Should never happen!
+ return null;
+ }
+ }
+
+ @Override
+ public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+ try {
+ return mPM.setDefaultBrowserPackageName(packageName, userId);
+ } catch (RemoteException e) {
+ // Should never happen!
+ return false;
+ }
+ }
+
+ @Override
public void setInstallerPackageName(String targetPackage,
String installerPackageName) {
try {
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 55c990f..c2580c0 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -450,6 +450,9 @@
List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName);
List<IntentFilter> getAllIntentFilters(String packageName);
+ boolean setDefaultBrowserPackageName(String packageName, int userId);
+ String getDefaultBrowserPackageName(int userId);
+
VerifierDeviceIdentity getVerifierDeviceIdentity();
boolean isFirstBoot();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d5461eba..0396660 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3667,6 +3667,32 @@
public abstract List<IntentFilter> getAllIntentFilters(String packageName);
/**
+ * Get the default Browser package name for a specific user.
+ *
+ * @param userId The user id.
+ *
+ * @return the package name of the default Browser for the specified user. If the user id passed
+ * is -1 (all users) it will return a null value.
+ *
+ * @hide
+ */
+ public abstract String getDefaultBrowserPackageName(int userId);
+
+ /**
+ * Set the default Browser package name for a specific user.
+ *
+ * @param packageName The package name of the default Browser.
+ * @param userId The user id.
+ *
+ * @return true if the default Browser for the specified user has been set,
+ * otherwise return false. If the user id passed is -1 (all users) this call will not
+ * do anything and just return false.
+ *
+ * @hide
+ */
+ public abstract boolean setDefaultBrowserPackageName(String packageName, int userId);
+
+ /**
* Change the installer associated with a given package. There are limitations
* on how the installer package can be changed; in particular:
* <ul>
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 11e1ccf..a0313e7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -729,37 +729,6 @@
}
return false;
}
- ArrayList<String> hosts = filter.getHostsList();
- if (hosts.size() == 0) {
- if (logging) {
- Slog.d(TAG, "IntentFilter does not contain any data hosts");
- }
- // We still return true as this is the case of any Browser
- return true;
- }
- String hostEndBase = null;
- for (String host : hosts) {
- String[] hostParts = host.split("\\.");
- // Should be at minimum a host like "example.com"
- if (hostParts.length < 2) {
- if (logging) {
- Slog.d(TAG, "IntentFilter does not contain a valid data host name: " + host);
- }
- return false;
- }
- // Verify that we have the same ending domain
- int length = hostParts.length;
- String hostEnd = hostParts[length - 1] + hostParts[length - 2];
- if (hostEndBase == null) {
- hostEndBase = hostEnd;
- }
- if (!hostEnd.equalsIgnoreCase(hostEndBase)) {
- if (logging) {
- Slog.d(TAG, "IntentFilter does not contain the same data domains");
- }
- return false;
- }
- }
return true;
}
@@ -9096,6 +9065,20 @@
}
}
+ @Override
+ public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+ synchronized (mPackages) {
+ return mSettings.setDefaultBrowserPackageNameLPr(packageName, userId);
+ }
+ }
+
+ @Override
+ public String getDefaultBrowserPackageName(int userId) {
+ synchronized (mPackages) {
+ return mSettings.getDefaultBrowserPackageNameLPw(userId);
+ }
+ }
+
/**
* Get the "allow unknown sources" setting.
*
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index f294b32..5429517 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -24,6 +24,7 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageUserState;
import android.os.storage.VolumeInfo;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.SparseArray;
@@ -435,23 +436,23 @@
userState.delete(userId);
}
- public IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
+ IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
return verificationInfo;
}
- public void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
+ void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
verificationInfo = info;
}
- public int getDomainVerificationStatusForUser(int userId) {
+ int getDomainVerificationStatusForUser(int userId) {
return readUserState(userId).domainVerificationStatus;
}
- public void setDomainVerificationStatusForUser(int status, int userId) {
+ void setDomainVerificationStatusForUser(int status, int userId) {
modifyUserState(userId).domainVerificationStatus = status;
}
- public void clearDomainVerificationStatusForUser(int userId) {
+ void clearDomainVerificationStatusForUser(int userId) {
modifyUserState(userId).domainVerificationStatus =
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index bfcc3db..45bfba1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -170,6 +170,8 @@
static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
"crossProfile-intent-filters";
public static final String TAG_DOMAIN_VERIFICATION = "domain-verification";
+ public static final String TAG_DEFAULT_APPS= "default-apps";
+ public static final String TAG_DEFAULT_BROWSER= "default-browser";
private static final String ATTR_NAME = "name";
private static final String ATTR_USER = "user";
@@ -185,6 +187,7 @@
private static final String ATTR_INSTALLED = "inst";
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
+ private static final String ATTR_PACKAGE_NAME= "packageName";
private final Object mLock;
@@ -272,7 +275,10 @@
// names. The packages appear everwhere else under their original
// names.
final ArrayMap<String, String> mRenamedPackages = new ArrayMap<String, String>();
-
+
+ // For every user, it is used to find the package name of the default Browser App.
+ final SparseArray<String> mDefaultBrowserApp = new SparseArray<String>();
+
final StringBuilder mReadMessages = new StringBuilder();
/**
@@ -1067,6 +1073,19 @@
}
}
+ boolean setDefaultBrowserPackageNameLPr(String packageName, int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ return false;
+ }
+ mDefaultBrowserApp.put(userId, packageName);
+ writePackageRestrictionsLPr(userId);
+ return true;
+ }
+
+ String getDefaultBrowserPackageNameLPw(int userId) {
+ return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.get(userId);
+ }
+
private File getUserPackagesStateFile(int userId) {
// TODO: Implement a cleaner solution when adding tests.
// This instead of Environment.getUserSystemDirectory(userId) to support testing.
@@ -1232,15 +1251,25 @@
Log.d(TAG, "Read domain verification for package:" + ivi.getPackageName());
}
- void writeDomainVerificationsLPr(XmlSerializer serializer, String packageName,
- IntentFilterVerificationInfo verificationInfo)
- throws IllegalArgumentException, IllegalStateException, IOException {
- if (verificationInfo != null && verificationInfo.getPackageName() != null) {
- serializer.startTag(null, TAG_DOMAIN_VERIFICATION);
- verificationInfo.writeToXml(serializer);
- Log.d(TAG, "Wrote domain verification for package: "
- + verificationInfo.getPackageName());
- serializer.endTag(null, TAG_DOMAIN_VERIFICATION);
+ private void readDefaultAppsLPw(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_DEFAULT_BROWSER)) {
+ String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
+ mDefaultBrowserApp.put(userId, packageName);
+ } else {
+ String msg = "Unknown element under " + TAG_DEFAULT_APPS + ": " +
+ parser.getName();
+ PackageManagerService.reportSettingsProblem(Log.WARN, msg);
+ XmlUtils.skipCurrentTag(parser);
+ }
}
}
@@ -1392,6 +1421,8 @@
readPersistentPreferredActivitiesLPw(parser, userId);
} else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
readCrossProfileIntentFiltersLPw(parser, userId);
+ } else if (tagName.equals(TAG_DEFAULT_APPS)) {
+ readDefaultAppsLPw(parser, userId);
} else {
Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
+ parser.getName());
@@ -1490,6 +1521,30 @@
serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
}
+ void writeDomainVerificationsLPr(XmlSerializer serializer,
+ IntentFilterVerificationInfo verificationInfo)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ if (verificationInfo != null && verificationInfo.getPackageName() != null) {
+ serializer.startTag(null, TAG_DOMAIN_VERIFICATION);
+ verificationInfo.writeToXml(serializer);
+ Log.d(TAG, "Wrote domain verification for package: "
+ + verificationInfo.getPackageName());
+ serializer.endTag(null, TAG_DOMAIN_VERIFICATION);
+ }
+ }
+
+ void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ serializer.startTag(null, TAG_DEFAULT_APPS);
+ String packageName = mDefaultBrowserApp.get(userId);
+ if (!TextUtils.isEmpty(packageName)) {
+ serializer.startTag(null, TAG_DEFAULT_BROWSER);
+ serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
+ serializer.endTag(null, TAG_DEFAULT_BROWSER);
+ }
+ serializer.endTag(null, TAG_DEFAULT_APPS);
+ }
+
void writePackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId);
@@ -1600,6 +1655,7 @@
writePreferredActivitiesLPr(serializer, userId, true);
writePersistentPreferredActivitiesLPr(serializer, userId);
writeCrossProfileIntentFiltersLPr(serializer, userId);
+ writeDefaultAppsLPr(serializer, userId);
serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
@@ -2114,7 +2170,7 @@
writeSigningKeySetLPr(serializer, pkg.keySetData);
writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
writeKeySetAliasesLPr(serializer, pkg.keySetData);
- writeDomainVerificationsLPr(serializer, pkg.name, pkg.verificationInfo);
+ writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
serializer.endTag(null, "package");
}
@@ -2283,8 +2339,9 @@
// TODO: check whether this is okay! as it is very
// similar to how preferred-activities are treated
readCrossProfileIntentFiltersLPw(parser, 0);
- }
- else if (tagName.equals("updated-package")) {
+ } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
+ readDefaultAppsLPw(parser, 0);
+ } else if (tagName.equals("updated-package")) {
readDisabledSysPackageLPw(parser);
} else if (tagName.equals("cleaning-package")) {
String name = parser.getAttributeValue(null, ATTR_NAME);
@@ -4044,7 +4101,8 @@
void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
if (!ArrayUtils.isEmpty(gids)) {
- pw.print(prefix); pw.print("gids="); pw.println(
+ pw.print(prefix);
+ pw.print("gids="); pw.println(
PackageManagerService.arrayToString(gids));
}
}
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 79510d0..e78750c 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -764,6 +764,16 @@
throw new UnsupportedOperationException();
}
+ @Override
+ public String getDefaultBrowserPackageName(int userId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* @hide
*/