Home | History | Annotate | Download | only in plugins
      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 package com.android.systemui.plugins;
     15 
     16 import com.android.systemui.plugins.annotations.Requires;
     17 
     18 import android.content.Context;
     19 
     20 /**
     21  * Plugins are separate APKs that
     22  * are expected to implement interfaces provided by SystemUI.  Their
     23  * code is dynamically loaded into the SysUI process which can allow
     24  * for multiple prototypes to be created and run on a single android
     25  * build.
     26  *
     27  * PluginLifecycle:
     28  * <pre class="prettyprint">
     29  *
     30  * plugin.onCreate(Context sysuiContext, Context pluginContext);
     31  * --- This is always called before any other calls
     32  *
     33  * pluginListener.onPluginConnected(Plugin p);
     34  * --- This lets the plugin hook know that a plugin is now connected.
     35  *
     36  * ** Any other calls back and forth between sysui/plugin **
     37  *
     38  * pluginListener.onPluginDisconnected(Plugin p);
     39  * --- Lets the plugin hook know that it should stop interacting with
     40  *     this plugin and drop all references to it.
     41  *
     42  * plugin.onDestroy();
     43  * --- Finally the plugin can perform any cleanup to ensure that its not
     44  *     leaking into the SysUI process.
     45  *
     46  * Any time a plugin APK is updated the plugin is destroyed and recreated
     47  * to load the new code/resources.
     48  *
     49  * </pre>
     50  *
     51  * Creating plugin hooks:
     52  *
     53  * To create a plugin hook, first create an interface in
     54  * frameworks/base/packages/SystemUI/plugin that extends Plugin.
     55  * Include in it any hooks you want to be able to call into from
     56  * sysui and create callback interfaces for anything you need to
     57  * pass through into the plugin.
     58  *
     59  * Then to attach to any plugins simply add a plugin listener and
     60  * onPluginConnected will get called whenever new plugins are installed,
     61  * updated, or enabled.  Like this example from SystemUIApplication:
     62  *
     63  * <pre class="prettyprint">
     64  * {@literal
     65  * PluginManager.getInstance(this).addPluginListener(OverlayPlugin.COMPONENT,
     66  *        new PluginListener<OverlayPlugin>() {
     67  *        @Override
     68  *        public void onPluginConnected(OverlayPlugin plugin) {
     69  *            StatusBar phoneStatusBar = getComponent(StatusBar.class);
     70  *            if (phoneStatusBar != null) {
     71  *                plugin.setup(phoneStatusBar.getStatusBarWindow(),
     72  *                phoneStatusBar.getNavigationBarView());
     73  *            }
     74  *        }
     75  * }, OverlayPlugin.VERSION, true /* Allow multiple plugins *\/);
     76  * }
     77  * </pre>
     78  * Note the VERSION included here.  Any time incompatible changes in the
     79  * interface are made, this version should be changed to ensure old plugins
     80  * aren't accidentally loaded.  Since the plugin library is provided by
     81  * SystemUI, default implementations can be added for new methods to avoid
     82  * version changes when possible.
     83  *
     84  * Implementing a Plugin:
     85  *
     86  * See the ExamplePlugin for an example Android.mk on how to compile
     87  * a plugin.  Note that SystemUILib is not static for plugins, its classes
     88  * are provided by SystemUI.
     89  *
     90  * Plugin security is based around a signature permission, so plugins must
     91  * hold the following permission in their manifest.
     92  *
     93  * <pre class="prettyprint">
     94  * {@literal
     95  * <uses-permission android:name="com.android.systemui.permission.PLUGIN" />
     96  * }
     97  * </pre>
     98  *
     99  * A plugin is found through a querying for services, so to let SysUI know
    100  * about it, create a service with a name that points at your implementation
    101  * of the plugin interface with the action accompanying it:
    102  *
    103  * <pre class="prettyprint">
    104  * {@literal
    105  * <service android:name=".TestOverlayPlugin">
    106  *    <intent-filter>
    107  *        <action android:name="com.android.systemui.action.PLUGIN_COMPONENT" />
    108  *    </intent-filter>
    109  * </service>
    110  * }
    111  * </pre>
    112  */
    113 public interface Plugin {
    114 
    115     /**
    116      * @deprecated
    117      * @see Requires
    118      */
    119     default int getVersion() {
    120         // Default of -1 indicates the plugin supports the new Requires model.
    121         return -1;
    122     }
    123 
    124     default void onCreate(Context sysuiContext, Context pluginContext) {
    125     }
    126 
    127     default void onDestroy() {
    128     }
    129 }
    130