summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2015-04-10 17:24:02 -0700
committerFabrice Di Meglio <fdimeglio@google.com>2015-04-10 17:54:02 -0700
commit6227172310663e1267b1fabd68be890a1cb7e145 (patch)
treeb05d1ddcd6858b676c6e5a128fdd07e0b6e5f599
parent2d897fbc447fd315b246a752e14825cbd7214e74 (diff)
downloadframeworks_base-6227172310663e1267b1fabd68be890a1cb7e145.zip
frameworks_base-6227172310663e1267b1fabd68be890a1cb7e145.tar.gz
frameworks_base-6227172310663e1267b1fabd68be890a1cb7e145.tar.bz2
Add Default Browser App support and relax Hosts validation for AppLinks
- add private PackageManager APIs for setting/getting the default Browser App package name - serialize / deserialize the default Browser App package name per User Also relax the Hosts name validation for the AppLinls feature. Now we just care if the IntentFilter is having an HTTP or HTTPS scheme. Change-Id: I4436f66ac6beff57e14f7f3a2a00b0b582c03be9
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--core/java/android/app/ApplicationPackageManager.java20
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/content/pm/PackageManager.java26
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java45
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java11
-rw-r--r--services/core/java/com/android/server/pm/Settings.java86
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java10
9 files changed, 155 insertions, 50 deletions
diff --git a/api/current.txt b/api/current.txt
index ccdac7e..9bd6367 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30603,6 +30603,7 @@ package android.test.mock {
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);
@@ -30650,6 +30651,7 @@ package android.test.mock {
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 7dad2bf..ca6b777 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -33205,6 +33205,7 @@ package android.test.mock {
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);
@@ -33254,6 +33255,7 @@ package android.test.mock {
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 @@ final class ApplicationPackageManager extends PackageManager {
}
@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 @@ interface IPackageManager {
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 303b709..6532563 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3658,6 +3658,32 @@ public abstract class PackageManager {
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 923b325..83c30aa 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 @@ public class PackageManagerService extends IPackageManager.Stub {
}
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;
}
@@ -9100,6 +9069,20 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @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.IntentFilterVerificationInfo;
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 @@ abstract class PackageSettingBase extends SettingBase {
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 @@ final class Settings {
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 @@ final class Settings {
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 @@ final class Settings {
// 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 @@ final class Settings {
}
}
+ 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 @@ final class Settings {
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 @@ final class Settings {
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 @@ final class Settings {
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 @@ final class Settings {
writePreferredActivitiesLPr(serializer, userId, true);
writePersistentPreferredActivitiesLPr(serializer, userId);
writeCrossProfileIntentFiltersLPr(serializer, userId);
+ writeDefaultAppsLPr(serializer, userId);
serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
@@ -2114,7 +2170,7 @@ final class Settings {
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 @@ final class Settings {
// 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 @@ final class Settings {
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 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
+ @Override
+ public String getDefaultBrowserPackageName(int userId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* @hide
*/