summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {