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
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
@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 @@
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 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
* @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 @@
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 @@
}
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 @@
}
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;
}
- return true;
+ if (!hostEnd.equalsIgnoreCase(hostEndBase)) {
+ Slog.d(TAG, "IntentFilter does not contain the same data domains");
+ return false;
+ }
}
+ return true;
}
private IntentFilterVerifier mIntentFilterVerifier;
@@ -3895,8 +3896,7 @@
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 @@
}
result = filterIfNotPrimaryUser(result, userId);
if (result.size() > 1) {
- return filterCandidatesWithDomainPreferedActivitiesLPw(result);
+ return filterCandidatesWithDomainPreferedActivitiesLPr(result);
}
return result;
@@ -3939,42 +3939,33 @@
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 @@
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 @@
}
}
+ @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 @@
}
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 @@
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 @@
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 @@
+ (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 @@
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_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 @@
}
/* 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 @@
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 @@
}
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 @@
throw new UnsupportedOperationException();
}
+ @Override
+ public List<IntentFilter> getAllIntentFilters(String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* @hide
*/