Using resource overrides for PluginManager instead of code-swap

Bug: 330920490
Test: Presubmit
Flag: None
Change-Id: Ib1cd50f95873928b9ce104e8e95d21f1dca9c6e3
This commit is contained in:
Sunny Goyal
2024-04-08 11:56:50 -07:00
parent c77a9ae116
commit 4a22ed81ea
16 changed files with 204 additions and 335 deletions

View File

@@ -34,6 +34,7 @@
<string name="taskbar_model_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarModelCallbacksFactory</string>
<string name="taskbar_view_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarViewCallbacksFactory</string>
<string name="launcher_restore_event_logger_class" translatable="false">com.android.quickstep.LauncherRestoreEventLoggerImpl</string>
<string name="plugin_manager_wrapper_class" translatable="false">com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl</string>
<string name="nav_handle_long_press_handler_class" translatable="false"></string>
<string name="assist_utils_class" translatable="false"></string>

View File

@@ -16,8 +16,12 @@
package com.android.launcher3.uioverrides.flags
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Handler
import android.provider.DeviceConfig
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
import android.text.Html
import android.view.inputmethod.EditorInfo
import androidx.preference.Preference
@@ -26,9 +30,12 @@ import androidx.preference.PreferenceViewHolder
import androidx.preference.SwitchPreference
import com.android.launcher3.ExtendedEditText
import com.android.launcher3.R
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl
import com.android.launcher3.util.PluginManagerWrapper
import com.android.quickstep.util.DeviceConfigHelper
import com.android.quickstep.util.DeviceConfigHelper.Companion.NAMESPACE_LAUNCHER
import com.android.quickstep.util.DeviceConfigHelper.DebugInfo
import com.android.systemui.shared.plugins.PluginEnabler
/** Helper class to generate UI for Device Config */
class DevOptionsUiHelper {
@@ -142,7 +149,92 @@ class DevOptionsUiHelper {
.getInt(this.key, DeviceConfig.getInt(NAMESPACE_LAUNCHER, this.key, this.valueInCode))
.toString()
/**
* Inflates the preferences for plugins
*
* A single pref is added for a plugin-group. A plugin-group is a collection of plugins in a
* single apk which have the same android:process tags defined. The apk should also hold the
* PLUGIN_PERMISSION. We collect all the plugin intents which Launcher listens for and fetch all
* corresponding plugins on the device. When a plugin-group is enabled/disabled we also need to
* notify the pluginManager manually since the broadcast-mechanism only works in sysui process
*/
fun inflatePluginPrefs(parent: PreferenceGroup) {
val context = parent.context
val manager = PluginManagerWrapper.INSTANCE[context] as PluginManagerWrapperImpl
val pm = context.packageManager
val pluginPermissionApps =
pm.getPackagesHoldingPermissions(
arrayOf(PLUGIN_PERMISSION),
PackageManager.MATCH_DISABLED_COMPONENTS
)
.map { it.packageName }
manager.pluginActions
.flatMap { action ->
pm.queryIntentServices(
Intent(action),
PackageManager.MATCH_DISABLED_COMPONENTS or
PackageManager.GET_RESOLVED_FILTER
)
.filter { pluginPermissionApps.contains(it.serviceInfo.packageName) }
}
.groupBy { "${it.serviceInfo.packageName}-${it.serviceInfo.processName}" }
.values
.forEach { infoList ->
val pluginInfo = infoList[0]!!
val pluginUri = Uri.fromParts("package", pluginInfo.serviceInfo.packageName, null)
object : SwitchPreference(context) {
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
holder.itemView.setOnLongClickListener {
context.startActivity(
Intent(ACTION_APPLICATION_DETAILS_SETTINGS, pluginUri)
)
true
}
}
}
.apply {
isPersistent = true
title = pluginInfo.loadLabel(pm)
isChecked =
infoList.all {
manager.pluginEnabler.isEnabled(it.serviceInfo.componentName)
}
summary =
infoList
.map { it.filter }
.filter { it?.countActions() ?: 0 > 0 }
.joinToString(prefix = "Plugins: ") {
it.getAction(0)
.replace("com.android.systemui.action.PLUGIN_", "")
.replace("com.android.launcher3.action.PLUGIN_", "")
}
setOnPreferenceChangeListener { _, newVal ->
val disabledState =
if (newVal as Boolean) PluginEnabler.ENABLED
else PluginEnabler.DISABLED_MANUALLY
infoList.forEach {
manager.pluginEnabler.setDisabled(
it.serviceInfo.componentName,
disabledState
)
}
manager.notifyChange(Intent(Intent.ACTION_PACKAGE_CHANGED, pluginUri))
true
}
parent.addPreference(this)
}
}
}
companion object {
const val TAG = "DeviceConfigUIHelper"
const val PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN"
}
}

