Tuner updates
Some UX updates to the tuner to feel better and align with settings
UX patterns.
Test: visual
Change-Id: I9c57194b9649c61e0d6d3f9e21a51d9c4a5c1286
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 11e2a71..8653523 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -215,6 +215,13 @@
return colorAccent;
}
+ public static Drawable getDrawable(Context context, int attr) {
+ TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+ Drawable drawable = ta.getDrawable(0);
+ ta.recycle();
+ return drawable;
+ }
+
/**
* Determine whether a package is a "system package", in which case certain things (like
* disabling notifications or disabling the package altogether) should be disallowed.
diff --git a/packages/SystemUI/res/drawable/ic_remove_circle.xml b/packages/SystemUI/res/drawable/ic_remove_circle.xml
new file mode 100644
index 0000000..439cc78
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_remove_circle.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:tint="#db4437"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <path android:fillColor="@android:color/white"
+ android:pathData="M24,4C12.95,4,4,12.95,4,24
+ s8.95,20,20,20,20-8.95,20-20
+ S35.05,4,24,4zm10,22H14v-4h20v4z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/preference_widget_radiobutton.xml b/packages/SystemUI/res/layout/preference_widget_radiobutton.xml
new file mode 100644
index 0000000..b3ec43d
--- /dev/null
+++ b/packages/SystemUI/res/layout/preference_widget_radiobutton.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- Layout used by CheckBoxPreference for the checkbox style. This is inflated
+ inside android.R.layout.preference. -->
+<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:focusable="false"
+ android:clickable="false" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 67def4f..77de9a2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1527,14 +1527,12 @@
<!-- SysUI Tuner: Button that controls layout of navigation bar [CHAR LIMIT=60] -->
<string name="nav_bar_layout">Layout</string>
- <!-- SysUI Tuner: Label for section of settings about the left nav button [CHAR LIMIT=60] -->
- <string name="nav_bar_left">Left</string>
-
- <!-- SysUI Tuner: Label for section of settings about the right nav button [CHAR LIMIT=60] -->
- <string name="nav_bar_right">Right</string>
+ <!-- SysUI Tuner: Setting for button type in nav bar [CHAR LIMIT=60] -->
+ <string name="left_nav_bar_button_type">Extra left button type</string>
<!-- SysUI Tuner: Setting for button type in nav bar [CHAR LIMIT=60] -->
- <string name="nav_bar_button_type">Button type</string>
+ <string name="right_nav_bar_button_type">Extra right button type</string>
+
<!-- SysUI Tuner: Added to nav bar option to indicate it is the default [CHAR LIMIT=60] -->
<string name="nav_bar_default"> (default)</string>
@@ -1543,7 +1541,7 @@
<string-array name="nav_bar_buttons">
<item>Clipboard</item>
<item>Keycode</item>
- <item>Menu / Keyboard Switcher</item>
+ <item>Keyboard switcher</item>
<item>None</item>
</string-array>
<string-array name="nav_bar_button_values" translatable="false">
@@ -1555,10 +1553,10 @@
<!-- SysUI Tuner: Labels for different types of navigation bar layouts [CHAR LIMIT=60] -->
<string-array name="nav_bar_layouts">
- <item>Divided (default)</item>
- <item>Centered</item>
- <item>Left-aligned</item>
- <item>Right-aligned</item>
+ <item>Normal</item>
+ <item>Compact</item>
+ <item>Left-leaning</item>
+ <item>Right-leaning</item>
</string-array>
<string-array name="nav_bar_layouts_values" translatable="false">
@@ -1569,7 +1567,7 @@
</string-array>
<!-- SysUI Tuner: Name of Combination Menu / Keyboard Switcher button [CHAR LIMIT=30] -->
- <string name="menu_ime">Menu / Keyboard Switcher</string>
+ <string name="menu_ime">Keyboard switcher</string>
<!-- SysUI Tuner: Save the current settings [CHAR LIMIT=30] -->
<string name="save">Save</string>
<!-- SysUI Tuner: Reset to default settings [CHAR LIMIT=30] -->
@@ -1585,10 +1583,16 @@
<string name="accessibility_key">Custom navigation button</string>
<!-- SysUI Tuner: Nav bar button that emulates a keycode [CHAR LIMIT=30] -->
- <string name="keycode">Keycode</string>
+ <string name="left_keycode">Left keycode</string>
+
+ <!-- SysUI Tuner: Nav bar button that emulates a keycode [CHAR LIMIT=30] -->
+ <string name="right_keycode">Right keycode</string>
<!-- SysUI Tuner: Settings to change nav bar icon [CHAR LIMIT=30] -->
- <string name="icon">Icon</string>
+ <string name="left_icon">Left icon</string>
+
+ <!-- SysUI Tuner: Settings to change nav bar icon [CHAR LIMIT=30] -->
+ <string name="right_icon">Right icon</string>
<!-- Label for area where tiles can be dragged out of [CHAR LIMIT=60] -->
<string name="drag_to_add_tiles">Drag to add tiles</string>
@@ -1725,6 +1729,9 @@
not appear on production builds ever. -->
<string name="tuner_doze_always_on" translatable="false">Always on</string>
+ <!-- SysUI Tuner: Section to customize lockscreen shortcuts [CHAR LIMIT=60] -->
+ <string name="tuner_lock_screen">Lock screen</string>
+
<!-- Making the PIP fullscreen [CHAR LIMIT=25] -->
<string name="pip_phone_expand">Expand</string>
@@ -1760,20 +1767,47 @@
<!-- Text body for dialog alerting user that their phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=300] -->
<string name="high_temp_dialog_message">Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally.</string>
- <!-- SysUI Tuner: Group of settings for left lock screen affordance [CHAR LIMIT=60] -->
- <string name="lockscreen_left">Left</string>
-
- <!-- SysUI Tuner: Group of settings for right lock screen affordance [CHAR LIMIT=60] -->
- <string name="lockscreen_right">Right</string>
-
- <!-- SysUI Tuner: Switch controlling whether to customize lock screen button [CHAR LIMIT=60] -->
- <string name="lockscreen_customize">Customize shortcut</string>
+ <!-- SysUI Tuner: Button to select lock screen shortcut [CHAR LIMIT=60] -->
+ <string name="lockscreen_shortcut_left">Left shortcut</string>
<!-- SysUI Tuner: Button to select lock screen shortcut [CHAR LIMIT=60] -->
- <string name="lockscreen_shortcut">Shortcut</string>
+ <string name="lockscreen_shortcut_right">Right shortcut</string>
- <!-- SysUI Tuner: Switch to control if device gets unlocked [CHAR LIMIT=60] -->
- <string name="lockscreen_unlock">Prompt for password</string>
+ <!-- SysUI Tuner: Switch to control if device gets unlocked by left shortcut [CHAR LIMIT=60] -->
+ <string name="lockscreen_unlock_left">Left shortcut also unlocks</string>
+
+ <!-- SysUI Tuner: Switch to control if device gets unlocked by right shortcut [CHAR LIMIT=60] -->
+ <string name="lockscreen_unlock_right">Right shortcut also unlocks</string>
+
+ <!-- SysUI Tuner: Summary of no shortcut being selected [CHAR LIMIT=60] -->
+ <string name="lockscreen_none">None</string>
+
+ <!-- SysUI Tuner: Format string for describing launching an app [CHAR LIMIT=60] -->
+ <string name="tuner_launch_app">Launch <xliff:g id="app" example="Settings">%1$s</xliff:g></string>
+
+ <!-- SysUI Tuner: Label for section of other apps that can be launched [CHAR LIMIT=60] -->
+ <string name="tuner_other_apps">Other apps</string>
+
+ <!-- SysUI Tuner: Label for icon shaped like a circle [CHAR LIMIT=60] -->
+ <string name="tuner_circle">Circle</string>
+
+ <!-- SysUI Tuner: Label for icon shaped like a plus [CHAR LIMIT=60] -->
+ <string name="tuner_plus">Plus</string>
+
+ <!-- SysUI Tuner: Label for icon shaped like a minus [CHAR LIMIT=60] -->
+ <string name="tuner_minus">Minus</string>
+
+ <!-- SysUI Tuner: Label for icon shaped like a left [CHAR LIMIT=60] -->
+ <string name="tuner_left">Left</string>
+
+ <!-- SysUI Tuner: Label for icon shaped like a right [CHAR LIMIT=60] -->
+ <string name="tuner_right">Right</string>
+
+ <!-- SysUI Tuner: Label for icon shaped like a menu [CHAR LIMIT=60] -->
+ <string name="tuner_menu">Menu</string>
+
+ <!-- SysUI Tuner: App subheading for shortcut selection [CHAR LIMIT=60] -->
+ <string name="tuner_app"><xliff:g id="app">%1$s</xliff:g> app</string>
<!-- Title for the notification channel containing important alerts like low battery. [CHAR LIMIT=NONE] -->
<string name="notification_channel_alerts">Alerts</string>
diff --git a/packages/SystemUI/res/xml/lockscreen_settings.xml b/packages/SystemUI/res/xml/lockscreen_settings.xml
index 73e29af..1e7d266 100644
--- a/packages/SystemUI/res/xml/lockscreen_settings.xml
+++ b/packages/SystemUI/res/xml/lockscreen_settings.xml
@@ -18,42 +18,25 @@
xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:title="@string/other">
- <PreferenceCategory
- android:key="left"
- android:title="@string/lockscreen_left">
- <SwitchPreference
- android:key="customize"
- android:title="@string/lockscreen_customize" />
+ <Preference
+ android:key="sysui_keyguard_left"
+ android:title="@string/lockscreen_shortcut_left"
+ android:fragment="com.android.systemui.tuner.ShortcutPicker" />
- <Preference
- android:key="shortcut"
- android:title="@string/lockscreen_shortcut" />
+ <com.android.systemui.tuner.TunerSwitch
+ android:key="sysui_keyguard_left_unlock"
+ android:title="@string/lockscreen_unlock_left"
+ sysui:defValue="true" />
- <com.android.systemui.tuner.TunerSwitch
- android:key="sysui_keyguard_left_unlock"
- android:title="@string/lockscreen_unlock"
- sysui:defValue="true" />
+ <Preference
+ android:key="sysui_keyguard_right"
+ android:title="@string/lockscreen_shortcut_right"
+ android:fragment="com.android.systemui.tuner.ShortcutPicker" />
- </PreferenceCategory>
-
- <PreferenceCategory
- android:key="right"
- android:title="@string/lockscreen_right">
-
- <SwitchPreference
- android:key="customize"
- android:title="@string/lockscreen_customize" />
-
- <Preference
- android:key="shortcut"
- android:title="@string/lockscreen_shortcut" />
-
- <com.android.systemui.tuner.TunerSwitch
- android:key="sysui_keyguard_right_unlock"
- android:title="@string/lockscreen_unlock"
- sysui:defValue="true" />
-
- </PreferenceCategory>
+ <com.android.systemui.tuner.TunerSwitch
+ android:key="sysui_keyguard_right_unlock"
+ android:title="@string/lockscreen_unlock_right"
+ sysui:defValue="true" />
</PreferenceScreen>
diff --git a/packages/SystemUI/res/xml/nav_bar_tuner.xml b/packages/SystemUI/res/xml/nav_bar_tuner.xml
index 6fa8bec..68e8fad 100644
--- a/packages/SystemUI/res/xml/nav_bar_tuner.xml
+++ b/packages/SystemUI/res/xml/nav_bar_tuner.xml
@@ -18,7 +18,7 @@
xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:title="@string/nav_bar">
- <ListPreference
+ <com.android.systemui.tuner.RadioListPreference
android:key="layout"
android:title="@string/nav_bar_layout"
android:summary="%s"
@@ -26,54 +26,42 @@
android:entries="@array/nav_bar_layouts"
android:entryValues="@array/nav_bar_layouts_values" />
- <PreferenceCategory
- android:key="left"
- android:title="@string/nav_bar_left">
+ <com.android.systemui.tuner.RadioListPreference
+ android:key="type_left"
+ android:title="@string/left_nav_bar_button_type"
+ android:persistent="false"
+ android:summary="%s"
+ android:entries="@array/nav_bar_buttons"
+ android:entryValues="@array/nav_bar_button_values" />
- <DropDownPreference
- android:key="type_left"
- android:title="@string/nav_bar_button_type"
- android:persistent="false"
- android:summary="%s"
- android:entries="@array/nav_bar_buttons"
- android:entryValues="@array/nav_bar_button_values" />
+ <Preference
+ android:key="keycode_left"
+ android:persistent="false"
+ android:title="@string/left_keycode" />
- <Preference
- android:key="keycode_left"
- android:persistent="false"
- android:title="@string/keycode" />
+ <com.android.systemui.tuner.RadioListPreference
+ android:key="icon_left"
+ android:persistent="false"
+ android:summary="%s"
+ android:title="@string/left_icon" />
- <com.android.systemui.tuner.BetterListPreference
- android:key="icon_left"
- android:persistent="false"
- android:summary="%s"
- android:title="@string/icon" />
+ <com.android.systemui.tuner.RadioListPreference
+ android:key="type_right"
+ android:title="@string/right_nav_bar_button_type"
+ android:summary="%s"
+ android:persistent="false"
+ android:entries="@array/nav_bar_buttons"
+ android:entryValues="@array/nav_bar_button_values" />
- </PreferenceCategory>
+ <Preference
+ android:key="keycode_right"
+ android:persistent="false"
+ android:title="@string/right_keycode" />
- <PreferenceCategory
- android:key="right"
- android:title="@string/nav_bar_right">
-
- <DropDownPreference
- android:key="type_right"
- android:title="@string/nav_bar_button_type"
- android:summary="%s"
- android:persistent="false"
- android:entries="@array/nav_bar_buttons"
- android:entryValues="@array/nav_bar_button_values" />
-
- <Preference
- android:key="keycode_right"
- android:persistent="false"
- android:title="@string/keycode" />
-
- <com.android.systemui.tuner.BetterListPreference
- android:key="icon_right"
- android:persistent="false"
- android:summary="%s"
- android:title="@string/icon" />
-
- </PreferenceCategory>
+ <com.android.systemui.tuner.RadioListPreference
+ android:key="icon_right"
+ android:persistent="false"
+ android:summary="%s"
+ android:title="@string/right_icon" />
</PreferenceScreen>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 6198ab7..c354811 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -121,6 +121,7 @@
</PreferenceScreen>
+ <!--
<PreferenceScreen
android:key="picture_in_picture"
android:title="@string/picture_in_picture">
@@ -143,6 +144,7 @@
sysui:defValue="false" />
</PreferenceScreen>
+ -->
<Preference
android:key="nav_bar"
@@ -151,15 +153,10 @@
<Preference
android:key="lockscreen"
- android:title="@string/accessibility_desc_lock_screen"
+ android:title="@string/tuner_lock_screen"
android:fragment="com.android.systemui.tuner.LockscreenFragment" />
<Preference
- android:key="other"
- 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" />
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 273b5e3..f1e7d53 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -25,6 +25,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
@@ -74,6 +76,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
+import java.util.function.Consumer;
/**
* Class to handle ugly dependencies throughout sysui until we determine the
@@ -227,6 +230,9 @@
mProviders.put(StatusBarIconController.class, () ->
new StatusBarIconControllerImpl(mContext));
+ mProviders.put(FragmentService.class, () ->
+ new FragmentService(mContext));
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
@@ -282,17 +288,42 @@
T createDependency();
}
+ private <T> void destroyDependency(Class<T> cls, Consumer<T> destroy) {
+ T dep = (T) mDependencies.remove(cls);
+ if (dep != null && destroy != null) {
+ destroy.accept(dep);
+ }
+ }
+
/**
* Used in separate processes (like tuner settings) to init the dependencies.
*/
public static void initDependencies(Context context) {
if (sDependency != null) return;
Dependency d = new Dependency();
- d.mContext = context.getApplicationContext();
+ d.mContext = context;
d.mComponents = new HashMap<>();
d.start();
}
+ /**
+ * Used in separate process teardown to ensure the context isn't leaked.
+ *
+ * TODO: Remove once PreferenceFragment doesn't reference getActivity()
+ * anymore and these context hacks are no longer needed.
+ */
+ public static void clearDependencies() {
+ sDependency = null;
+ }
+
+ /**
+ * Checks to see if a dependency is instantiated, if it is it removes it from
+ * the cache and calls the destroy callback.
+ */
+ public static <T> void destroy(Class<T> cls, Consumer<T> destroy) {
+ sDependency.destroyDependency(cls, destroy);
+ }
+
public static <T> T get(Class<T> cls) {
return sDependency.getDependency(cls);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 187b557..6caee5f 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -67,7 +67,6 @@
*/
private final Class<?>[] SERVICES = new Class[] {
Dependency.class,
- FragmentService.class,
NotificationChannels.class,
CommandQueue.CommandQueueStart.class,
KeyguardViewMediator.class,
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 0c6bf52..57c75bf 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -32,6 +32,7 @@
import android.view.View;
import com.android.settingslib.applications.InterestingConfigChanges;
+import com.android.systemui.Dependency;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginManager;
@@ -171,6 +172,10 @@
return mPlugins;
}
+ void destroy() {
+ mFragments.dispatchDestroy();
+ }
+
public interface FragmentListener {
void onFragmentViewCreated(String tag, Fragment fragment);
@@ -182,8 +187,7 @@
public static FragmentHostManager get(View view) {
try {
- return ((SystemUIApplication) view.getContext().getApplicationContext())
- .getComponent(FragmentService.class).getFragmentHostManager(view);
+ return Dependency.get(FragmentService.class).getFragmentHostManager(view);
} catch (ClassCastException e) {
// TODO: Some auto handling here?
throw e;
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
index 85cde10..9a8512d 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
@@ -14,6 +14,7 @@
package com.android.systemui.fragments;
+import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
@@ -21,6 +22,7 @@
import android.util.Log;
import android.view.View;
+import com.android.systemui.ConfigurationChangedReceiver;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIApplication;
@@ -28,16 +30,16 @@
* Holds a map of root views to FragmentHostStates and generates them as needed.
* Also dispatches the configuration changes to all current FragmentHostStates.
*/
-public class FragmentService extends SystemUI {
+public class FragmentService implements ConfigurationChangedReceiver {
private static final String TAG = "FragmentService";
private final ArrayMap<View, FragmentHostState> mHosts = new ArrayMap<>();
private final Handler mHandler = new Handler();
+ private final Context mContext;
- @Override
- public void start() {
- putComponent(FragmentService.class, this);
+ public FragmentService(Context context) {
+ mContext = context;
}
public FragmentHostManager getFragmentHostManager(View view) {
@@ -50,8 +52,14 @@
return state.getFragmentHostManager();
}
+ public void destroyAll() {
+ for (FragmentHostState state : mHosts.values()) {
+ state.mFragmentHostManager.destroy();
+ }
+ }
+
@Override
- protected void onConfigurationChanged(Configuration newConfig) {
+ public void onConfigurationChanged(Configuration newConfig) {
for (FragmentHostState state : mHosts.values()) {
state.sendConfigurationChange(newConfig);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index f2c3e61..4e30797 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -301,6 +301,7 @@
if (position == mEditIndex) position--;
move(mAccessibilityFromIndex, position, v);
+
notifyDataSetChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java
new file mode 100644
index 0000000..e50fd5e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java
@@ -0,0 +1,173 @@
+/*
+ * 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.tuner;
+
+import android.annotation.Nullable;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.support.v14.preference.ListPreferenceDialogFragment;
+import android.support.v7.preference.ListPreference;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class CustomListPreference extends ListPreference {
+
+ public CustomListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+ OnClickListener listener) {
+ }
+
+ protected void onDialogClosed(boolean positiveResult) {
+ }
+
+ protected Dialog onDialogCreated(DialogFragment fragment, Dialog dialog) {
+ return dialog;
+ }
+
+ protected boolean isAutoClosePreference() {
+ return true;
+ }
+
+ /**
+ * Called when a user is about to choose the given value, to determine if we
+ * should show a confirmation dialog.
+ *
+ * @param value the value the user is about to choose
+ * @return the message to show in a confirmation dialog, or {@code null} to
+ * not request confirmation
+ */
+ protected CharSequence getConfirmationMessage(String value) {
+ return null;
+ }
+
+ protected void onDialogStateRestored(DialogFragment fragment, Dialog dialog,
+ Bundle savedInstanceState) {
+ }
+
+ public static class CustomListPreferenceDialogFragment extends ListPreferenceDialogFragment {
+
+ private static final String KEY_CLICKED_ENTRY_INDEX
+ = "settings.CustomListPrefDialog.KEY_CLICKED_ENTRY_INDEX";
+
+ private int mClickedDialogEntryIndex;
+
+ public static ListPreferenceDialogFragment newInstance(String key) {
+ final ListPreferenceDialogFragment fragment = new CustomListPreferenceDialogFragment();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ public CustomListPreference getCustomizablePreference() {
+ return (CustomListPreference) getPreference();
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ super.onPrepareDialogBuilder(builder);
+ mClickedDialogEntryIndex = getCustomizablePreference()
+ .findIndexOfValue(getCustomizablePreference().getValue());
+ getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener());
+ if (!getCustomizablePreference().isAutoClosePreference()) {
+ builder.setPositiveButton(com.android.internal.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onItemConfirmed();
+ }
+ });
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
+ if (savedInstanceState != null) {
+ mClickedDialogEntryIndex = savedInstanceState.getInt(KEY_CLICKED_ENTRY_INDEX,
+ mClickedDialogEntryIndex);
+ }
+ return getCustomizablePreference().onDialogCreated(this, dialog);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(KEY_CLICKED_ENTRY_INDEX, mClickedDialogEntryIndex);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ getCustomizablePreference().onDialogStateRestored(this, getDialog(), savedInstanceState);
+ }
+
+ protected OnClickListener getOnItemClickListener() {
+ return new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ setClickedDialogEntryIndex(which);
+ if (getCustomizablePreference().isAutoClosePreference()) {
+ onItemConfirmed();
+ }
+ }
+ };
+ }
+
+ protected void setClickedDialogEntryIndex(int which) {
+ mClickedDialogEntryIndex = which;
+ }
+
+ private String getValue() {
+ final ListPreference preference = getCustomizablePreference();
+ if (mClickedDialogEntryIndex >= 0 && preference.getEntryValues() != null) {
+ return preference.getEntryValues()[mClickedDialogEntryIndex].toString();
+ } else {
+ return null;
+ }
+ }
+
+ protected void onItemConfirmed() {
+ onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
+ getDialog().dismiss();
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+ getCustomizablePreference().onDialogClosed(positiveResult);
+ final ListPreference preference = getCustomizablePreference();
+ final String value = getValue();
+ if (positiveResult && value != null) {
+ if (preference.callChangeListener(value)) {
+ preference.setValue(value);
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
index 6f4a3a4..410d3d2 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
@@ -80,10 +80,8 @@
mTunerService = Dependency.get(TunerService.class);
mHandler = new Handler();
addPreferencesFromResource(R.xml.lockscreen_settings);
- setupGroup((PreferenceGroup) findPreference(KEY_LEFT), LOCKSCREEN_LEFT_BUTTON,
- LOCKSCREEN_LEFT_UNLOCK);
- setupGroup((PreferenceGroup) findPreference(KEY_RIGHT), LOCKSCREEN_RIGHT_BUTTON,
- LOCKSCREEN_RIGHT_UNLOCK);
+ setupGroup(LOCKSCREEN_LEFT_BUTTON, LOCKSCREEN_LEFT_UNLOCK);
+ setupGroup(LOCKSCREEN_RIGHT_BUTTON, LOCKSCREEN_RIGHT_UNLOCK);
}
@Override
@@ -92,30 +90,14 @@
mTunables.forEach(t -> mTunerService.removeTunable(t));
}
- private void setupGroup(PreferenceGroup group, String buttonSetting, String unlockKey) {
- SwitchPreference customize = (SwitchPreference) group.findPreference(KEY_CUSTOMIZE);
- Preference shortcut = group.findPreference(KEY_SHORTCUT);
- SwitchPreference unlock = (SwitchPreference) group.findPreference(unlockKey);
+ private void setupGroup(String buttonSetting, String unlockKey) {
+ Preference shortcut = findPreference(buttonSetting);
+ SwitchPreference unlock = (SwitchPreference) findPreference(unlockKey);
addTunable((k, v) -> {
- boolean visible = v != null;
- customize.setChecked(visible);
- shortcut.setVisible(visible);
+ boolean visible = !TextUtils.isEmpty(v);
unlock.setVisible(visible);
- if (visible) {
- setSummary(shortcut, v);
- }
+ setSummary(shortcut, v);
}, buttonSetting);
- customize.setOnPreferenceChangeListener((preference, newValue) -> {
- boolean hasSetting = mTunerService.getValue(buttonSetting) != null;
- if (hasSetting != (boolean) newValue) {
- mHandler.post(() -> mTunerService.setValue(buttonSetting, hasSetting ? null : ""));
- }
- return true;
- });
- shortcut.setOnPreferenceClickListener(preference -> {
- showSelectDialog(buttonSetting);
- return true;
- });
}
private void showSelectDialog(String buttonSetting) {
@@ -129,24 +111,15 @@
mTunerService.setValue(buttonSetting, item.getSettingValue());
dialog.dismiss();
});
- LauncherApps apps = getContext().getSystemService(LauncherApps.class);
- List<LauncherActivityInfo> activities = apps.getActivityList(null,
- Process.myUserHandle());
-
- activities.forEach(info -> {
- App app = new App(getContext(), info);
- try {
- new ShortcutParser(getContext(), info.getComponentName()).getShortcuts().forEach(
- shortcut -> app.addChild(new StaticShortcut(getContext(), shortcut)));
- } catch (NameNotFoundException e) {
- }
- adapter.addItem(app);
- });
v.setAdapter(adapter);
}
private void setSummary(Preference shortcut, String value) {
+ if (value == null) {
+ shortcut.setSummary(R.string.lockscreen_none);
+ return;
+ }
if (value.contains("::")) {
Shortcut info = getShortcutInfo(getContext(), value);
shortcut.setSummary(info != null ? info.label : null);
@@ -155,7 +128,7 @@
shortcut.setSummary(info != null ? info.loadLabel(getContext().getPackageManager())
: null);
} else {
- shortcut.setSummary(null);
+ shortcut.setSummary(R.string.lockscreen_none);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index 28a0057..45abd45 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -33,6 +33,9 @@
import android.content.DialogInterface.OnClickListener;
import android.content.res.Resources;
import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetricsInt;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -58,7 +61,7 @@
import java.util.ArrayList;
-public class NavBarTuner extends PreferenceFragment {
+public class NavBarTuner extends TunerPreferenceFragment {
private static final String LAYOUT = "layout";
private static final String LEFT = "left";
@@ -68,13 +71,13 @@
private static final String KEYCODE = "keycode";
private static final String ICON = "icon";
- private static final int[] ICONS = new int[]{
- R.drawable.ic_qs_circle,
- R.drawable.ic_add,
- R.drawable.ic_remove,
- R.drawable.ic_left,
- R.drawable.ic_right,
- R.drawable.ic_menu,
+ private static final int[][] ICONS = new int[][]{
+ {R.drawable.ic_qs_circle, R.string.tuner_circle},
+ {R.drawable.ic_add, R.string.tuner_plus},
+ {R.drawable.ic_remove, R.string.tuner_minus},
+ {R.drawable.ic_left, R.string.tuner_left},
+ {R.drawable.ic_right, R.string.tuner_right},
+ {R.drawable.ic_menu, R.string.tuner_menu},
};
private final ArrayList<Tunable> mTunables = new ArrayList<>();
@@ -96,10 +99,8 @@
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.nav_bar_tuner);
bindLayout((ListPreference) findPreference(LAYOUT));
- bindButton((PreferenceCategory) findPreference(LEFT),
- NAV_BAR_LEFT, NAVSPACE);
- bindButton((PreferenceCategory) findPreference(RIGHT),
- NAV_BAR_RIGHT, MENU_IME);
+ bindButton(NAV_BAR_LEFT, NAVSPACE, LEFT);
+ bindButton(NAV_BAR_RIGHT, MENU_IME, RIGHT);
}
@Override
@@ -129,9 +130,8 @@
});
}
- private void bindButton(PreferenceCategory parent, String setting, String def) {
- String k = parent.getKey();
- DropDownPreference type = (DropDownPreference) findPreference(TYPE + "_" + k);
+ private void bindButton(String setting, String def, String k) {
+ ListPreference type = (ListPreference) findPreference(TYPE + "_" + k);
Preference keycode = findPreference(KEYCODE + "_" + k);
ListPreference icon = (ListPreference) findPreference(ICON + "_" + k);
setupIcons(icon);
@@ -195,8 +195,14 @@
.loadDrawable(getContext());
d.setTint(Color.BLACK);
d.setBounds(0, 0, size, size);
- ImageSpan span = new ImageSpan(d);
+ ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
builder.append(" ", span, 0);
+ builder.append(" ");
+ for (int i = 0; i < ICONS.length; i++) {
+ if (ICONS[i][0] == id) {
+ builder.append(getString(ICONS[i][1]));
+ }
+ }
icon.setSummary(builder);
} catch (Exception e) {
Log.d("NavButton", "Problem with summary", e);
@@ -204,7 +210,7 @@
}
}
- private void setValue(String setting, DropDownPreference type, Preference keycode,
+ private void setValue(String setting, ListPreference type, Preference keycode,
ListPreference icon) {
String button = type.getValue();
if (KEY.equals(button)) {
@@ -226,14 +232,16 @@
getContext().getResources().getDisplayMetrics());
for (int i = 0; i < ICONS.length; i++) {
SpannableStringBuilder builder = new SpannableStringBuilder();
- Drawable d = Icon.createWithResource(getContext().getPackageName(), ICONS[i])
+ Drawable d = Icon.createWithResource(getContext().getPackageName(), ICONS[i][0])
.loadDrawable(getContext());
d.setTint(Color.BLACK);
d.setBounds(0, 0, size, size);
- ImageSpan span = new ImageSpan(d);
+ ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
builder.append(" ", span, 0);
+ builder.append(" ");
+ builder.append(getString(ICONS[i][1]));
labels[i] = builder;
- values[i] = getContext().getPackageName() + "/" + ICONS[i];
+ values[i] = getContext().getPackageName() + "/" + ICONS[i][0];
}
icon.setEntries(labels);
icon.setEntryValues(values);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java
new file mode 100644
index 0000000..dc0d8bf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java
@@ -0,0 +1,145 @@
+/*
+ * 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.tuner;
+
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toolbar;
+
+import com.android.settingslib.Utils;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.R;
+
+import libcore.util.Objects;
+
+public class RadioListPreference extends CustomListPreference {
+
+ private OnClickListener mOnClickListener;
+ private CharSequence mSummary;
+
+ public RadioListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(Builder builder, OnClickListener listener) {
+ mOnClickListener = listener;
+ }
+
+ @Override
+ public void setSummary(CharSequence summary) {
+ super.setSummary(summary);
+ mSummary = summary;
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ if (mSummary == null || mSummary.toString().contains("%s")) {
+ return super.getSummary();
+ }
+ return mSummary;
+ }
+
+ @Override
+ protected Dialog onDialogCreated(DialogFragment fragment, Dialog dialog) {
+ Dialog d = new Dialog(getContext(), android.R.style.Theme_DeviceDefault_Settings);
+ Toolbar t = (Toolbar) d.findViewById(com.android.internal.R.id.action_bar);
+ View v = new View(getContext());
+ v.setId(R.id.content);
+ d.setContentView(v);
+ t.setTitle(getTitle());
+ t.setNavigationIcon(Utils.getDrawable(d.getContext(), android.R.attr.homeAsUpIndicator));
+ t.setNavigationOnClickListener(view -> d.dismiss());
+
+ RadioFragment f = new RadioFragment();
+ f.setPreference(this);
+ FragmentHostManager.get(v).getFragmentManager()
+ .beginTransaction()
+ .add(android.R.id.content, f)
+ .commit();
+ return d;
+ }
+
+ @Override
+ protected void onDialogStateRestored(DialogFragment fragment, Dialog dialog,
+ Bundle savedInstanceState) {
+ super.onDialogStateRestored(fragment, dialog, savedInstanceState);
+ View view = dialog.findViewById(R.id.content);
+ RadioFragment radioFragment = (RadioFragment) FragmentHostManager.get(view)
+ .getFragmentManager().findFragmentById(R.id.content);
+ if (radioFragment != null) {
+ radioFragment.setPreference(this);
+ }
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+ }
+
+ public static class RadioFragment extends TunerPreferenceFragment {
+ private RadioListPreference mListPref;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ Context context = getPreferenceManager().getContext();
+ PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(context);
+ setPreferenceScreen(screen);
+ if (mListPref != null) {
+ update();
+ }
+ }
+
+ private void update() {
+ Context context = getPreferenceManager().getContext();
+
+ CharSequence[] entries = mListPref.getEntries();
+ CharSequence[] values = mListPref.getEntryValues();
+ CharSequence current = mListPref.getValue();
+ for (int i = 0; i < entries.length; i++) {
+ CharSequence entry = entries[i];
+ SelectablePreference pref = new SelectablePreference(context);
+ getPreferenceScreen().addPreference(pref);
+ pref.setTitle(entry);
+ pref.setChecked(Objects.equal(current, values[i]));
+ pref.setKey(String.valueOf(i));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(Preference preference) {
+ mListPref.mOnClickListener.onClick(null, Integer.parseInt(preference.getKey()));
+ return true;
+ }
+
+ public void setPreference(RadioListPreference radioListPreference) {
+ mListPref = radioListPreference;
+ if (getPreferenceManager() != null) {
+ update();
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java
new file mode 100644
index 0000000..1d15708
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java
@@ -0,0 +1,45 @@
+/*
+ * 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.tuner;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.v7.preference.CheckBoxPreference;
+import android.util.TypedValue;
+
+import com.android.systemui.statusbar.ScalingDrawableWrapper;
+
+public class SelectablePreference extends CheckBoxPreference {
+ private final int mSize;
+
+ public SelectablePreference(Context context) {
+ super(context);
+ setWidgetLayoutResource(com.android.systemui.R.layout.preference_widget_radiobutton);
+ setSelectable(true);
+ mSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32,
+ context.getResources().getDisplayMetrics());
+ }
+
+ @Override
+ public void setIcon(Drawable icon) {
+ super.setIcon(new ScalingDrawableWrapper(icon,
+ mSize / (float) icon.getIntrinsicWidth()));
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java
new file mode 100644
index 0000000..533388a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java
@@ -0,0 +1,200 @@
+/*
+ * 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.tuner;
+
+import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
+
+import android.content.Context;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.os.Process;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.PreferenceViewHolder;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.tuner.ShortcutParser.Shortcut;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ShortcutPicker extends PreferenceFragment implements Tunable {
+
+ private final ArrayList<SelectablePreference> mSelectablePreferences = new ArrayList<>();
+ private String mKey;
+ private SelectablePreference mNonePreference;
+ private TunerService mTunerService;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ Context context = getPreferenceManager().getContext();
+ PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(context);
+ screen.setOrderingAsAdded(true);
+ PreferenceCategory otherApps = new PreferenceCategory(context);
+ otherApps.setTitle(R.string.tuner_other_apps);
+
+ mNonePreference = new SelectablePreference(context);
+ mSelectablePreferences.add(mNonePreference);
+ mNonePreference.setTitle(R.string.lockscreen_none);
+ mNonePreference.setIcon(R.drawable.ic_remove_circle);
+ screen.addPreference(mNonePreference);
+
+ LauncherApps apps = getContext().getSystemService(LauncherApps.class);
+ List<LauncherActivityInfo> activities = apps.getActivityList(null,
+ Process.myUserHandle());
+
+ screen.addPreference(otherApps);
+ activities.forEach(info -> {
+ try {
+ List<Shortcut> shortcuts = new ShortcutParser(getContext(),
+ info.getComponentName()).getShortcuts();
+ AppPreference appPreference = new AppPreference(context, info);
+ mSelectablePreferences.add(appPreference);
+ if (shortcuts.size() != 0) {
+ //PreferenceCategory category = new PreferenceCategory(context);
+ //screen.addPreference(category);
+ //category.setTitle(info.getLabel());
+ screen.addPreference(appPreference);
+ shortcuts.forEach(shortcut -> {
+ ShortcutPreference shortcutPref = new ShortcutPreference(context, shortcut,
+ info.getLabel());
+ mSelectablePreferences.add(shortcutPref);
+ screen.addPreference(shortcutPref);
+ });
+ return;
+ }
+ otherApps.addPreference(appPreference);
+ } catch (NameNotFoundException e) {
+ }
+ });
+ // Move other apps to the bottom.
+ screen.removePreference(otherApps);
+ for (int i = 0; i < otherApps.getPreferenceCount(); i++) {
+ Preference p = otherApps.getPreference(0);
+ otherApps.removePreference(p);
+ p.setOrder(Preference.DEFAULT_ORDER);
+ screen.addPreference(p);
+ }
+ //screen.addPreference(otherApps);
+
+ setPreferenceScreen(screen);
+ mKey = getArguments().getString(ARG_PREFERENCE_ROOT);
+ mTunerService = Dependency.get(TunerService.class);
+ mTunerService.addTunable(this, mKey);
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(Preference preference) {
+ mTunerService.setValue(mKey, preference.toString());
+ getActivity().onBackPressed();
+ return true;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ if (LOCKSCREEN_LEFT_BUTTON.equals(mKey)) {
+ getActivity().setTitle(R.string.lockscreen_shortcut_left);
+ } else {
+ getActivity().setTitle(R.string.lockscreen_shortcut_right);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mTunerService.removeTunable(this);
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ String v = newValue != null ? newValue : "";
+ mSelectablePreferences.forEach(p -> p.setChecked(v.equals(p.toString())));
+ }
+
+ private static class AppPreference extends SelectablePreference {
+ private final LauncherActivityInfo mInfo;
+ private boolean mBinding;
+
+ public AppPreference(Context context, LauncherActivityInfo info) {
+ super(context);
+ mInfo = info;
+ setTitle(context.getString(R.string.tuner_launch_app, info.getLabel()));
+ setSummary(context.getString(R.string.tuner_app, info.getLabel()));
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ mBinding = true;
+ if (getIcon() == null) {
+ setIcon(mInfo.getBadgedIcon(
+ getContext().getResources().getConfiguration().densityDpi));
+ }
+ mBinding = false;
+ super.onBindViewHolder(holder);
+ }
+
+ @Override
+ protected void notifyChanged() {
+ if (mBinding) return;
+ super.notifyChanged();
+ }
+
+ @Override
+ public String toString() {
+ return mInfo.getComponentName().flattenToString();
+ }
+ }
+
+ private static class ShortcutPreference extends SelectablePreference {
+ private final Shortcut mShortcut;
+ private boolean mBinding;
+
+ public ShortcutPreference(Context context, Shortcut shortcut, CharSequence appLabel) {
+ super(context);
+ mShortcut = shortcut;
+ setTitle(shortcut.label);
+ setSummary(context.getString(R.string.tuner_app, appLabel));
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ mBinding = true;
+ if (getIcon() == null) {
+ setIcon(mShortcut.icon.loadDrawable(getContext()));
+ }
+ mBinding = false;
+ super.onBindViewHolder(holder);
+ }
+
+ @Override
+ protected void notifyChanged() {
+ if (mBinding) return;
+ super.notifyChanged();
+ }
+
+ @Override
+ public String toString() {
+ return mShortcut.toString();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 74280a3..4eb1db6 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -22,10 +22,12 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
+import android.view.MenuItem;
import com.android.settingslib.drawer.SettingsDrawerActivity;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.fragments.FragmentService;
public class TunerActivity extends SettingsDrawerActivity implements
PreferenceFragment.OnPreferenceStartFragmentCallback,
@@ -51,6 +53,22 @@
}
@Override
+ protected void onDestroy() {
+ super.onDestroy();
+ Dependency.destroy(FragmentService.class, s -> s.destroyAll());
+ Dependency.clearDependencies();
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ onBackPressed();
+ return true;
+ }
+ return super.onMenuItemSelected(featureId, item);
+ }
+
+ @Override
public void onBackPressed() {
if (!getFragmentManager().popBackStackImmediate()) {
super.onBackPressed();
@@ -62,6 +80,9 @@
try {
Class<?> cls = Class.forName(pref.getFragment());
Fragment fragment = (Fragment) cls.newInstance();
+ final Bundle b = new Bundle(1);
+ b.putString(PreferenceFragment.ARG_PREFERENCE_ROOT, pref.getKey());
+ fragment.setArguments(b);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
setTitle(pref.getTitle());
transaction.replace(R.id.content_frame, fragment);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java
new file mode 100644
index 0000000..06d40da
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java
@@ -0,0 +1,36 @@
+/*
+ * 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.tuner;
+
+import android.app.DialogFragment;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+
+public abstract class TunerPreferenceFragment extends PreferenceFragment {
+
+ @Override
+ public void onDisplayPreferenceDialog(Preference preference) {
+ DialogFragment f = null;
+ if (preference instanceof CustomListPreference) {
+ f = CustomListPreference.CustomListPreferenceDialogFragment
+ .newInstance(preference.getKey());
+ } else {
+ super.onDisplayPreferenceDialog(preference);
+ }
+ f.setTargetFragment(this, 0);
+ f.show(getFragmentManager(), "dialog_preference");
+ }
+}