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