summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jason Monk <jmonk@google.com> 2016-08-23 14:41:05 -0400
committer Jason Monk <jmonk@google.com> 2016-09-27 12:41:34 -0400
commitef0d34d32e9872e36d321e921d7da91f35be032d (patch)
treedad78d7c9cac83f9745f2042c5583baff338a5ba
parent46767b77c004a3541c614f8e21d6a871dd148e54 (diff)
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
-rw-r--r--packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml10
-rw-r--r--packages/SystemUI/plugin/ExamplePlugin/res/layout/plugin_settings.xml24
-rw-r--r--packages/SystemUI/plugin/ExamplePlugin/res/values/strings.xml24
-rw-r--r--packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java32
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java2
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java3
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginPrefs.java61
-rw-r--r--packages/SystemUI/res/layout/tuner_widget_settings_switch.xml47
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/res/xml/tuner_prefs.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java111
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java12
12 files changed, 326 insertions, 9 deletions
diff --git a/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml b/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
index bd2c71c38f5a..ff89bbcb455f 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 000000000000..eb90283f08d0
--- /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 000000000000..a0bfe849e5c6
--- /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 000000000000..cf39075d958f
--- /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 2a7139c3a74c..495771a3c8ec 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.ApplicationInfo;
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 @@ public class PluginInstanceManager<T extends Plugin> extends BroadcastReceiver {
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 aa0b3c586747..4bf6494995bc 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 @@ public class PluginManager {
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 @@ public class PluginManager {
mBackgroundThread = new HandlerThread("Plugins");
mBackgroundThread.start();
isDebuggable = debuggable;
+ mPluginPrefs = new PluginPrefs(mContext);
PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler(
defaultHandler);
@@ -68,6 +70,7 @@ public class PluginManager {
// 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 000000000000..3671b3c1689f
--- /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();
+ }
+}
diff --git a/packages/SystemUI/res/layout/tuner_widget_settings_switch.xml b/packages/SystemUI/res/layout/tuner_widget_settings_switch.xml
new file mode 100644
index 000000000000..c89c02fd9171
--- /dev/null
+++ b/packages/SystemUI/res/layout/tuner_widget_settings_switch.xml
@@ -0,0 +1,47 @@
+<?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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+
+ <ImageView
+ android:id="@+id/settings"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_settings"
+ android:tint="@android:color/black"
+ android:padding="12dp"
+ android:background="?android:attr/selectableItemBackgroundBorderless" />
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="1dp"
+ android:layout_height="30dp"
+ android:layout_marginEnd="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <Switch
+ android:id="@android:id/switch_widget"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:clickable="false"
+ android:background="@null" />
+</LinearLayout>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 562fb7f62b83..3f485c3bad8b 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1667,4 +1667,8 @@
<!-- accessibility label for paging indicator in quick settings [CHAR LIMITi=NONE] -->
<string name="accessibility_quick_settings_page">Page <xliff:g name="current_page" example="1">%1$d</xliff:g> of <xliff:g name="num_pages" example="2">%2$d</xliff:g></string>
+ <!-- Plugin control section of the tuner. Non-translatable since it should
+ not appear on production builds ever. -->
+ <string name="plugins" translatable="false">Plugins</string>
+
</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index b46e862471f3..211f8e8183e8 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -133,6 +133,11 @@
android:title="@string/other"
android:fragment="com.android.systemui.tuner.OtherPrefs" />
+ <Preference
+ android:key="plugins"
+ android:title="@string/plugins"
+ android:fragment="com.android.systemui.tuner.PluginFragment" />
+
<!-- Warning, this goes last. -->
<Preference
android:summary="@string/tuner_persistent_warning"
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
new file mode 100644
index 000000000000..132a6dd6c747
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
@@ -0,0 +1,111 @@
+/*
+ * 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.tuner;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.View;
+
+import com.android.systemui.plugins.PluginPrefs;
+import com.android.systemui.R;
+
+import java.util.List;
+import java.util.Set;
+
+public class PluginFragment extends PreferenceFragment {
+
+ public static final String ACTION_PLUGIN_SETTINGS
+ = "com.android.systemui.action.PLUGIN_SETTINGS";
+
+ private PluginPrefs mPluginPrefs;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getContext());
+ screen.setOrderingAsAdded(false);
+ Context prefContext = getPreferenceManager().getContext();
+ mPluginPrefs = new PluginPrefs(getContext());
+ Set<String> pluginActions = mPluginPrefs.getPluginList();
+ for (String action : pluginActions) {
+ String name = action.replace("com.android.systemui.action.PLUGIN_", "");
+ PreferenceCategory category = new PreferenceCategory(prefContext);
+ category.setTitle(name);
+
+ List<ResolveInfo> result = getContext().getPackageManager().queryIntentServices(
+ new Intent(action), PackageManager.MATCH_DISABLED_COMPONENTS);
+ if (result.size() > 0) {
+ screen.addPreference(category);
+ }
+ for (ResolveInfo info : result) {
+ category.addPreference(new PluginPreference(prefContext, info));
+ }
+ }
+ setPreferenceScreen(screen);
+ }
+
+ private static class PluginPreference extends SwitchPreference {
+ private final ComponentName mComponent;
+ private final boolean mHasSettings;
+
+ public PluginPreference(Context prefContext, ResolveInfo info) {
+ super(prefContext);
+ mComponent = new ComponentName(info.serviceInfo.packageName, info.serviceInfo.name);
+ PackageManager pm = prefContext.getPackageManager();
+ mHasSettings = pm.resolveActivity(new Intent(ACTION_PLUGIN_SETTINGS)
+ .setPackage(mComponent.getPackageName()), 0) != null;
+ setTitle(info.serviceInfo.loadLabel(pm));
+ setChecked(pm.getComponentEnabledSetting(mComponent)
+ != PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
+ setWidgetLayoutResource(R.layout.tuner_widget_settings_switch);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ getContext().getPackageManager().setComponentEnabledSetting(mComponent,
+ value ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ return true;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ holder.findViewById(R.id.settings).setVisibility(mHasSettings ? View.VISIBLE
+ : View.GONE);
+ holder.findViewById(R.id.divider).setVisibility(mHasSettings ? View.VISIBLE
+ : View.GONE);
+ holder.findViewById(R.id.settings).setOnClickListener(v -> {
+ ResolveInfo result = v.getContext().getPackageManager().resolveActivity(
+ new Intent(ACTION_PLUGIN_SETTINGS).setPackage(
+ mComponent.getPackageName()), 0);
+ if (result != null) {
+ v.getContext().startActivity(new Intent().setComponent(
+ new ComponentName(result.activityInfo.packageName,
+ result.activityInfo.name)));
+ }
+ });
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 70f2fdcfa8d3..7f63418de324 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -19,16 +19,9 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
-import android.database.ContentObserver;
-import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.provider.Settings;
-import android.provider.Settings.System;
import android.support.v14.preference.PreferenceFragment;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -36,12 +29,14 @@ import android.view.MenuItem;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
+import com.android.systemui.plugins.PluginPrefs;
public class TunerFragment extends PreferenceFragment {
private static final String TAG = "TunerFragment";
private static final String KEY_BATTERY_PCT = "battery_pct";
+ private static final String KEY_PLUGINS = "plugins";
public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning";
@@ -65,6 +60,9 @@ public class TunerFragment extends PreferenceFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.tuner_prefs);
+ if (!PluginPrefs.hasPlugins(getContext())) {
+ getPreferenceScreen().removePreference(findPreference(KEY_PLUGINS));
+ }
if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
0) == 0) {