1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.uioverrides.plugins;
18 
19 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
20 
21 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
22 
23 import android.app.NotificationManager;
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.ResolveInfo;
28 
29 import com.android.launcher3.BuildConfig;
30 import com.android.launcher3.util.PluginManagerWrapper;
31 import com.android.systemui.plugins.Plugin;
32 import com.android.systemui.plugins.PluginListener;
33 import com.android.systemui.shared.plugins.PluginActionManager;
34 import com.android.systemui.shared.plugins.PluginInstance;
35 import com.android.systemui.shared.plugins.PluginManagerImpl;
36 import com.android.systemui.shared.plugins.PluginPrefs;
37 import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
38 
39 import java.io.PrintWriter;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.List;
43 import java.util.Set;
44 
45 public class PluginManagerWrapperImpl extends PluginManagerWrapper {
46 
47     private static final UncaughtExceptionPreHandlerManager UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER =
48             new UncaughtExceptionPreHandlerManager();
49 
50     private final Context mContext;
51     private final PluginManagerImpl mPluginManager;
52     private final PluginEnablerImpl mPluginEnabler;
53 
PluginManagerWrapperImpl(Context c)54     public PluginManagerWrapperImpl(Context c) {
55         mContext = c;
56         mPluginEnabler = new PluginEnablerImpl(c);
57         List<String> privilegedPlugins = Collections.emptyList();
58         PluginInstance.Factory instanceFactory = new PluginInstance.Factory(
59                 getClass().getClassLoader(), new PluginInstance.InstanceFactory<>(),
60                 new PluginInstance.VersionCheckerImpl(), privilegedPlugins,
61                 BuildConfig.IS_DEBUG_DEVICE);
62         PluginActionManager.Factory instanceManagerFactory = new PluginActionManager.Factory(
63                 c, c.getPackageManager(), c.getMainExecutor(), MODEL_EXECUTOR,
64                 c.getSystemService(NotificationManager.class), mPluginEnabler,
65                 privilegedPlugins, instanceFactory);
66 
67         mPluginManager = new PluginManagerImpl(c, instanceManagerFactory,
68                 BuildConfig.IS_DEBUG_DEVICE,
69                 UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER, mPluginEnabler,
70                 new PluginPrefs(c), privilegedPlugins);
71     }
72 
getPluginEnabler()73     public PluginEnablerImpl getPluginEnabler() {
74         return mPluginEnabler;
75     }
76 
77     @Override
addPluginListener( PluginListener<T> listener, Class<T> pluginClass, boolean allowMultiple)78     public <T extends Plugin> void addPluginListener(
79             PluginListener<T> listener, Class<T> pluginClass, boolean allowMultiple) {
80         mPluginManager.addPluginListener(listener, pluginClass, allowMultiple);
81     }
82 
83     @Override
removePluginListener(PluginListener<? extends Plugin> listener)84     public void removePluginListener(PluginListener<? extends Plugin> listener) {
85         mPluginManager.removePluginListener(listener);
86     }
87 
getPluginActions()88     public Set<String> getPluginActions() {
89         return new PluginPrefs(mContext).getPluginList();
90     }
91 
92     /** Notifies that a plugin state has changed */
notifyChange(Intent intent)93     public void notifyChange(Intent intent) {
94         mPluginManager.onReceive(mContext, intent);
95     }
96 
97     @Override
dump(PrintWriter pw)98     public void dump(PrintWriter pw) {
99         final List<ComponentName> enabledPlugins = new ArrayList<>();
100         final List<ComponentName> disabledPlugins = new ArrayList<>();
101         for (String action : getPluginActions()) {
102             for (ResolveInfo resolveInfo : mContext.getPackageManager().queryIntentServices(
103                     new Intent(action), MATCH_DISABLED_COMPONENTS)) {
104                 ComponentName installedPlugin = new ComponentName(
105                         resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
106                 if (mPluginEnabler.isEnabled(installedPlugin)) {
107                     enabledPlugins.add(installedPlugin);
108                 } else {
109                     disabledPlugins.add(installedPlugin);
110                 }
111             }
112         }
113 
114         pw.println("PluginManager:");
115         pw.println("  numEnabledPlugins=" + enabledPlugins.size());
116         pw.println("  numDisabledPlugins=" + disabledPlugins.size());
117         pw.println("  enabledPlugins=" + enabledPlugins);
118         pw.println("  disabledPlugins=" + disabledPlugins);
119     }
120 }
121