1 /*
2  * Copyright (C) 2021 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.systemui.plugins;
18 
19 import static com.android.systemui.util.concurrency.GlobalConcurrencyModule.PRE_HANDLER;
20 
21 import android.app.NotificationManager;
22 import android.content.Context;
23 import android.content.pm.PackageManager;
24 import android.os.Build;
25 
26 import com.android.systemui.R;
27 import com.android.systemui.dagger.PluginModule;
28 import com.android.systemui.dagger.qualifiers.Main;
29 import com.android.systemui.shared.plugins.PluginActionManager;
30 import com.android.systemui.shared.plugins.PluginEnabler;
31 import com.android.systemui.shared.plugins.PluginInstance;
32 import com.android.systemui.shared.plugins.PluginManager;
33 import com.android.systemui.shared.plugins.PluginManagerImpl;
34 import com.android.systemui.shared.plugins.PluginPrefs;
35 import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
36 import com.android.systemui.util.concurrency.ThreadFactory;
37 
38 import java.util.Arrays;
39 import java.util.List;
40 import java.util.Optional;
41 import java.util.concurrent.Executor;
42 
43 import javax.inject.Named;
44 import javax.inject.Singleton;
45 
46 import dagger.Binds;
47 import dagger.Module;
48 import dagger.Provides;
49 
50 /**
51  * Dagger Module for code related to plugins.
52  *
53  * Covers code both in com.android.systemui.plugins and code in
54  * com.android.systemui.shared.plugins.
55  */
56 @Module(includes = {GlobalConcurrencyModule.class})
57 public abstract class PluginsModule {
58     public static final String PLUGIN_THREAD = "plugin_thread";
59     public static final String PLUGIN_DEBUG = "plugin_debug";
60     public static final String PLUGIN_PRIVILEGED = "plugin_privileged";
61 
62     @Provides
63     @Named(PLUGIN_DEBUG)
providesPluginDebug()64     static boolean providesPluginDebug() {
65         return Build.IS_DEBUGGABLE;
66     }
67 
68     @Binds
bindsPluginEnablerImpl(PluginEnablerImpl impl)69     abstract PluginEnabler bindsPluginEnablerImpl(PluginEnablerImpl impl);
70 
71     @Provides
72     @Singleton
providesPluginInstanceFactory( @amedPLUGIN_PRIVILEGED) List<String> privilegedPlugins, @Named(PLUGIN_DEBUG) boolean isDebug)73     static PluginInstance.Factory providesPluginInstanceFactory(
74             @Named(PLUGIN_PRIVILEGED) List<String> privilegedPlugins,
75             @Named(PLUGIN_DEBUG) boolean isDebug) {
76         return new PluginInstance.Factory(
77                 PluginModule.class.getClassLoader(),
78                 new PluginInstance.InstanceFactory<>(),
79                 new PluginInstance.VersionChecker(),
80                 privilegedPlugins,
81                 isDebug);
82     }
83 
84     @Provides
85     @Singleton
providePluginInstanceManagerFactory(Context context, PackageManager packageManager, @Main Executor mainExecutor, @Named(PLUGIN_THREAD) Executor pluginExecutor, NotificationManager notificationManager, PluginEnabler pluginEnabler, @Named(PLUGIN_PRIVILEGED) List<String> privilegedPlugins, PluginInstance.Factory pluginInstanceFactory)86     static PluginActionManager.Factory providePluginInstanceManagerFactory(Context context,
87             PackageManager packageManager, @Main Executor mainExecutor,
88             @Named(PLUGIN_THREAD) Executor pluginExecutor,
89             NotificationManager notificationManager, PluginEnabler pluginEnabler,
90             @Named(PLUGIN_PRIVILEGED) List<String> privilegedPlugins,
91             PluginInstance.Factory pluginInstanceFactory) {
92         return new PluginActionManager.Factory(
93                 context, packageManager, mainExecutor, pluginExecutor,
94                 notificationManager, pluginEnabler, privilegedPlugins, pluginInstanceFactory);
95     }
96 
97     @Provides
98     @Singleton
99     @Named(PLUGIN_THREAD)
providesPluginExecutor(ThreadFactory threadFactory)100     static Executor providesPluginExecutor(ThreadFactory threadFactory) {
101         return threadFactory.buildExecutorOnNewThread("plugin");
102     }
103 
104     @Provides
105     @Singleton
providesPluginManager( Context context, PluginActionManager.Factory instanceManagerFactory, @Named(PLUGIN_DEBUG) boolean debug, @Named(PRE_HANDLER) Optional<Thread.UncaughtExceptionHandler> uncaughtExceptionHandlerOptional, PluginEnabler pluginEnabler, PluginPrefs pluginPrefs, @Named(PLUGIN_PRIVILEGED) List<String> privilegedPlugins)106     static PluginManager providesPluginManager(
107             Context context,
108             PluginActionManager.Factory instanceManagerFactory,
109             @Named(PLUGIN_DEBUG) boolean debug,
110             @Named(PRE_HANDLER)
111                     Optional<Thread.UncaughtExceptionHandler> uncaughtExceptionHandlerOptional,
112             PluginEnabler pluginEnabler,
113             PluginPrefs pluginPrefs,
114             @Named(PLUGIN_PRIVILEGED) List<String> privilegedPlugins) {
115         return new PluginManagerImpl(context, instanceManagerFactory, debug,
116                 uncaughtExceptionHandlerOptional, pluginEnabler, pluginPrefs,
117                 privilegedPlugins);
118     }
119 
120     @Provides
providesPluginPrefs(Context context)121     static PluginPrefs providesPluginPrefs(Context context) {
122         return new PluginPrefs(context);
123     }
124 
125     @Provides
126     @Named(PLUGIN_PRIVILEGED)
providesPrivilegedPlugins(Context context)127     static List<String> providesPrivilegedPlugins(Context context) {
128         return Arrays.asList(context.getResources().getStringArray(R.array.config_pluginWhitelist));
129     }
130 }
131