summaryrefslogtreecommitdiff
path: root/packages/SystemUI/plugin_core
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2018-10-04 10:45:42 -0700
committerTony Wickham <twickham@google.com>2018-10-05 14:36:34 -0700
commitb4593f977b9ea51d4dc3d9f4d22c57b35ddaf753 (patch)
treea349a39daf786c7dfc4a9be28dd80f43ce262922 /packages/SystemUI/plugin_core
parent32c554373d268a9f66e49e232ec40c32dbc51f86 (diff)
Move code to plugin core lib
This contains the core interfaces for plugin support, e.g. Plugin.java and the associated annotations. It is reused by the shared library and plugin interfaces in both sysui and launcher are built off of it. Test: atest com.android.systemui.shared.plugins Test: cd $ANDROID_BUILD_TOP/frameworks/base/packages/SystemUI/plugin_core \ && mma -j32 && cd - out/target/product/$TARGET_PRODUCT/obj/JAVA_LIBRARIES/PluginCoreLib_intermediates/javalib.jar contains the created jar and is useable in launcher Bug: 115877296 Change-Id: I82ca7398e882d6432333238e2f77a12e776f1d76
Diffstat (limited to 'packages/SystemUI/plugin_core')
-rw-r--r--packages/SystemUI/plugin_core/Android.bp21
-rw-r--r--packages/SystemUI/plugin_core/AndroidManifest.xml24
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java129
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginFragment.java45
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java38
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Dependencies.java27
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/DependsOn.java32
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProvidesInterface.java30
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requirements.java27
-rw-r--r--packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requires.java33
10 files changed, 406 insertions, 0 deletions
diff --git a/packages/SystemUI/plugin_core/Android.bp b/packages/SystemUI/plugin_core/Android.bp
new file mode 100644
index 000000000000..58a8e494856e
--- /dev/null
+++ b/packages/SystemUI/plugin_core/Android.bp
@@ -0,0 +1,21 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+java_library {
+
+ name: "PluginCoreLib",
+
+ srcs: ["src/**/*.java"],
+
+}
diff --git a/packages/SystemUI/plugin_core/AndroidManifest.xml b/packages/SystemUI/plugin_core/AndroidManifest.xml
new file mode 100644
index 000000000000..df835fd8e32d
--- /dev/null
+++ b/packages/SystemUI/plugin_core/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.systemui.plugin_core">
+
+ <uses-sdk
+ android:minSdkVersion="28" />
+
+</manifest>
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
new file mode 100644
index 000000000000..bb93367c3791
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins;
+
+import com.android.systemui.plugins.annotations.Requires;
+
+import android.content.Context;
+
+/**
+ * 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:
+ * <pre class="prettyprint">
+ *
+ * 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.
+ *
+ * </pre>
+ *
+ * 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:
+ *
+ * <pre class="prettyprint">
+ * {@literal
+ * PluginManager.getInstance(this).addPluginListener(OverlayPlugin.COMPONENT,
+ * new PluginListener<OverlayPlugin>() {
+ * @Override
+ * public void onPluginConnected(OverlayPlugin plugin) {
+ * StatusBar phoneStatusBar = getComponent(StatusBar.class);
+ * if (phoneStatusBar != null) {
+ * plugin.setup(phoneStatusBar.getStatusBarWindow(),
+ * phoneStatusBar.getNavigationBarView());
+ * }
+ * }
+ * }, OverlayPlugin.VERSION, true /* Allow multiple plugins *\/);
+ * }
+ * </pre>
+ * 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.
+ *
+ * <pre class="prettyprint">
+ * {@literal
+ * <uses-permission android:name="com.android.systemui.permission.PLUGIN" />
+ * }
+ * </pre>
+ *
+ * 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:
+ *
+ * <pre class="prettyprint">
+ * {@literal
+ * <service android:name=".TestOverlayPlugin">
+ * <intent-filter>
+ * <action android:name="com.android.systemui.action.PLUGIN_COMPONENT" />
+ * </intent-filter>
+ * </service>
+ * }
+ * </pre>
+ */
+public interface Plugin {
+
+ /**
+ * @deprecated
+ * @see Requires
+ */
+ default int getVersion() {
+ // Default of -1 indicates the plugin supports the new Requires model.
+ return -1;
+ }
+
+ default void onCreate(Context sysuiContext, Context pluginContext) {
+ }
+
+ default void onDestroy() {
+ }
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginFragment.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginFragment.java
new file mode 100644
index 000000000000..1bfa567b6630
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginFragment.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+
+public abstract class PluginFragment extends Fragment implements Plugin {
+
+ private Context mPluginContext;
+
+ @Override
+ public void onCreate(Context sysuiContext, Context pluginContext) {
+ mPluginContext = pluginContext;
+ }
+
+ @Override
+ public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
+ return super.onGetLayoutInflater(savedInstanceState).cloneInContext(getContext());
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public Context getContext() {
+ return mPluginContext;
+ }
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
new file mode 100644
index 000000000000..b488d2a84baa
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.content.Context;
+
+/**
+ * Interface for listening to plugins being connected.
+ */
+public interface PluginListener<T extends Plugin> {
+ /**
+ * Called when the plugin has been loaded and is ready to be used.
+ * This may be called multiple times if multiple plugins are allowed.
+ * It may also be called in the future if the plugin package changes
+ * and needs to be reloaded.
+ */
+ void onPluginConnected(T plugin, Context pluginContext);
+
+ /**
+ * Called when a plugin has been uninstalled/updated and should be removed
+ * from use.
+ */
+ default void onPluginDisconnected(T plugin) {
+ // Optional.
+ }
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Dependencies.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Dependencies.java
new file mode 100644
index 000000000000..dbbf047519bb
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Dependencies.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used for repeated @DependsOn internally, not for plugin
+ * use.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Dependencies {
+ DependsOn[] value();
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/DependsOn.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/DependsOn.java
new file mode 100644
index 000000000000..b81d67306307
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/DependsOn.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins.annotations;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used to indicate that an interface in the plugin library needs another
+ * interface to function properly. When this is added, it will be enforced
+ * that all plugins that @Requires the annotated interface also @Requires
+ * the specified class as well.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(value = Dependencies.class)
+public @interface DependsOn {
+ Class<?> target();
+
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProvidesInterface.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProvidesInterface.java
new file mode 100644
index 000000000000..d0e14b8657ff
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProvidesInterface.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Should be added to all interfaces in plugin lib to specify their
+ * current version and optionally their action to implement the plugin.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ProvidesInterface {
+ int version();
+
+ String action() default "";
+
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requirements.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requirements.java
new file mode 100644
index 000000000000..9cfa279b9c19
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requirements.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used for repeated @Requires internally, not for plugin
+ * use.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Requirements {
+ Requires[] value();
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requires.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requires.java
new file mode 100644
index 000000000000..e1b1303b8cb5
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requires.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins.annotations;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used to annotate which interfaces a given plugin depends on.
+ *
+ * At minimum all plugins should have at least one @Requires annotation
+ * for the plugin interface that they are implementing. They will also
+ * need an @Requires for each class that the plugin interface @DependsOn.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(value = Requirements.class)
+public @interface Requires {
+ Class<?> target();
+ int version();
+}