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