1 /*
2  * Copyright (C) 2016 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.systemui.plugins;
16 
17 import android.content.Context;
18 
19 /**
20  * Interface for listening to plugins being connected and disconnected.
21  *
22  * The call order for a plugin is
23  *  1) {@link #onPluginAttached}
24  *          Called when a new plugin is added to the device, or an existing plugin was replaced by
25  *          the package manager. Will only be called once per package manager event. If multiple
26  *          non-conflicting packages which have the same plugin interface are installed on the
27  *          device, then this method can be called multiple times with different instances of
28  *          {@link PluginLifecycleManager} (as long as `allowMultiple` was set to true when the
29  *          listener was registered with {@link PluginManager#addPluginListener}).
30  *  2) {@link #onPluginLoaded}
31  *          Called whenever a new instance of the plugin object is created and ready for use. Can be
32  *          called multiple times per {@link PluginLifecycleManager}, but will always pass a newly
33  *          created plugin object. {@link #onPluginUnloaded} with the previous plugin object will
34  *          be called before another call to {@link #onPluginLoaded} is made. This method will be
35  *          called once automatically after {@link #onPluginAttached}. Besides the initial call,
36  *          {@link #onPluginLoaded} will occur due to {@link PluginLifecycleManager#loadPlugin}.
37  *  3) {@link #onPluginUnloaded}
38  *          Called when a request to unload the plugin has been received. This can be triggered from
39  *          a related call to {@link PluginLifecycleManager#unloadPlugin} or for any reason that
40  *          {@link #onPluginDetached} would be triggered.
41  *  4) {@link #onPluginDetached}
42  *          Called when the package is removed from the device, disabled, or replaced due to an
43  *          external trigger. These are events from the android package manager.
44  *
45  * @param <T> is the target plugin type
46  */
47 public interface PluginListener<T extends Plugin> {
48     /**
49      * Called when the plugin has been loaded and is ready to be used.
50      * This may be called multiple times if multiple plugins are allowed.
51      * It may also be called in the future if the plugin package changes
52      * and needs to be reloaded.
53      *
54      * @deprecated Migrate to {@link #onPluginLoaded} or {@link #onPluginAttached}
55      */
56     @Deprecated
onPluginConnected(T plugin, Context pluginContext)57     default void onPluginConnected(T plugin, Context pluginContext) {
58         // Optional
59     }
60 
61     /**
62      * Called when the plugin is first attached to the host application. {@link #onPluginLoaded}
63      * will be automatically called as well when first attached if true is returned. This may be
64      * called multiple times if multiple plugins are allowed. It may also be called in the future
65      * if the plugin package changes and needs to be reloaded. Each call to
66      * {@link #onPluginAttached} will provide a new or different {@link PluginLifecycleManager}.
67      *
68      * @return returning true will immediately load the plugin and call onPluginLoaded with the
69      *   created object. false will skip loading, but the listener can load it at any time using the
70      *   provided PluginLifecycleManager. Loading plugins immediately is the default behavior.
71      */
onPluginAttached(PluginLifecycleManager<T> manager)72     default boolean onPluginAttached(PluginLifecycleManager<T> manager) {
73         // Optional
74         return true;
75     }
76 
77     /**
78      * Called when a plugin has been uninstalled/updated and should be removed
79      * from use.
80      *
81      * @deprecated Migrate to {@link #onPluginDetached} or {@link #onPluginUnloaded}
82      */
83     @Deprecated
onPluginDisconnected(T plugin)84     default void onPluginDisconnected(T plugin) {
85         // Optional.
86     }
87 
88     /**
89      * Called when the plugin has been detached from the host application. Implementers should no
90      * longer attempt to reload it via this {@link PluginLifecycleManager}. If the package was
91      * updated and not removed, then {@link #onPluginAttached} will be called again when the updated
92      * package is available.
93      */
onPluginDetached(PluginLifecycleManager<T> manager)94     default void onPluginDetached(PluginLifecycleManager<T> manager) {
95         // Optional.
96     }
97 
98     /**
99      * Called when the plugin is loaded into the host's process and is available for use. This can
100      * happen several times if clients are using {@link PluginLifecycleManager} to manipulate a
101      * plugin's load state. Each call to {@link #onPluginLoaded} will have a matched call to
102      * {@link #onPluginUnloaded} when that plugin object should no longer be used.
103      */
onPluginLoaded( T plugin, Context pluginContext, PluginLifecycleManager<T> manager )104     default void onPluginLoaded(
105             T plugin,
106             Context pluginContext,
107             PluginLifecycleManager<T> manager
108     ) {
109         // Optional, default to deprecated version
110         onPluginConnected(plugin, pluginContext);
111     }
112 
113     /**
114      * Called when the plugin should no longer be used. Listeners should clean up all references to
115      * the relevant plugin so that it can be garbage collected. If the plugin object is required in
116      * the future a call can be made to {@link PluginLifecycleManager#loadPlugin} to create a new
117      * plugin object and trigger {@link #onPluginLoaded}.
118      */
onPluginUnloaded(T plugin, PluginLifecycleManager<T> manager)119     default void onPluginUnloaded(T plugin, PluginLifecycleManager<T> manager) {
120         // Optional, default to deprecated version
121         onPluginDisconnected(plugin);
122     }
123 }