Adding utility class to load customization resources for easier prototype

Also adding support for grouping multiple plugins in same APK using process name

To customize resources update the defination of dymanic_resources in config.xml:
    <array name="dynamic_resources">
        <item>@color/delete_target_hover_tint</item>
        <item>@integer/config_folderDelay</item>
        <item>@dimen/all_apps_action_spacing</item>
        <item>@fraction/container_margin</item>
    </array>

Change-Id: I79c08845464510af96b16d375b424ad914657f39
This commit is contained in:
Sunny Goyal
2019-11-08 13:43:58 -08:00
parent 4b62b18aa1
commit 7b97eebbe5
6 changed files with 209 additions and 54 deletions

View File

@@ -15,6 +15,8 @@
*/
package com.android.launcher3.settings;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
@@ -24,28 +26,21 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
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;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.FlagTogglerPrefUi;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import java.util.List;
import java.util.Set;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceDataStore;
@@ -54,6 +49,16 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.FlagTogglerPrefUi;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Dev-build only UI allowing developers to toggle flag settings and plugins.
* See {@link FeatureFlags}.
@@ -154,44 +159,53 @@ public class DeveloperOptionsFragment extends PreferenceFragment {
PackageManager pm = getContext().getPackageManager();
Set<String> pluginActions = manager.getPluginActions();
ArrayMap<String, ArraySet<String>> plugins = new ArrayMap<>();
ArrayMap<Pair<String, String>, ArrayList<Pair<String, ServiceInfo>>> plugins =
new ArrayMap<>();
Set<String> pluginPermissionApps = pm.getPackagesHoldingPermissions(
new String[]{PLUGIN_PERMISSION}, MATCH_DISABLED_COMPONENTS)
.stream()
.map(pi -> pi.packageName)
.collect(Collectors.toSet());
for (String action : pluginActions) {
String name = toName(action);
List<ResolveInfo> result = pm.queryIntentServices(
new Intent(action), PackageManager.MATCH_DISABLED_COMPONENTS);
new Intent(action), MATCH_DISABLED_COMPONENTS);
for (ResolveInfo info : result) {
String packageName = info.serviceInfo.packageName;
if (!plugins.containsKey(packageName)) {
plugins.put(packageName, new ArraySet<>());
if (!pluginPermissionApps.contains(packageName)) {
continue;
}
plugins.get(packageName).add(name);
Pair<String, String> key = Pair.create(packageName, info.serviceInfo.processName);
if (!plugins.containsKey(key)) {
plugins.put(key, new ArrayList<>());
}
plugins.get(key).add(Pair.create(name, info.serviceInfo));
}
}
List<PackageInfo> apps = pm.getPackagesHoldingPermissions(new String[]{PLUGIN_PERMISSION},
PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.GET_SERVICES);
PreferenceDataStore enabled = manager.getPluginEnabler();
apps.forEach(app -> {
if (!plugins.containsKey(app.packageName)) return;
SwitchPreference pref = new PluginPreference(prefContext, app, enabled);
pref.setSummary("Plugins: " + toString(plugins.get(app.packageName)));
mPluginsCategory.addPreference(pref);
PreferenceDataStore enabler = manager.getPluginEnabler();
plugins.forEach((key, si) -> {
String packageName = key.first;
List<ComponentName> componentNames = si.stream()
.map(p -> new ComponentName(packageName, p.second.name))
.collect(Collectors.toList());
if (!componentNames.isEmpty()) {
SwitchPreference pref = new PluginPreference(
prefContext, si.get(0).second.applicationInfo, enabler, componentNames);
pref.setSummary("Plugins: "
+ si.stream().map(p -> p.first).collect(Collectors.joining(", ")));
mPluginsCategory.addPreference(pref);
}
});
}
private String toString(ArraySet<String> plugins) {
StringBuilder b = new StringBuilder();
for (String string : plugins) {
if (b.length() != 0) {
b.append(", ");
}
b.append(string);
}
return b.toString();
}
private String toName(String action) {
String str = action.replace("com.android.systemui.action.PLUGIN_", "");
String str = action.replace("com.android.systemui.action.PLUGIN_", "")
.replace("com.android.launcher3.action.PLUGIN_", "");
StringBuilder b = new StringBuilder();
for (String s : str.split("_")) {
if (b.length() != 0) {
@@ -205,18 +219,20 @@ public class DeveloperOptionsFragment extends PreferenceFragment {
private static class PluginPreference extends SwitchPreference {
private final boolean mHasSettings;
private final PackageInfo mInfo;
private final PreferenceDataStore mPluginEnabler;
private final String mPackageName;
private final List<ComponentName> mComponentNames;
public PluginPreference(Context prefContext, PackageInfo info,
PreferenceDataStore pluginEnabler) {
PluginPreference(Context prefContext, ApplicationInfo info,
PreferenceDataStore pluginEnabler, List<ComponentName> componentNames) {
super(prefContext);
PackageManager pm = prefContext.getPackageManager();
mHasSettings = pm.resolveActivity(new Intent(ACTION_PLUGIN_SETTINGS)
.setPackage(info.packageName), 0) != null;
mInfo = info;
mPackageName = info.packageName;
mComponentNames = componentNames;
mPluginEnabler = pluginEnabler;
setTitle(info.applicationInfo.loadLabel(pm));
setTitle(info.loadLabel(pm));
setChecked(isPluginEnabled());
setWidgetLayoutResource(R.layout.switch_preference_with_settings);
}
@@ -227,9 +243,7 @@ public class DeveloperOptionsFragment extends PreferenceFragment {
}
private boolean isPluginEnabled() {
for (int i = 0; i < mInfo.services.length; i++) {
ComponentName componentName = new ComponentName(mInfo.packageName,
mInfo.services[i].name);
for (ComponentName componentName : mComponentNames) {
if (!isEnabled(componentName)) {
return false;
}
@@ -240,17 +254,14 @@ public class DeveloperOptionsFragment extends PreferenceFragment {
@Override
protected boolean persistBoolean(boolean isEnabled) {
boolean shouldSendBroadcast = false;
for (int i = 0; i < mInfo.services.length; i++) {
ComponentName componentName = new ComponentName(mInfo.packageName,
mInfo.services[i].name);
for (ComponentName componentName : mComponentNames) {
if (isEnabled(componentName) != isEnabled) {
mPluginEnabler.putBoolean(pluginEnabledKey(componentName), isEnabled);
shouldSendBroadcast = true;
}
}
if (shouldSendBroadcast) {
final String pkg = mInfo.packageName;
final String pkg = mPackageName;
final Intent intent = new Intent(PLUGIN_CHANGED,
pkg != null ? Uri.fromParts("package", pkg, null) : null);
getContext().sendBroadcast(intent);
@@ -268,8 +279,7 @@ public class DeveloperOptionsFragment extends PreferenceFragment {
: View.GONE);
holder.findViewById(R.id.settings).setOnClickListener(v -> {
ResolveInfo result = v.getContext().getPackageManager().resolveActivity(
new Intent(ACTION_PLUGIN_SETTINGS).setPackage(
mInfo.packageName), 0);
new Intent(ACTION_PLUGIN_SETTINGS).setPackage(mPackageName), 0);
if (result != null) {
v.getContext().startActivity(new Intent().setComponent(
new ComponentName(result.activityInfo.packageName,
@@ -278,7 +288,7 @@ public class DeveloperOptionsFragment extends PreferenceFragment {
});
holder.itemView.setOnLongClickListener(v -> {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", mInfo.packageName, null));
intent.setData(Uri.fromParts("package", mPackageName, null));
getContext().startActivity(intent);
return true;
});