Add plugin controls to tuner

Allow plugins to be manually turned off from within the tuner. This
screen only shows itself if at some point in time a plugin has been
active on this device.  Plugins can also serface settings there by
receiving the com.android.systemui.action.PLUGIN_SETTINGS action.

Test: Manual
Change-Id: Ifb043c85e383fc072c6445ae322293a6401a6f2c
diff --git a/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml b/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
index bd2c71c..ff89bbc 100644
--- a/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
+++ b/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
@@ -21,7 +21,15 @@
     <uses-permission android:name="com.android.systemui.permission.PLUGIN" />
 
     <application>
-        <service android:name=".SampleOverlayPlugin">
+        <activity android:name=".PluginSettings"
+            android:label="@string/plugin_label">
+            <intent-filter>
+                <action android:name="com.android.systemui.action.PLUGIN_SETTINGS" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".SampleOverlayPlugin"
+            android:label="@string/plugin_label">
             <intent-filter>
                 <action android:name="com.android.systemui.action.PLUGIN_OVERLAY" />
             </intent-filter>
diff --git a/packages/SystemUI/plugin/ExamplePlugin/res/layout/plugin_settings.xml b/packages/SystemUI/plugin/ExamplePlugin/res/layout/plugin_settings.xml
new file mode 100644
index 0000000..eb90283
--- /dev/null
+++ b/packages/SystemUI/plugin/ExamplePlugin/res/layout/plugin_settings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:textAppearance="?android:attr/textAppearanceLarge"
+    android:text="@string/plugin_settings_here"
+    android:gravity="center" />
diff --git a/packages/SystemUI/plugin/ExamplePlugin/res/values/strings.xml b/packages/SystemUI/plugin/ExamplePlugin/res/values/strings.xml
new file mode 100644
index 0000000..a0bfe84
--- /dev/null
+++ b/packages/SystemUI/plugin/ExamplePlugin/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <string name="plugin_settings_here" translatable="false">Plugin settings go here</string>
+    <string name="plugin_label" translatable="false">Overlay Plugin</string>
+
+</resources>
diff --git a/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java b/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java
new file mode 100644
index 0000000..cf39075
--- /dev/null
+++ b/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java
@@ -0,0 +1,32 @@
+/*
+ * 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.plugin.testoverlayplugin;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * DO NOT Reference Plugin interfaces here, this runs in the plugin APK's process
+ * and is only for modifying settings.
+ */
+public class PluginSettings extends Activity {
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.plugin_settings);
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
index 2a7139c..495771a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -163,6 +162,7 @@
             switch (msg.what) {
                 case PLUGIN_CONNECTED:
                     if (DEBUG) Log.d(TAG, "onPluginConnected");
+                    PluginPrefs.setHasPlugins(mContext);
                     PluginInfo<T> info = (PluginInfo<T>) msg.obj;
                     info.mPlugin.onCreate(mContext, info.mPluginContext);
                     mListener.onPluginConnected(info.mPlugin);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
index aa0b3c5..4bf6494 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
@@ -37,6 +37,7 @@
     private final Context mContext;
     private final PluginInstanceManagerFactory mFactory;
     private final boolean isDebuggable;
+    private final PluginPrefs mPluginPrefs;
 
     private PluginManager(Context context) {
         this(context, new PluginInstanceManagerFactory(), Build.IS_DEBUGGABLE,
@@ -51,6 +52,7 @@
         mBackgroundThread = new HandlerThread("Plugins");
         mBackgroundThread.start();
         isDebuggable = debuggable;
+        mPluginPrefs = new PluginPrefs(mContext);
 
         PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler(
                 defaultHandler);
@@ -68,6 +70,7 @@
             // Never ever ever allow these on production builds, they are only for prototyping.
             return;
         }
+        mPluginPrefs.addAction(action);
         PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener,
                 allowMultiple, mBackgroundThread.getLooper(), version);
         p.startListening();
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginPrefs.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginPrefs.java
new file mode 100644
index 0000000..3671b3c
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginPrefs.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+import android.content.SharedPreferences;
+import android.util.ArraySet;
+
+import java.util.Set;
+
+/**
+ * Storage for all plugin actions in SharedPreferences.
+ *
+ * This allows the list of actions that the Tuner needs to search for to be generated
+ * instead of hard coded.
+ */
+public class PluginPrefs {
+
+    private static final String PREFS = "plugin_prefs";
+
+    private static final String PLUGIN_ACTIONS = "actions";
+    private static final String HAS_PLUGINS = "plugins";
+
+    private final Set<String> mPluginActions;
+    private final SharedPreferences mSharedPrefs;
+
+    public PluginPrefs(Context context) {
+        mSharedPrefs = context.getSharedPreferences(PREFS, 0);
+        mPluginActions = new ArraySet<>(mSharedPrefs.getStringSet(PLUGIN_ACTIONS, null));
+    }
+
+    public Set<String> getPluginList() {
+        return mPluginActions;
+    }
+
+    public synchronized void addAction(String action) {
+        if (mPluginActions.add(action)){
+            mSharedPrefs.edit().putStringSet(PLUGIN_ACTIONS, mPluginActions).commit();
+        }
+    }
+
+    public static boolean hasPlugins(Context context) {
+        return context.getSharedPreferences(PREFS, 0).getBoolean(HAS_PLUGINS, false);
+    }
+
+    public static void setHasPlugins(Context context) {
+        context.getSharedPreferences(PREFS, 0).edit().putBoolean(HAS_PLUGINS, true).commit();
+    }
+}