summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2015-04-06 19:41:28 -0700
committerFabrice Di Meglio <fdimeglio@google.com>2015-04-07 17:13:32 -0700
commit0788595e0c9bc5e8c1907c63db595010006ef5b4 (patch)
tree1f44f98341a3ed4c1e4f81bf597f67d25edbbc88
parent37c905e64655d5bfc5ba06fa0bbee10c1fdc6010 (diff)
downloadframeworks_base-0788595e0c9bc5e8c1907c63db595010006ef5b4.zip
frameworks_base-0788595e0c9bc5e8c1907c63db595010006ef5b4.tar.gz
frameworks_base-0788595e0c9bc5e8c1907c63db595010006ef5b4.tar.bz2
Add IntentFilter auto verification - part 3
- add private API PackageManager.getAllIntentFilters(String) for getting all IntentFilters from a given package - update IntentFilterVerificationInfo to use an ArrayList<String> for domains instead of a String[] - if you make an App a default domain handler then make the others as non default - create an IntentVerificationInfo even if the App IntentFilters do not need to be verified. This would be done only if the App has some domain URLs defined and would allow to make it the default handler for a domain - a few code optimizations here and there Change-Id: I4535372a0bb1a2c8e662e1485be8ca700003e9b3
-rw-r--r--api/current.txt22
-rw-r--r--api/system-current.txt22
-rw-r--r--core/java/android/app/ApplicationPackageManager.java10
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl1
-rw-r--r--core/java/android/content/pm/IntentFilterVerificationInfo.java27
-rw-r--r--core/java/android/content/pm/PackageManager.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java143
-rw-r--r--services/core/java/com/android/server/pm/Settings.java43
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java5
9 files changed, 177 insertions, 116 deletions
diff --git a/api/current.txt b/api/current.txt
index bf55b7c..b6380d7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8857,25 +8857,6 @@ package android.content.pm {
field public java.lang.String targetPackage;
}
- public final class IntentFilterVerificationInfo implements android.os.Parcelable {
- ctor public IntentFilterVerificationInfo();
- ctor public IntentFilterVerificationInfo(java.lang.String, java.lang.String[]);
- ctor public IntentFilterVerificationInfo(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
- ctor public IntentFilterVerificationInfo(android.os.Parcel);
- method public int describeContents();
- method public java.lang.String[] getDomains();
- method public java.lang.String getDomainsString();
- method public java.lang.String getPackageName();
- method public int getStatus();
- method public java.lang.String getStatusString();
- method public static java.lang.String getStatusStringFromValue(int);
- method public void readFromXml(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
- method public void setStatus(int);
- method public void writeToParcel(android.os.Parcel, int);
- method public void writeToXml(org.xmlpull.v1.XmlSerializer) throws java.io.IOException;
- field public static final android.os.Parcelable.Creator<android.content.pm.IntentFilterVerificationInfo> CREATOR;
- }
-
public class LabeledIntent extends android.content.Intent {
ctor public LabeledIntent(android.content.Intent, java.lang.String, int, int);
ctor public LabeledIntent(android.content.Intent, java.lang.String, java.lang.CharSequence, int);
@@ -9104,7 +9085,6 @@ package android.content.pm {
method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
method public abstract java.lang.String getInstallerPackageName(java.lang.String);
method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
method public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public abstract android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public abstract java.lang.String getNameForUid(int);
@@ -30655,6 +30635,7 @@ package android.test.mock {
method public android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public java.util.List<android.content.IntentFilter> getAllIntentFilters(java.lang.String);
method public java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
method public android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
method public android.graphics.drawable.Drawable getApplicationBanner(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -30672,7 +30653,6 @@ package android.test.mock {
method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
method public java.lang.String getInstallerPackageName(java.lang.String);
method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
method public android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public java.lang.String getNameForUid(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 1152de5..a65c35d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9101,25 +9101,6 @@ package android.content.pm {
field public java.lang.String targetPackage;
}
- public final class IntentFilterVerificationInfo implements android.os.Parcelable {
- ctor public IntentFilterVerificationInfo();
- ctor public IntentFilterVerificationInfo(java.lang.String, java.lang.String[]);
- ctor public IntentFilterVerificationInfo(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
- ctor public IntentFilterVerificationInfo(android.os.Parcel);
- method public int describeContents();
- method public java.lang.String[] getDomains();
- method public java.lang.String getDomainsString();
- method public java.lang.String getPackageName();
- method public int getStatus();
- method public java.lang.String getStatusString();
- method public static java.lang.String getStatusStringFromValue(int);
- method public void readFromXml(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
- method public void setStatus(int);
- method public void writeToParcel(android.os.Parcel, int);
- method public void writeToXml(org.xmlpull.v1.XmlSerializer) throws java.io.IOException;
- field public static final android.os.Parcelable.Creator<android.content.pm.IntentFilterVerificationInfo> CREATOR;
- }
-
public class LabeledIntent extends android.content.Intent {
ctor public LabeledIntent(android.content.Intent, java.lang.String, int, int);
ctor public LabeledIntent(android.content.Intent, java.lang.String, java.lang.CharSequence, int);
@@ -9354,7 +9335,6 @@ package android.content.pm {
method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
method public abstract java.lang.String getInstallerPackageName(java.lang.String);
method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
method public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public abstract android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public abstract java.lang.String getNameForUid(int);
@@ -33202,6 +33182,7 @@ package android.test.mock {
method public android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public java.util.List<android.content.IntentFilter> getAllIntentFilters(java.lang.String);
method public java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
method public android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
method public android.graphics.drawable.Drawable getApplicationBanner(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -33219,7 +33200,6 @@ package android.test.mock {
method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
method public java.lang.String getInstallerPackageName(java.lang.String);
method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method public java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
method public android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public java.lang.String getNameForUid(int);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 10dcd85..ffdc81d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1349,6 +1349,16 @@ final class ApplicationPackageManager extends PackageManager {
}
@Override
+ public List<IntentFilter> getAllIntentFilters(String packageName) {
+ try {
+ return mPM.getAllIntentFilters(packageName);
+ } catch (RemoteException e) {
+ // Should never happen!
+ return null;
+ }
+ }
+
+ @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 eed0df5..55c990f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -448,6 +448,7 @@ interface IPackageManager {
int getIntentVerificationStatus(String packageName, int userId);
boolean updateIntentVerificationStatus(String packageName, int status, int userId);
List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName);
+ List<IntentFilter> getAllIntentFilters(String packageName);
VerifierDeviceIdentity getVerifierDeviceIdentity();
diff --git a/core/java/android/content/pm/IntentFilterVerificationInfo.java b/core/java/android/content/pm/IntentFilterVerificationInfo.java
index 60cb4a8..28cbaa8 100644
--- a/core/java/android/content/pm/IntentFilterVerificationInfo.java
+++ b/core/java/android/content/pm/IntentFilterVerificationInfo.java
@@ -24,6 +24,7 @@ import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATIO
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -47,17 +48,17 @@ public final class IntentFilterVerificationInfo implements Parcelable {
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_STATUS = "status";
- private String[] mDomains;
+ private ArrayList<String> mDomains;
private String mPackageName;
private int mMainStatus;
public IntentFilterVerificationInfo() {
mPackageName = null;
- mDomains = new String[0];
+ mDomains = new ArrayList<>();
mMainStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
}
- public IntentFilterVerificationInfo(String packageName, String[] domains) {
+ public IntentFilterVerificationInfo(String packageName, ArrayList<String> domains) {
mPackageName = packageName;
mDomains = domains;
mMainStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
@@ -72,10 +73,14 @@ public final class IntentFilterVerificationInfo implements Parcelable {
readFromParcel(source);
}
- public String[] getDomains() {
+ public ArrayList<String> getDomains() {
return mDomains;
}
+ public ArraySet<String> getDomainsSet() {
+ return new ArraySet<>(mDomains);
+ }
+
public String getPackageName() {
return mPackageName;
}
@@ -140,7 +145,7 @@ public final class IntentFilterVerificationInfo implements Parcelable {
}
mMainStatus = status;
- ArrayList<String> list = new ArrayList<>();
+ mDomains = new ArrayList<>();
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -155,18 +160,13 @@ public final class IntentFilterVerificationInfo implements Parcelable {
if (tagName.equals(TAG_DOMAIN)) {
String name = getStringFromXml(parser, ATTR_DOMAIN_NAME, null);
if (!TextUtils.isEmpty(name)) {
- if (list == null) {
- list = new ArrayList<>();
- }
- list.add(name);
+ mDomains.add(name);
}
} else {
Log.w(TAG, "Unknown tag parsing IntentFilter: " + tagName);
}
XmlUtils.skipCurrentTag(parser);
}
-
- mDomains = list.toArray(new String[list.size()]);
}
public void writeToXml(XmlSerializer serializer) throws IOException {
@@ -201,14 +201,15 @@ public final class IntentFilterVerificationInfo implements Parcelable {
private void readFromParcel(Parcel source) {
mPackageName = source.readString();
mMainStatus = source.readInt();
- mDomains = source.readStringArray();
+ mDomains = new ArrayList<>();
+ source.readStringList(mDomains);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mPackageName);
dest.writeInt(mMainStatus);
- dest.writeStringArray(mDomains);
+ dest.writeStringList(mDomains);
}
public static final Creator<IntentFilterVerificationInfo> CREATOR =
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4c99d09..303b709 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3635,13 +3635,29 @@ public abstract class PackageManager {
* @param packageName the package name. When this parameter is set to a non null value,
* the results will be filtered by the package name provided.
* Otherwise, there will be no filtering and it will return a list
- * corresponding for all packages for the provided userId.
- * @return a list of IntentFilterVerificationInfo for a specific package and User.
+ * corresponding for all packages
+ *
+ * @return a list of IntentFilterVerificationInfo for a specific package.
+ *
+ * @hide
*/
public abstract List<IntentFilterVerificationInfo> getIntentFilterVerifications(
String packageName);
/**
+ * Get the list of IntentFilter for a specific package.
+ *
+ * @param packageName the package name. This parameter is set to a non null value,
+ * the list will contain all the IntentFilter for that package.
+ * Otherwise, the list will be empty.
+ *
+ * @return a list of IntentFilter for a specific package.
+ *
+ * @hide
+ */
+ public abstract List<IntentFilter> getAllIntentFilters(String packageName);
+
+ /**
* 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 4fea889..80a4351 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -564,14 +564,15 @@ public class PackageManagerService extends IPackageManager.Stub {
ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
final int filterCount = filters.size();
+ ArraySet<String> domainsSet = new ArraySet<>();
for (int m=0; m<filterCount; m++) {
PackageParser.ActivityIntentInfo filter = filters.get(m);
- synchronized (mPackages) {
- modified = mSettings.createIntentFilterVerificationIfNeededLPw(
- packageName, filter.getHosts());
- }
+ domainsSet.addAll(filter.getHostsList());
}
+ ArrayList<String> domainsList = new ArrayList<>(domainsSet);
synchronized (mPackages) {
+ modified = mSettings.createIntentFilterVerificationIfNeededLPw(
+ packageName, domainsList);
if (modified) {
scheduleWriteSettingsLocked();
}
@@ -582,7 +583,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
private void sendVerificationRequest(int userId, int verificationId,
- IntentFilterVerificationState ivs) {
+ IntentFilterVerificationState ivs) {
Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
verificationIntent.putExtra(
@@ -716,33 +717,33 @@ public class PackageManagerService extends IPackageManager.Stub {
}
return ivs;
}
+ }
- private boolean hasValidHosts(ArrayList<String> hosts) {
- if (hosts.size() == 0) {
- Slog.d(TAG, "IntentFilter does not contain any data hosts");
+ private static boolean hasValidHosts(ArrayList<String> hosts) {
+ if (hosts.size() == 0) {
+ Slog.d(TAG, "IntentFilter does not contain any data hosts");
+ return false;
+ }
+ String hostEndBase = null;
+ for (String host : hosts) {
+ String[] hostParts = host.split("\\.");
+ // Should be at minimum a host like "example.com"
+ if (hostParts.length < 2) {
+ Slog.d(TAG, "IntentFilter does not contain a valid data host name: " + host);
return false;
}
- String hostEndBase = null;
- for (String host : hosts) {
- String[] hostParts = host.split("\\.");
- // Should be at minimum a host like "example.com"
- if (hostParts.length < 2) {
- 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)) {
- Slog.d(TAG, "IntentFilter does not contain the same data domains");
- 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)) {
+ Slog.d(TAG, "IntentFilter does not contain the same data domains");
+ return false;
}
- return true;
}
+ return true;
}
private IntentFilterVerifier mIntentFilterVerifier;
@@ -3895,8 +3896,7 @@ public class PackageManagerService extends IPackageManager.Stub {
resolveInfo = queryCrossProfileIntents(
matchingFilters, intent, resolvedType, flags, userId);
- // Check for results in the current profile. Adding GET_RESOLVED_FILTER flags
- // as we need it later
+ // Check for results in the current profile.
List<ResolveInfo> result = mActivities.queryIntent(
intent, resolvedType, flags, userId);
if (resolveInfo != null) {
@@ -3905,7 +3905,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
result = filterIfNotPrimaryUser(result, userId);
if (result.size() > 1) {
- return filterCandidatesWithDomainPreferedActivitiesLPw(result);
+ return filterCandidatesWithDomainPreferedActivitiesLPr(result);
}
return result;
@@ -3939,42 +3939,33 @@ public class PackageManagerService extends IPackageManager.Stub {
return resolveInfos;
}
- private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPw(
+ private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr(
List<ResolveInfo> candidates) {
if (DEBUG_PREFERRED) {
Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
candidates.size());
}
final int userId = UserHandle.getCallingUserId();
- ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(candidates);
+ ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
synchronized (mPackages) {
- final int count = result.size();
- for (int n = count-1; n >= 0; n--) {
- ResolveInfo info = result.get(n);
- if (!info.filterNeedsVerification) {
- continue;
- }
+ final int count = candidates.size();
+ // First, try to use the domain prefered App
+ for (int n=0; n<count; n++) {
+ ResolveInfo info = candidates.get(n);
String packageName = info.activityInfo.packageName;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
// Try to get the status from User settings first
- int status = ps.getDomainVerificationStatusForUser(userId);
- // if none available, get the master status
- if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
- if (ps.getIntentFilterVerificationInfo() != null) {
- status = ps.getIntentFilterVerificationInfo().getStatus();
- }
- }
+ int status = getDomainVerificationStatusLPr(ps, userId);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
- result.clear();
result.add(info);
- // We break the for loop as we are good to go
- break;
- } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
- result.remove(n);
}
}
}
+ // There is not much we can do, add all candidates
+ if (result.size() == 0) {
+ result.addAll(candidates);
+ }
}
if (DEBUG_PREFERRED) {
Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " +
@@ -3983,6 +3974,17 @@ public class PackageManagerService extends IPackageManager.Stub {
return result;
}
+ private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
+ int status = ps.getDomainVerificationStatusForUser(userId);
+ // if none available, get the master status
+ if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
+ if (ps.getIntentFilterVerificationInfo() != null) {
+ status = ps.getIntentFilterVerificationInfo().getStatus();
+ }
+ }
+ return status;
+ }
+
private ResolveInfo querySkipCurrentProfileIntents(
List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
int flags, int sourceUserId) {
@@ -8980,6 +8982,28 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
+ public List<IntentFilter> getAllIntentFilters(String packageName) {
+ if (TextUtils.isEmpty(packageName)) {
+ return Collections.<IntentFilter>emptyList();
+ }
+ synchronized (mPackages) {
+ PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null || pkg.activities == null) {
+ return Collections.<IntentFilter>emptyList();
+ }
+ final int count = pkg.activities.size();
+ ArrayList<IntentFilter> result = new ArrayList<>();
+ for (int n=0; n<count; n++) {
+ PackageParser.Activity activity = pkg.activities.get(n);
+ if (activity.intents != null || activity.intents.size() > 0) {
+ result.addAll(activity.intents);
+ }
+ }
+ return result;
+ }
+ }
+
/**
* Get the "allow unknown sources" setting.
*
@@ -11184,7 +11208,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
private void verifyIntentFiltersIfNeeded(int userId, int verifierUid,
- PackageParser.Package pkg) {
+ PackageParser.Package pkg) {
int size = pkg.activities.size();
if (size == 0) {
Slog.d(TAG, "No activity, so no need to verify any IntentFilter!");
@@ -11196,6 +11220,8 @@ public class PackageManagerService extends IPackageManager.Stub {
final int verificationId = mIntentFilterVerificationToken++;
int count = 0;
+ final String packageName = pkg.packageName;
+ ArrayList<String> allHosts = new ArrayList<>();
synchronized (mPackages) {
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
@@ -11204,10 +11230,14 @@ public class PackageManagerService extends IPackageManager.Stub {
if (needFilterVerification && needNetworkVerificationLPr(filter)) {
Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString());
mIntentFilterVerifier.addOneIntentFilterVerification(
- verifierUid, userId, verificationId, filter, pkg.packageName);
+ verifierUid, userId, verificationId, filter, packageName);
count++;
} else {
Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString());
+ ArrayList<String> list = filter.getHostsList();
+ if (hasValidHosts(list)) {
+ allHosts.addAll(list);
+ }
}
}
}
@@ -11219,6 +11249,11 @@ public class PackageManagerService extends IPackageManager.Stub {
+ (count > 1 ? "s" : "") + " for userId:" + userId + "!");
} else {
Slog.d(TAG, "No need to start any IntentFilter verification!");
+ if (allHosts.size() > 0 && hasDomainURLs(pkg) &&
+ mSettings.createIntentFilterVerificationIfNeededLPw(
+ packageName, allHosts)) {
+ scheduleWriteSettingsLocked();
+ }
}
}
@@ -11271,6 +11306,10 @@ public class PackageManagerService extends IPackageManager.Stub {
return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
}
+ private static boolean hasDomainURLs(PackageParser.Package pkg) {
+ return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
+ }
+
private static boolean isSystemApp(PackageSetting ps) {
return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6b7c35c..2e2053d 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -22,6 +22,8 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.PACKAGE_INFO_GID;
@@ -964,7 +966,8 @@ final class Settings {
}
/* package protected */
- boolean createIntentFilterVerificationIfNeededLPw(String packageName, String[] domains) {
+ boolean createIntentFilterVerificationIfNeededLPw(String packageName,
+ ArrayList<String> domains) {
PackageSetting ps = mPackages.get(packageName);
if (ps == null) {
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
@@ -973,9 +976,9 @@ final class Settings {
if (ps.getIntentFilterVerificationInfo() == null) {
IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(packageName, domains);
ps.setIntentFilterVerificationInfo(ivi);
- return false;
+ return true;
}
- return true;
+ return false;
}
int getIntentFilterVerificationStatusLPr(String packageName, int userId) {
@@ -994,17 +997,43 @@ final class Settings {
}
boolean updateIntentFilterVerificationStatusLPw(String packageName, int status, int userId) {
- PackageSetting ps = mPackages.get(packageName);
- if (ps == null) {
+ // Update the status for the current package
+ PackageSetting current = mPackages.get(packageName);
+ if (current == null) {
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
return false;
}
- ps.setDomainVerificationStatusForUser(status, userId);
+ current.setDomainVerificationStatusForUser(status, userId);
+
+ if (current.getIntentFilterVerificationInfo() == null) {
+ Slog.w(PackageManagerService.TAG,
+ "No IntentFilterVerificationInfo known for name: " + packageName);
+ return false;
+ }
+
+ // Then, if we set a ALWAYS status, then put NEVER status for Apps whose IntentFilter
+ // domains overlap the domains of the current package
+ ArraySet<String> currentDomains = current.getIntentFilterVerificationInfo().getDomainsSet();
+ if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
+ for (PackageSetting ps : mPackages.values()) {
+ if (ps == null || ps.pkg.packageName.equals(packageName)) continue;
+ IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
+ if (ivi == null) {
+ continue;
+ }
+ ArraySet<String> set = ivi.getDomainsSet();
+ set.retainAll(currentDomains);
+ if (set.size() > 0) {
+ ps.setDomainVerificationStatusForUser(
+ INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, userId);
+ }
+ }
+ }
return true;
}
/**
- * Used for dump. Should be read only.
+ * Used for Settings App and PackageManagerService dump. Should be read only.
*/
List<IntentFilterVerificationInfo> getIntentFilterVerificationsLPr(
String packageName) {
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index c8b6846..79510d0 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -759,6 +759,11 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
+ @Override
+ public List<IntentFilter> getAllIntentFilters(String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* @hide
*/