View File

@@ -15,13 +15,7 @@
*/
package com.android.launcher3.uioverrides.flags;
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.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
@@ -29,18 +23,11 @@ import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_C
import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
import static com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.ArrayMap;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -52,20 +39,12 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.systemui.shared.plugins.PluginEnabler;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.android.systemui.shared.plugins.PluginPrefs;
/**
* Dev-build only UI allowing developers to toggle flag settings and plugins.
@@ -73,15 +52,9 @@ import java.util.stream.Collectors;
*/
public class DeveloperOptionsUI {
private static final String ACTION_PLUGIN_SETTINGS =
"com.android.systemui.action.PLUGIN_SETTINGS";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
private final PreferenceFragmentCompat mFragment;
private final PreferenceScreen mPreferenceScreen;
private PreferenceCategory mPluginsCategory;
public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
mFragment = fragment;
mPreferenceScreen = fragment.getPreferenceScreen();
@@ -97,8 +70,10 @@ public class DeveloperOptionsUI {
DevOptionsUiHelper uiHelper = new DevOptionsUiHelper();
uiHelper.inflateServerFlags(newCategory("Server flags"));
if (PluginPrefs.hasPlugins(getContext())) {
uiHelper.inflatePluginPrefs(newCategory("Plugins"));
}
loadPluginPrefs();
maybeAddSandboxCategory();
addOnboardingPrefsCatergory();
}
@@ -160,65 +135,6 @@ public class DeveloperOptionsUI {
return mFragment.requireContext();
}
private void loadPluginPrefs() {
if (mPluginsCategory != null) {
mPreferenceScreen.removePreference(mPluginsCategory);
}
if (!PluginManagerWrapper.hasPlugins(getContext())) {
mPluginsCategory = null;
return;
}
mPluginsCategory = newCategory("Plugins");
PluginManagerWrapper manager = PluginManagerWrapper.INSTANCE.get(getContext());
Context prefContext = getContext();
PackageManager pm = getContext().getPackageManager();
Set<String> pluginActions = manager.getPluginActions();
ArrayMap<Pair<String, String>, ArrayList<Pair<String, ResolveInfo>>> 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), MATCH_DISABLED_COMPONENTS | GET_RESOLVED_FILTER);
for (ResolveInfo info : result) {
String packageName = info.serviceInfo.packageName;
if (!pluginPermissionApps.contains(packageName)) {
continue;
}
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));
}
}
PluginEnabler enabler = manager.getPluginEnabler();
plugins.forEach((key, si) -> {
String packageName = key.first;
List<ComponentName> componentNames = si.stream()
.map(p -> new ComponentName(packageName, p.second.serviceInfo.name))
.collect(Collectors.toList());
if (!componentNames.isEmpty()) {
SwitchPreference pref = new PluginPreference(
prefContext, si.get(0).second, enabler, componentNames);
pref.setSummary("Plugins: "
+ si.stream().map(p -> p.first).collect(Collectors.joining(", ")));
mPluginsCategory.addPreference(pref);
}
});
}
private void maybeAddSandboxCategory() {
Context context = getContext();
if (context == null) {
@@ -321,102 +237,4 @@ public class DeveloperOptionsUI {
});
return onboardingPref;
}
private String toName(String action) {
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) {
b.append(' ');
}
b.append(s.substring(0, 1));
b.append(s.substring(1).toLowerCase());
}
return b.toString();
}
private static class PluginPreference extends SwitchPreference {
private final String mPackageName;
private final ResolveInfo mSettingsInfo;
private final PluginEnabler mPluginEnabler;
private final List<ComponentName> mComponentNames;
PluginPreference(Context prefContext, ResolveInfo pluginInfo,
PluginEnabler pluginEnabler, List<ComponentName> componentNames) {
super(prefContext);
PackageManager pm = prefContext.getPackageManager();
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<ResolveInfo> 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;
mComponentNames = componentNames;
setTitle(pluginInfo.loadLabel(pm));
setChecked(isPluginEnabled());
setWidgetLayoutResource(R.layout.switch_preference_with_settings);
}
private boolean isPluginEnabled() {
for (ComponentName componentName : mComponentNames) {
if (!mPluginEnabler.isEnabled(componentName)) {
return false;
}
}
return true;
}
@Override
protected boolean persistBoolean(boolean isEnabled) {
boolean shouldSendBroadcast = false;
for (ComponentName componentName : mComponentNames) {
if (mPluginEnabler.isEnabled(componentName) != isEnabled) {
mPluginEnabler.setDisabled(componentName,
isEnabled ? PluginEnabler.ENABLED : PluginEnabler.DISABLED_MANUALLY);
shouldSendBroadcast = true;
}
}
if (shouldSendBroadcast) {
final String pkg = mPackageName;
final Intent intent = new Intent(PLUGIN_CHANGED,
pkg != null ? Uri.fromParts("package", pkg, null) : null);
getContext().sendBroadcast(intent);
}
setChecked(isEnabled);
return true;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
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 -> {
if (hasSettings) {
v.getContext().startActivity(new Intent().setComponent(
new ComponentName(mSettingsInfo.activityInfo.packageName,
mSettingsInfo.activityInfo.name)));
}
});
holder.itemView.setOnLongClickListener(v -> {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", mPackageName, null));
getContext().startActivity(intent);
return true;
});
}
}
}

