From 2b14f4bfd4e435689528dabdd7d82726f4406caa Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Mon, 1 Feb 2021 14:13:00 -0800 Subject: [PATCH] Allows a plugin Settings activity to designate plugins it supports. The activity can add categories to its intent filter which match the actions of the plugins it supports. The Settings icon is only shown next to these plugins. This is useful if an app (e.g. SupportApp) implements multiple plugins which may each want their own settings. Note: If any settings activity in an app specifies categories of plugin it supports, any other settings activities in the same app must also provide categories of their plugins to disambiguate. Test: Manually with SupportApp (including mix of plugins with and without Settings activities) and AwarenessSpace plugin (with a non-categorized settings activity). Change-Id: If3ab7b5f7f916fd3f6b05b89cf1a22c9d21403cc --- .../settings/DeveloperOptionsFragment.java | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java index 47d214d0a8..c9fb956617 100644 --- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java +++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java @@ -15,7 +15,10 @@ */ package com.android.launcher3.settings; +import static android.content.pm.PackageManager.GET_RESOLVED_FILTER; import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED; import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey; @@ -26,10 +29,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -130,7 +131,7 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); EditText filterBox = view.findViewById(R.id.filter_box); - filterBox.setVisibility(View.VISIBLE); + filterBox.setVisibility(VISIBLE); filterBox.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { @@ -212,7 +213,7 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { Set pluginActions = manager.getPluginActions(); - ArrayMap, ArrayList>> plugins = + ArrayMap, ArrayList>> plugins = new ArrayMap<>(); Set pluginPermissionApps = pm.getPackagesHoldingPermissions( @@ -224,7 +225,7 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { for (String action : pluginActions) { String name = toName(action); List result = pm.queryIntentServices( - new Intent(action), MATCH_DISABLED_COMPONENTS); + new Intent(action), MATCH_DISABLED_COMPONENTS | GET_RESOLVED_FILTER); for (ResolveInfo info : result) { String packageName = info.serviceInfo.packageName; if (!pluginPermissionApps.contains(packageName)) { @@ -235,7 +236,7 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { if (!plugins.containsKey(key)) { plugins.put(key, new ArrayList<>()); } - plugins.get(key).add(Pair.create(name, info.serviceInfo)); + plugins.get(key).add(Pair.create(name, info)); } } @@ -243,11 +244,11 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { plugins.forEach((key, si) -> { String packageName = key.first; List componentNames = si.stream() - .map(p -> new ComponentName(packageName, p.second.name)) + .map(p -> new ComponentName(packageName, p.second.serviceInfo.name)) .collect(Collectors.toList()); if (!componentNames.isEmpty()) { SwitchPreference pref = new PluginPreference( - prefContext, si.get(0).second.applicationInfo, enabler, componentNames); + prefContext, si.get(0).second, enabler, componentNames); pref.setSummary("Plugins: " + si.stream().map(p -> p.first).collect(Collectors.joining(", "))); mPluginsCategory.addPreference(pref); @@ -341,21 +342,33 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { } private static class PluginPreference extends SwitchPreference { - private final boolean mHasSettings; - private final PreferenceDataStore mPluginEnabler; private final String mPackageName; + private final ResolveInfo mSettingsInfo; + private final PreferenceDataStore mPluginEnabler; private final List mComponentNames; - PluginPreference(Context prefContext, ApplicationInfo info, + PluginPreference(Context prefContext, ResolveInfo pluginInfo, PreferenceDataStore pluginEnabler, List componentNames) { super(prefContext); PackageManager pm = prefContext.getPackageManager(); - mHasSettings = pm.resolveActivity(new Intent(ACTION_PLUGIN_SETTINGS) - .setPackage(info.packageName), 0) != null; - mPackageName = info.packageName; - mComponentNames = componentNames; + mPackageName = pluginInfo.serviceInfo.applicationInfo.packageName; + Intent settingsIntent = new Intent(ACTION_PLUGIN_SETTINGS).setPackage(mPackageName); + // If any Settings activity in app has category filters, set plugin action as category. + List settingsInfos = + pm.queryIntentActivities(settingsIntent, GET_RESOLVED_FILTER); + if (pluginInfo.filter != null) { + for (ResolveInfo settingsInfo : settingsInfos) { + if (settingsInfo.filter != null && settingsInfo.filter.countCategories() > 0) { + settingsIntent.addCategory(pluginInfo.filter.getAction(0)); + break; + } + } + } + + mSettingsInfo = pm.resolveActivity(settingsIntent, 0); mPluginEnabler = pluginEnabler; - setTitle(info.loadLabel(pm)); + mComponentNames = componentNames; + setTitle(pluginInfo.loadLabel(pm)); setChecked(isPluginEnabled()); setWidgetLayoutResource(R.layout.switch_preference_with_settings); } @@ -396,17 +409,14 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - holder.findViewById(R.id.settings).setVisibility(mHasSettings ? View.VISIBLE - : View.GONE); - holder.findViewById(R.id.divider).setVisibility(mHasSettings ? View.VISIBLE - : View.GONE); + boolean hasSettings = mSettingsInfo != null; + holder.findViewById(R.id.settings).setVisibility(hasSettings ? VISIBLE : GONE); + holder.findViewById(R.id.divider).setVisibility(hasSettings ? VISIBLE : GONE); holder.findViewById(R.id.settings).setOnClickListener(v -> { - ResolveInfo result = v.getContext().getPackageManager().resolveActivity( - new Intent(ACTION_PLUGIN_SETTINGS).setPackage(mPackageName), 0); - if (result != null) { + if (hasSettings) { v.getContext().startActivity(new Intent().setComponent( - new ComponentName(result.activityInfo.packageName, - result.activityInfo.name))); + new ComponentName(mSettingsInfo.activityInfo.packageName, + mSettingsInfo.activityInfo.name))); } }); holder.itemView.setOnLongClickListener(v -> {