Skip to content
Commit 86bc3318 authored by Jason Monk's avatar Jason Monk
Browse files

Plugins for sysui

Why this is safe:
 - To never ever be used in production code, simply for rapid
   prototyping (multiple checks in place)
 - Guarded by signature level permission checks, so only matching
   signed code will be used
 - Any crashing plugins are auto-disabled and sysui is allowed
   to continue in peace

Now on to what it actually does.  Plugins are separate APKs that
are expected to implement interfaces provided by SystemUI.  Their
code is dynamically loaded into the SysUI process which can allow
for multiple prototypes to be created and run on a single android
build.

-------

PluginLifecycle:

plugin.onCreate(Context sysuiContext, Context pluginContext);
 --- This is always called before any other calls

pluginListener.onPluginConnected(Plugin p);
 --- This lets the plugin hook know that a plugin is now connected.

** Any other calls back and forth between sysui/plugin **

pluginListener.onPluginDisconnected(Plugin p);
 --- Lets the plugin hook know that it should stop interacting with
     this plugin and drop all references to it.

plugin.onDestroy();
 --- Finally the plugin can perform any cleanup to ensure that its not
     leaking into the SysUI process.

Any time a plugin APK is updated the plugin is destroyed and recreated
to load the new code/resources.

-------

Creating plugin hooks:

To create a plugin hook, first create an interface in
frameworks/base/packages/SystemUI/plugin that extends Plugin.
Include in it any hooks you want to be able to call into from
sysui and create callback interfaces for anything you need to
pass through into the plugin.

Then to attach to any plugins simply add a plugin listener and
onPluginConnected will get called whenever new plugins are installed,
updated, or enabled.  Like this example from SystemUIApplication:

PluginManager.getInstance(this).addPluginListener(OverlayPlugin.COMPONENT,
        new PluginListener<OverlayPlugin>() {
    @Override
    public void onPluginConnected(OverlayPlugin plugin) {
        PhoneStatusBar phoneStatusBar = getComponent(PhoneStatusBar.class);
        if (phoneStatusBar != null) {
            plugin.setup(phoneStatusBar.getStatusBarWindow(),
                    phoneStatusBar.getNavigationBarView());
        }
    }
}, OverlayPlugin.VERSION, true /* Allow multiple plugins */);

Note the VERSION included here.  Any time incompatible changes in the
interface are made, this version should be changed to ensure old plugins
aren't accidentally loaded.  Since the plugin library is provided by
SystemUI, default implementations can be added for new methods to avoid
version changes when possible.

-------

Implementing a Plugin:

See the ExamplePlugin for an example Android.mk on how to compile
a plugin.  Note that SystemUILib is not static for plugins, its classes
are provided by SystemUI.

Plugin security is based around a signature permission, so plugins must
hold the following permission in their manifest.

<uses-permission android:name="com.android.systemui.permission.PLUGIN" />

A plugin is found through a querying for services, so to let SysUI know
about it, create a service with a name that points at your implementation
of the plugin interface with the action accompanying it:

<service android:name=".TestOverlayPlugin">
    <intent-filter>
        <action android:name="com.android.systemui.action.PLUGIN_COMPONENT" />
    </intent-filter>
</service>

Change-Id: I42c573a94907ca7a2eaacbb0a44614d49b8fc26f
parent 72b817d1
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment