From a08a225d184fa75bb066fcb2d151d589106986de Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Wed, 1 Jul 2015 16:52:43 -0700 Subject: [PATCH] App link handling is not just for "official" verified handlers Allow apps to be enabled as link handlers for their accepted domains even when they are not the "official" apps for those domains. Also clean up a bunch of inconsistent/wrong state reporting in the UI. Bug 22069429 Change-Id: Ic3b2bcc476dfc30085d3df7412b02bdc5d53df6d --- src/com/android/settings/Utils.java | 25 ++++++ .../applications/AppLaunchSettings.java | 88 +++++++++---------- .../applications/ManageApplications.java | 11 +-- 3 files changed, 69 insertions(+), 55 deletions(-) diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 21a5019f039..01f4eb86ebd 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -33,6 +33,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; +import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -70,6 +71,7 @@ import android.provider.ContactsContract.RawContacts; import android.service.persistentdata.PersistentDataBlockManager; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; import android.view.LayoutInflater; @@ -1109,6 +1111,29 @@ public final class Utils { return prefActList.size() > 0; } + public static ArraySet getHandledDomains(PackageManager pm, String packageName) { + List iviList = pm.getIntentFilterVerifications(packageName); + List filters = pm.getAllIntentFilters(packageName); + + ArraySet result = new ArraySet<>(); + if (iviList.size() > 0) { + for (IntentFilterVerificationInfo ivi : iviList) { + for (String host : ivi.getDomains()) { + result.add(host); + } + } + } + if (filters != null && filters.size() > 0) { + for (IntentFilter filter : filters) { + if (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || + filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)) { + result.addAll(filter.getHostsList()); + } + } + } + return result; + } + public static CharSequence getLaunchByDeafaultSummary(ApplicationsState.AppEntry appEntry, IUsbManager usbManager, PackageManager pm, Context context) { String packageName = appEntry.info.packageName; diff --git a/src/com/android/settings/applications/AppLaunchSettings.java b/src/com/android/settings/applications/AppLaunchSettings.java index 05a1fcae8b8..a59171f75ca 100644 --- a/src/com/android/settings/applications/AppLaunchSettings.java +++ b/src/com/android/settings/applications/AppLaunchSettings.java @@ -17,32 +17,31 @@ package com.android.settings.applications; import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.UserHandle; import android.preference.Preference; import android.preference.SwitchPreference; import android.util.ArraySet; +import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import com.android.internal.logging.MetricsLogger; import com.android.settings.R; +import com.android.settings.Utils; + +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 java.util.List; -import static android.content.pm.PackageManager.GET_ACTIVITIES; -import static android.content.pm.PackageManager.GET_META_DATA; -import static android.content.pm.PackageManager.GET_RESOLVED_FILTER; - public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener, Preference.OnPreferenceChangeListener { + private static final String TAG = "AppLaunchSettings"; private static final String KEY_OPEN_DOMAIN_URLS = "app_launch_open_domain_urls"; private static final String KEY_SUPPORTED_DOMAIN_URLS = "app_launch_supported_domain_urls"; @@ -50,6 +49,7 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe private PackageManager mPm; + private boolean mHasDomainUrls; private SwitchPreference mOpenDomainUrls; private AppDomainsPreference mAppDomainUrls; private ClearDefaultsPreference mClearDefaultsPreference; @@ -61,61 +61,50 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe addPreferencesFromResource(R.xml.installed_app_launch_settings); mPm = getActivity().getPackageManager(); - final int myUserId = UserHandle.myUserId(); mOpenDomainUrls = (SwitchPreference) findPreference(KEY_OPEN_DOMAIN_URLS); mOpenDomainUrls.setOnPreferenceChangeListener(this); - boolean hasDomainUrls = + mHasDomainUrls = (mAppEntry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; List iviList = mPm.getIntentFilterVerifications(mPackageName); - boolean enabled = hasDomainUrls && (iviList.size() != 0); - - mOpenDomainUrls.setEnabled(enabled); - if (enabled) { - final int status = mPm.getIntentVerificationStatus(mPackageName, myUserId); - boolean checked = - (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); - mOpenDomainUrls.setChecked(checked); - } - List filters = mPm.getAllIntentFilters(mPackageName); mAppDomainUrls = (AppDomainsPreference) findPreference(KEY_SUPPORTED_DOMAIN_URLS); - CharSequence[] entries = getEntries(iviList, filters); + CharSequence[] entries = getEntries(mPackageName, iviList, filters); mAppDomainUrls.setTitles(entries); mAppDomainUrls.setValues(new int[entries.length]); mClearDefaultsPreference = (ClearDefaultsPreference) findPreference(KEY_CLEAR_DEFAULTS); + + updateDomainUrlPrefState(); } - private CharSequence[] getEntries(List iviList, + private void updateDomainUrlPrefState() { + mOpenDomainUrls.setEnabled(mHasDomainUrls); + + boolean checked = false; + if (mHasDomainUrls) { + final int status = mPm.getIntentVerificationStatus(mPackageName, UserHandle.myUserId()); + if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { + checked = true; + } + } + mOpenDomainUrls.setChecked(checked); + } + + private CharSequence[] getEntries(String packageName, List iviList, List filters) { - ArraySet result = new ArraySet<>(); - if (iviList.size() > 0) { - for (IntentFilterVerificationInfo ivi : iviList) { - for (String host : ivi.getDomains()) { - result.add(host); - } - } - } - if (filters != null && filters.size() > 0) { - for (IntentFilter filter : filters) { - if (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || - filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)) { - result.addAll(filter.getHostsList()); - } - } - } - return result.toArray(new CharSequence[0]); + ArraySet result = Utils.getHandledDomains(mPm, packageName); + return result.toArray(new CharSequence[result.size()]); } @Override protected boolean refreshUi() { mClearDefaultsPreference.setPackageName(mPackageName); mClearDefaultsPreference.setAppEntry(mAppEntry); - + updateDomainUrlPrefState(); return true; } @@ -125,7 +114,6 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe return null; } - @Override public void onClick(View v) { // Nothing to do @@ -136,11 +124,21 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe boolean ret = false; final String key = preference.getKey(); if (KEY_OPEN_DOMAIN_URLS.equals(key)) { - SwitchPreference pref = (SwitchPreference) preference; - int status = !pref.isChecked() ? - PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS : - PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; - ret = mPm.updateIntentVerificationStatus(mPackageName, status, UserHandle.myUserId()); + final SwitchPreference pref = (SwitchPreference) preference; + final Boolean switchedOn = (Boolean) newValue; + int newState = switchedOn ? + INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS : + INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; + final int userId = UserHandle.myUserId(); + boolean success = mPm.updateIntentVerificationStatus(mPackageName, newState, userId); + if (success) { + // read back the state to ensure canonicality + newState = mPm.getIntentVerificationStatus(mPackageName, userId); + ret = (newState == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); + pref.setChecked(ret); + } else { + Log.e(TAG, "Couldn't update intent verification status!"); + } } return ret; } diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index c1566d05dd4..0a09133ffb0 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -20,7 +20,6 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; -import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Environment; @@ -76,7 +75,6 @@ import com.android.settingslib.applications.ApplicationsState.VolumeFilter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.List; /** * Activity to pick an application that will be used to display installation information and @@ -1047,14 +1045,7 @@ public class ManageApplications extends InstrumentedFragment } private CharSequence getDomainsSummary(String packageName) { - ArraySet result = new ArraySet<>(); - List list = - mPm.getIntentFilterVerifications(packageName); - for (IntentFilterVerificationInfo ivi : list) { - for (String host : ivi.getDomains()) { - result.add(host); - } - } + ArraySet result = Utils.getHandledDomains(mPm, packageName); if (result.size() == 0) { return mContext.getString(R.string.domain_urls_summary_none); } else if (result.size() == 1) {