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