View File

@@ -1,15 +1,17 @@
/*
* Copyright (C) 2018 The Android Open Source Project
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.uioverrides.plugins;
@@ -24,11 +26,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.BuildConfig;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginActionManager;
import com.android.systemui.shared.plugins.PluginInstance;
import com.android.systemui.shared.plugins.PluginManagerImpl;
@@ -41,35 +42,30 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
public class PluginManagerWrapper {
public static final MainThreadInitializedObject<PluginManagerWrapper> INSTANCE =
new MainThreadInitializedObject<>(PluginManagerWrapper::new);
public static final String PLUGIN_CHANGED = PluginManager.PLUGIN_CHANGED;
public class PluginManagerWrapperImpl extends PluginManagerWrapper {
private static final UncaughtExceptionPreHandlerManager UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER =
new UncaughtExceptionPreHandlerManager();
private final Context mContext;
private final PluginManager mPluginManager;
private final PluginManagerImpl mPluginManager;
private final PluginEnablerImpl mPluginEnabler;
private PluginManagerWrapper(Context c) {
public PluginManagerWrapperImpl(Context c) {
mContext = c;
mPluginEnabler = new PluginEnablerImpl(c);
List<String> privilegedPlugins = Collections.emptyList();
PluginInstance.Factory instanceFactory = new PluginInstance.Factory(
getClass().getClassLoader(), new PluginInstance.InstanceFactory<>(),
new PluginInstance.VersionCheckerImpl(), privilegedPlugins,
Utilities.IS_DEBUG_DEVICE);
BuildConfig.IS_DEBUG_DEVICE);
PluginActionManager.Factory instanceManagerFactory = new PluginActionManager.Factory(
c, c.getPackageManager(), c.getMainExecutor(), MODEL_EXECUTOR,
c.getSystemService(NotificationManager.class), mPluginEnabler,
privilegedPlugins, instanceFactory);
mPluginManager = new PluginManagerImpl(c, instanceManagerFactory,
Utilities.IS_DEBUG_DEVICE,
BuildConfig.IS_DEBUG_DEVICE,
UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER, mPluginEnabler,
new PluginPrefs(c), privilegedPlugins);
}
@@ -78,18 +74,13 @@ public class PluginManagerWrapper {
return mPluginEnabler;
}
/** */
public <T extends Plugin> void addPluginListener(
PluginListener<T> listener, Class<T> pluginClass) {
addPluginListener(listener, pluginClass, false);
}
/** */
@Override
public <T extends Plugin> void addPluginListener(
PluginListener<T> listener, Class<T> pluginClass, boolean allowMultiple) {
mPluginManager.addPluginListener(listener, pluginClass, allowMultiple);
}
@Override
public void removePluginListener(PluginListener<? extends Plugin> listener) {
mPluginManager.removePluginListener(listener);
}
@@ -98,10 +89,12 @@ public class PluginManagerWrapper {
return new PluginPrefs(mContext).getPluginList();
}
public static boolean hasPlugins(Context context) {
return PluginPrefs.hasPlugins(context);
/** Notifies that a plugin state has changed */
public void notifyChange(Intent intent) {
mPluginManager.onReceive(mContext, intent);
}
@Override
public void dump(PrintWriter pw) {
final List<ComponentName> enabledPlugins = new ArrayList<>();
final List<ComponentName> disabledPlugins = new ArrayList<>();

View File

@@ -95,9 +95,9 @@ import com.android.launcher3.taskbar.TaskbarManager;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.LockedUserState;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.TraceHelper;

View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:id="@+id/settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_setting"
android:forceDarkAllowed="true"
android:padding="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless" />
<View
android:id="@+id/divider"
android:layout_width="1dp"
android:layout_height="30dp"
android:layout_marginEnd="8dp"
android:background="?android:attr/listDivider" />
<!-- Note: seems we need focusable="false" and clickable="false" when moving to androidx -->
<Switch
android:id="@android:id/switch_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null" />
</LinearLayout>

View File

@@ -84,7 +84,7 @@
<string name="wallpaper_picker_package" translatable="false"></string>
<string name="local_colors_extraction_class" translatable="false"></string>
<string name="search_session_manager_class" translatable="false"></string>
<string name="plugin_manager_wrapper_class" translatable="false"></string>
<!-- Scalable Grid configuration -->
<!-- This is a float because it is converted to dp later in DeviceProfile -->

View File

@@ -222,7 +222,6 @@ import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.ActivityResultInfo;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.BackPressHandler;
@@ -235,6 +234,7 @@ import com.android.launcher3.util.KeyboardShortcutsDelegate;
import com.android.launcher3.util.LockedUserState;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
@@ -576,8 +576,8 @@ public class Launcher extends StatefulActivity<LauncherState>
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
mOverlayManager = getDefaultOverlay();
PluginManagerWrapper.INSTANCE.get(this).addPluginListener(this,
LauncherOverlayPlugin.class, false /* allowedMultiple */);
PluginManagerWrapper.INSTANCE.get(this)
.addPluginListener(this, LauncherOverlayPlugin.class);
mRotationHelper.initialize();
TraceHelper.INSTANCE.endSection();

View File

@@ -34,7 +34,7 @@ import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.views.ActivityContext;
import com.android.systemui.plugins.AllAppsRow;
import com.android.systemui.plugins.AllAppsRow.OnHeightUpdatedListener;

View File

@@ -90,12 +90,12 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.launcher3.views.ActivityContext;

View File

@@ -22,7 +22,6 @@ import androidx.annotation.DimenRes;
import androidx.annotation.FractionRes;
import androidx.annotation.IntegerRes;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.ResourceProvider;

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.util;
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
import com.android.launcher3.R;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import java.io.PrintWriter;
public class PluginManagerWrapper implements ResourceBasedOverride, SafeCloseable {
public static final MainThreadInitializedObject<PluginManagerWrapper> INSTANCE =
forOverride(PluginManagerWrapper.class, R.string.plugin_manager_wrapper_class);
public <T extends Plugin> void addPluginListener(
PluginListener<T> listener, Class<T> pluginClass) {
addPluginListener(listener, pluginClass, false);
}
public <T extends Plugin> void addPluginListener(
PluginListener<T> listener, Class<T> pluginClass, boolean allowMultiple) {
}
public void removePluginListener(PluginListener<? extends Plugin> listener) { }
@Override
public void close() { }
public void dump(PrintWriter pw) { }
}

View File

@@ -32,9 +32,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.launcher3.uioverrides.plugins;
import android.content.ComponentName;
import android.content.Context;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import java.util.Collections;
import java.util.Set;
import androidx.preference.PreferenceDataStore;
public class PluginManagerWrapper {
public static final MainThreadInitializedObject<PluginManagerWrapper> INSTANCE =
new MainThreadInitializedObject<>(PluginManagerWrapper::new);
private static final String PREFIX_PLUGIN_ENABLED = "PLUGIN_ENABLED_";
public static final String PLUGIN_CHANGED = "com.android.systemui.action.PLUGIN_CHANGED";
private PluginManagerWrapper(Context c) {
}
public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass) {
}
public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass,
boolean allowMultiple) {
}
public void removePluginListener(PluginListener<? extends Plugin> listener) { }
public Set<String> getPluginActions() {
return Collections.emptySet();
}
public PreferenceDataStore getPluginEnabler() {
return new PreferenceDataStore() { };
}
public static String pluginEnabledKey(ComponentName cn) {
return PREFIX_PLUGIN_ENABLED + cn.flattenToString();
}
public static boolean hasPlugins(Context context) {
return false;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.plugins;
import com.android.systemui.plugins.annotations.ProvidesInterface;
/**
* Implement this plugin to proxy network requests
*/
@ProvidesInterface(action = NetworkFetcherPlugin.ACTION, version = NetworkFetcherPlugin.VERSION)
public interface NetworkFetcherPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_NETWORK_FETCHER_ACTIONS";
int VERSION = 1;
/** Fetches the provided user and return all byte contents */
byte[] fetchUrl(String url) throws Exception;
}

View File

@@ -60,7 +60,6 @@ import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.testing.TestInformationProvider;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.launcher3.widget.custom.CustomWidgetManager;