summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-11-21 12:43:11 +0000
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-11-21 12:54:23 +0000
commit6ef90d3ebd47aba87ea5cadbef275fd08edd0b81 (patch)
tree7e47bba2eef709c799bd43d044330dcf8ea47595
parent28413bb813a4b621f6575b85ef04ce7636490f92 (diff)
downloadpackages_apps_settings-6ef90d3ebd47aba87ea5cadbef275fd08edd0b81.zip
packages_apps_settings-6ef90d3ebd47aba87ea5cadbef275fd08edd0b81.tar.gz
packages_apps_settings-6ef90d3ebd47aba87ea5cadbef275fd08edd0b81.tar.bz2
Add System menu and PowerWidget configuration support from mr0/10.0
Change-Id: I4c34812be0bc39dbe93e21a29682717ccf9c077f
-rw-r--r--AndroidManifest.xml6
-rw-r--r--res/drawable-hdpi-finger/ic_grabber.pngbin0 -> 1158 bytes
-rw-r--r--res/drawable-hdpi/ic_settings_system.pngbin0 -> 1155 bytes
-rwxr-xr-xres/drawable-mdpi-finger/ic_grabber.pngbin0 -> 550 bytes
-rw-r--r--res/drawable-mdpi/ic_settings_system.pngbin0 -> 794 bytes
-rw-r--r--res/drawable-xhdpi/ic_settings_system.pngbin0 -> 1728 bytes
-rw-r--r--res/layout-finger/order_power_widget_button_list_item.xml72
-rw-r--r--res/layout-finger/order_power_widget_buttons_activity.xml32
-rw-r--r--res/values/arrays.xml77
-rwxr-xr-xres/values/config.xml5
-rwxr-xr-xres/values/dimens.xml8
-rw-r--r--res/values/strings.xml55
-rw-r--r--res/xml/power_widget.xml68
-rw-r--r--res/xml/power_widget_settings.xml72
-rw-r--r--res/xml/settings_headers.xml6
-rw-r--r--res/xml/system_settings.xml27
-rw-r--r--src/com/android/settings/cyanogenmod/PowerWidget.java579
-rw-r--r--src/com/android/settings/cyanogenmod/PowerWidgetEnabler.java64
-rw-r--r--src/com/android/settings/cyanogenmod/PowerWidgetUtil.java213
-rw-r--r--src/com/android/settings/cyanogenmod/SwitchWidget.java75
-rw-r--r--src/com/android/settings/cyanogenmod/SystemSettings.java121
-rw-r--r--src/com/android/settings/cyanogenmod/TouchInterceptor.java360
22 files changed, 1840 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9415ea1..047148b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1517,6 +1517,12 @@
<activity android:name=".notificationlight.BatteryLightSettings" />
+ <activity android:name=".cyanogenmod.SystemSettings" />
+
+ <activity android:name=".cyanogenmod.PowerWidget" />
+
+ <!-- CyanogenMod activities End -->
+
<receiver android:name=".widget.SettingsAppWidgetProvider"
android:label="@string/gadget_title"
android:exported="true"
diff --git a/res/drawable-hdpi-finger/ic_grabber.png b/res/drawable-hdpi-finger/ic_grabber.png
new file mode 100644
index 0000000..0ff8d1a
--- /dev/null
+++ b/res/drawable-hdpi-finger/ic_grabber.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_settings_system.png b/res/drawable-hdpi/ic_settings_system.png
new file mode 100644
index 0000000..920b65e
--- /dev/null
+++ b/res/drawable-hdpi/ic_settings_system.png
Binary files differ
diff --git a/res/drawable-mdpi-finger/ic_grabber.png b/res/drawable-mdpi-finger/ic_grabber.png
new file mode 100755
index 0000000..9169ae5
--- /dev/null
+++ b/res/drawable-mdpi-finger/ic_grabber.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_settings_system.png b/res/drawable-mdpi/ic_settings_system.png
new file mode 100644
index 0000000..f738fd9
--- /dev/null
+++ b/res/drawable-mdpi/ic_settings_system.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_settings_system.png b/res/drawable-xhdpi/ic_settings_system.png
new file mode 100644
index 0000000..aa3b1fb
--- /dev/null
+++ b/res/drawable-xhdpi/ic_settings_system.png
Binary files differ
diff --git a/res/layout-finger/order_power_widget_button_list_item.xml b/res/layout-finger/order_power_widget_button_list_item.xml
new file mode 100644
index 0000000..8d9fc45
--- /dev/null
+++ b/res/layout-finger/order_power_widget_button_list_item.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2008, 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="match_parent"
+ android:layout_height="64dip"
+ android:gravity="bottom"
+ android:orientation="vertical"
+ android:baselineAligned="false">
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:drawable/divider_horizontal_dark" />
+
+ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="64dip"
+ android:gravity="center_vertical"
+ android:ignoreGravity="@+id/icon">
+
+ <!-- left icon, used for the grabber -->
+ <ImageView android:id="@+id/grabber"
+ android:src="@drawable/ic_grabber"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentBottom="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <!-- icon representing the galaxy s widget button -->
+ <ImageView android:id="@+id/icon"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop = "true"
+ android:layout_alignParentBottom = "true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="10dip" />
+
+ <!-- The height is set to half the height of the parent, which is 64 dip -->
+ <TextView android:id="@+id/name"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="wrap_content"
+ android:paddingLeft="9dip"
+ android:paddingRight="9dip"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop = "true"
+ android:layout_alignParentBottom = "true"
+ android:layout_toRightOf="@id/grabber"
+ android:layout_toLeftOf="@id/icon"
+ android:ellipsize="marquee"
+ android:gravity="center_vertical"
+ android:singleLine="true" />
+
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/res/layout-finger/order_power_widget_buttons_activity.xml b/res/layout-finger/order_power_widget_buttons_activity.xml
new file mode 100644
index 0000000..42124a0
--- /dev/null
+++ b/res/layout-finger/order_power_widget_buttons_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_vertical" >
+
+ <com.android.settings.cyanogenmod.TouchInterceptor
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:textSize="18sp"
+ android:drawSelectorOnTop="false"
+ android:fastScrollEnabled="true" />
+
+</LinearLayout>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 90b76b3..6aa8983 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -907,5 +907,82 @@
<item>5000</item>
</string-array>
+ <!-- Arrays required by Notification Widgets. -->
+ <string-array name="entries_brightness_widget" formatted="false" translatable="false">
+ <item>@string/cm_brightness_mode_auto</item>
+ <item>@string/cm_brightness_mode_dim</item>
+ <item>25%</item>
+ <item>50%</item>
+ <item>75%</item>
+ <item>100%</item>
+ </string-array>
+
+ <string-array name="values_brightness_widget" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>4</item>
+ <item>5</item>
+ </string-array>
+
+ <string-array name="entries_network_widget">
+ <item>2G/3G+2G</item>
+ <item>2G/3G Only</item>
+ <item>2G/3G Only/3G+2G</item>
+ </string-array>
+
+ <string-array name="values_network_widget" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ </string-array>
+
+ <string-array name="entries_screentimeout_widget">
+ <item>15s/1m/5m</item>
+ <item>30s/2m/5m</item>
+ </string-array>
+
+ <string-array name="values_screentimeout_widget" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ </string-array>
+
+ <string-array name="entries_ring_widget" translatable="false">
+ <item>@string/cm_sound_mode_silent</item>
+ <item>@string/cm_sound_mode_vibrate</item>
+ <item>@string/cm_sound_mode_sound</item>
+ <item>@string/cm_sound_mode_soundVibrate</item>
+ </string-array>
+
+ <string-array name="values_ring_widget" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <string-array name="entries_flash_widget">
+ <item>Normal</item>
+ <item>High</item>
+ </string-array>
+
+ <string-array name="values_flash_widget" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ </string-array>
+
+ <string-array name="haptic_feedback_entries">
+ <item>Use global setting</item>
+ <item>On</item>
+ <item>Off</item>
+ </string-array>
+
+ <string-array name="haptic_feedback_values" translatable="false">
+ <item>2</item>
+ <item>1</item>
+ <item>0</item>
+ </string-array>
+
<!-- **** CYANOGENMOD EDITS END **** -->
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 557dadb..2b0e17b 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -29,4 +29,9 @@
very long strings too. -->
<integer name="maximum_user_dictionary_word_length" translatable="false">48</integer>
+ <!-- **** CYANOGENMOD ADDITIONS START **** -->
+ <!-- LED Flashlight -->
+ <bool name="has_led_flash">false</bool>
+
+ <!-- **** CYANOGENMOD ADDITIONS END **** -->
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c168819..cbc9b6d 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -62,7 +62,15 @@
<dimen name="keyguard_appwidget_picker_margin_right">6dip</dimen>
<integer name="keyguard_appwidget_picker_cols">1</integer>
+ <!-- **** CYANOGENMOD ADDITIONS START **** -->
+
<!-- Light settings dialog -->
<dimen name="dialog_light_settings_width">400dip</dimen>
+ <!-- height of a normal list item in edit playlist mode -->
+ <dimen name="normal_height">64dip</dimen>
+ <!-- height of an expanded list item in edit playlist mode -->
+ <dimen name="expanded_height">128dip</dimen>
+
+ <!-- **** CYANOGENMOD ADDITIONS END **** -->
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 21b89fd..5b96a1f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4456,6 +4456,13 @@
<!-- Themes settings -->
<string name="themes_settings_title">Themes</string>
+ <!-- System Interface settings -->
+ <string name="system_settings_title">System</string>
+ <string name="system_interface_title">System interface</string>
+
+ <!-- Notification Drawer -->
+ <string name="notification_drawer_title">Notification drawer</string>
+
<!-- Profiles settings -->
<string name="profiles_settings_title">Profiles</string>
<string name="profiles_general_title">General</string>
@@ -4629,5 +4636,53 @@
<string name="battery_light_medium_color_title">Charging</string>
<string name="battery_light_full_color_title">Fully charged</string>
+ <!-- Power Widget -->
+ <string name="power_widget_title">Power widget</string>
+ <string name="title_expanded_widget">Power widget</string>
+ <string name="power_widget_behavior">Widget behavior</string>
+ <string name="title_expanded_hide_onchange">Close drawer on change</string>
+ <string name="title_expanded_hide_indicator">Hide indicators</string>
+ <string name="title_expanded_hide_scrollbar">Hide scrollbar</string>
+ <string name="title_widget_picker">Widget buttons</string>
+ <string name="summary_widget_picker">View or change the displayed buttons</string>
+ <string name="title_widget_order">Widget button order</string>
+ <string name="summary_widget_order">View or change the order of the buttons</string>
+ <string name="title_buttons">Buttons</string>
+ <string name="title_toggle_wifi">Toggle Wi-Fi</string>
+ <string name="title_toggle_bluetooth">Toggle Bluetooth</string>
+ <string name="title_toggle_gps">Toggle GPS</string>
+ <string name="title_toggle_sound">Toggle Sound</string>
+ <string name="title_toggle_brightness">Toggle Brightness</string>
+ <string name="title_toggle_sync">Toggle Sync</string>
+ <string name="title_toggle_wifiap">Toggle Wi-Fi AP</string>
+ <string name="title_toggle_screentimeout">Toggle Screen timeout</string>
+ <string name="title_toggle_mobiledata">Toggle Mobile data</string>
+ <string name="title_toggle_lockscreen">Toggle Lock screen</string>
+ <string name="title_toggle_networkmode">Toggle 2G/3G</string>
+ <string name="title_toggle_autorotate">Toggle Orientation</string>
+ <string name="title_toggle_airplane">Toggle Airplane mode</string>
+ <string name="title_toggle_flashlight">Toggle LED flashlight</string>
+ <string name="title_toggle_sleep">Go to sleep</string>
+ <string name="title_toggle_media_play_pause">Media: Toggle Play/Pause</string>
+ <string name="title_toggle_media_previous">Media: Skip to Previous</string>
+ <string name="title_toggle_media_next">Media: Skip to Next</string>
+ <string name="title_toggle_lte">Toggle LTE</string>
+ <string name="title_toggle_wimax">Toggle WiMAX</string>
+ <string name="title_button_modes">Button modes</string>
+ <string name="pref_brightness_mode_title">Brightness modes</string>
+ <string name="pref_brightness_mode_summary">View or change the Brightness button modes</string>
+ <string name="cm_brightness_mode_auto">Auto</string>
+ <string name="cm_brightness_mode_dim">Dim</string>
+ <string name="pref_network_mode_title">Network modes</string>
+ <string name="pref_screentimeout_mode_title">Screen timeout modes</string>
+ <string name="pref_ring_mode_title">Sound modes</string>
+ <string name="pref_ring_mode_summary">View or change the Sound button modes</string>
+ <string name="cm_sound_mode_silent">Silent</string>
+ <string name="cm_sound_mode_vibrate">Vibrate</string>
+ <string name="cm_sound_mode_sound">Sound</string>
+ <string name="cm_sound_mode_soundVibrate">Sound + Vibrate</string>
+ <string name="pref_flash_mode_title">Flash mode</string>
+ <string name="expanded_haptic_feedback_title">Haptic feedback</string>
+
<!-- **** CYANOGENMOD ADDITIONS END **** -->
</resources>
diff --git a/res/xml/power_widget.xml b/res/xml/power_widget.xml
new file mode 100644
index 0000000..b900e85
--- /dev/null
+++ b/res/xml/power_widget.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The CyanogenMod 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:key="pref_buttons"
+ android:title="@string/title_buttons" />
+
+ <PreferenceCategory
+ android:key="pref_buttons_modes"
+ android:title="@string/title_button_modes">
+
+ <MultiSelectListPreference
+ android:key="pref_brightness_mode"
+ android:dialogTitle="@string/pref_brightness_mode_title"
+ android:title="@string/pref_brightness_mode_title"
+ android:summary="@string/pref_brightness_mode_summary"
+ android:entries="@array/entries_brightness_widget"
+ android:entryValues="@array/values_brightness_widget"
+ android:persistent="false" />
+
+ <ListPreference
+ android:key="pref_network_mode"
+ android:dialogTitle="@string/pref_network_mode_title"
+ android:title="@string/pref_network_mode_title"
+ android:entries="@array/entries_network_widget"
+ android:entryValues="@array/values_network_widget" />
+
+ <ListPreference
+ android:key="pref_screentimeout_mode"
+ android:dialogTitle="@string/pref_screentimeout_mode_title"
+ android:title="@string/pref_screentimeout_mode_title"
+ android:entries="@array/entries_screentimeout_widget"
+ android:entryValues="@array/values_screentimeout_widget" />
+
+ <MultiSelectListPreference
+ android:key="pref_ring_mode"
+ android:dialogTitle="@string/pref_ring_mode_title"
+ android:title="@string/pref_ring_mode_title"
+ android:summary="@string/pref_ring_mode_summary"
+ android:entries="@array/entries_ring_widget"
+ android:entryValues="@array/values_ring_widget"
+ android:persistent="false" />
+
+ <ListPreference
+ android:key="pref_flash_mode"
+ android:dialogTitle="@string/pref_flash_mode_title"
+ android:title="@string/pref_flash_mode_title"
+ android:entries="@array/entries_flash_widget"
+ android:entryValues="@array/values_flash_widget" />
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/power_widget_settings.xml b/res/xml/power_widget_settings.xml
new file mode 100644
index 0000000..2a068c7
--- /dev/null
+++ b/res/xml/power_widget_settings.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The CyanogenMod 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!-- Notification drawer Power Widget -->
+ <PreferenceCategory
+ android:title="@string/power_widget_title">
+
+ <CheckBoxPreference
+ android:key="expanded_widget"
+ android:title="@string/title_expanded_widget"
+ android:defaultValue="true" />
+
+ <PreferenceScreen
+ android:key="widget_picker"
+ android:title="@string/title_widget_picker"
+ android:summary="@string/summary_widget_picker"
+ android:dependency="expanded_widget"
+ android:fragment="com.android.settings.cyanogenmod.PowerWidget$PowerWidgetChooser">
+ </PreferenceScreen>
+
+ <PreferenceScreen
+ android:key="widget_order"
+ android:title="@string/title_widget_order"
+ android:summary="@string/summary_widget_order"
+ android:dependency="expanded_widget"
+ android:fragment="com.android.settings.cyanogenmod.PowerWidget$PowerWidgetOrder">
+ </PreferenceScreen>
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/power_widget_behavior">
+
+ <CheckBoxPreference
+ android:key="expanded_hide_onchange"
+ android:title="@string/title_expanded_hide_onchange"
+ android:defaultValue="false"
+ android:dependency="expanded_widget" />
+
+ <CheckBoxPreference
+ android:key="expanded_hide_scrollbar"
+ android:title="@string/title_expanded_hide_scrollbar"
+ android:defaultValue="false"
+ android:dependency="expanded_widget" />
+
+ <ListPreference
+ android:key="expanded_haptic_feedback"
+ android:dialogTitle="@string/expanded_haptic_feedback_title"
+ android:title="@string/expanded_haptic_feedback_title"
+ android:entries="@array/haptic_feedback_entries"
+ android:entryValues="@array/haptic_feedback_values"
+ android:dependency="expanded_widget" />
+
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml
index f25014d..57f363f 100644
--- a/res/xml/settings_headers.xml
+++ b/res/xml/settings_headers.xml
@@ -78,6 +78,12 @@
android:targetClass="com.tmobile.themechooser.ThemeChooser" />
</header>
+ <!-- System -->
+ <header
+ android:id="@+id/system_settings"
+ android:icon="@drawable/ic_settings_system"
+ android:fragment="com.android.settings.cyanogenmod.SystemSettings"
+ android:title="@string/system_settings_title" />
<!-- DEVICE -->
<header android:id="@+id/device_section"
diff --git a/res/xml/system_settings.xml b/res/xml/system_settings.xml
new file mode 100644
index 0000000..6b42c1f
--- /dev/null
+++ b/res/xml/system_settings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The CyanogenMod 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/system_interface_title"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+ <PreferenceScreen
+ android:key="notification_drawer"
+ android:fragment="com.android.settings.cyanogenmod.PowerWidget"
+ android:title="@string/notification_drawer_title" />
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/cyanogenmod/PowerWidget.java b/src/com/android/settings/cyanogenmod/PowerWidget.java
new file mode 100644
index 0000000..b4f0e77
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/PowerWidget.java
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2011 The CyanogenMod 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.settings.cyanogenmod;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import android.app.ListFragment;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.net.wimax.WimaxHelper;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.MultiSelectListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.internal.telephony.Phone;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+public class PowerWidget extends SettingsPreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ private static final String TAG = "PowerWidget";
+ private static final String SEPARATOR = "OV=I=XseparatorX=I=VO";
+ private static final String UI_EXP_WIDGET = "expanded_widget";
+ private static final String UI_EXP_WIDGET_HIDE_ONCHANGE = "expanded_hide_onchange";
+ private static final String UI_EXP_WIDGET_HIDE_SCROLLBAR = "expanded_hide_scrollbar";
+ private static final String UI_EXP_WIDGET_HAPTIC_FEEDBACK = "expanded_haptic_feedback";
+
+ private CheckBoxPreference mPowerWidget;
+ private CheckBoxPreference mPowerWidgetHideOnChange;
+ private CheckBoxPreference mPowerWidgetHideScrollBar;
+ private ListPreference mPowerWidgetHapticFeedback;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (getPreferenceManager() != null) {
+ addPreferencesFromResource(R.xml.power_widget_settings);
+
+ PreferenceScreen prefSet = getPreferenceScreen();
+
+ mPowerWidget = (CheckBoxPreference) prefSet.findPreference(UI_EXP_WIDGET);
+ mPowerWidgetHideOnChange = (CheckBoxPreference) prefSet
+ .findPreference(UI_EXP_WIDGET_HIDE_ONCHANGE);
+ mPowerWidgetHideScrollBar = (CheckBoxPreference) prefSet
+ .findPreference(UI_EXP_WIDGET_HIDE_SCROLLBAR);
+
+ mPowerWidgetHapticFeedback = (ListPreference) prefSet
+ .findPreference(UI_EXP_WIDGET_HAPTIC_FEEDBACK);
+ mPowerWidgetHapticFeedback.setOnPreferenceChangeListener(this);
+ mPowerWidgetHapticFeedback.setSummary(mPowerWidgetHapticFeedback.getEntry());
+
+ mPowerWidget.setChecked((Settings.System.getInt(getActivity().getApplicationContext()
+ .getContentResolver(),
+ Settings.System.EXPANDED_VIEW_WIDGET, 1) == 1));
+ mPowerWidgetHideOnChange.setChecked((Settings.System.getInt(getActivity()
+ .getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_HIDE_ONCHANGE, 0) == 1));
+ mPowerWidgetHideScrollBar.setChecked((Settings.System.getInt(getActivity()
+ .getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_HIDE_SCROLLBAR, 0) == 1));
+ mPowerWidgetHapticFeedback.setValue(Integer.toString(Settings.System.getInt(
+ getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_HAPTIC_FEEDBACK, 2)));
+ }
+ }
+
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mPowerWidgetHapticFeedback) {
+ int intValue = Integer.parseInt((String) newValue);
+ int index = mPowerWidgetHapticFeedback.findIndexOfValue((String) newValue);
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_HAPTIC_FEEDBACK, intValue);
+ mPowerWidgetHapticFeedback.setSummary(mPowerWidgetHapticFeedback.getEntries()[index]);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ boolean value;
+
+ if (preference == mPowerWidget) {
+ value = mPowerWidget.isChecked();
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_VIEW_WIDGET,
+ value ? 1 : 0);
+ } else if (preference == mPowerWidgetHideOnChange) {
+ value = mPowerWidgetHideOnChange.isChecked();
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_HIDE_ONCHANGE,
+ value ? 1 : 0);
+ } else if (preference == mPowerWidgetHideScrollBar) {
+ value = mPowerWidgetHideScrollBar.isChecked();
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_HIDE_SCROLLBAR,
+ value ? 1 : 0);
+ } else {
+ // If we didn't handle it, let preferences handle it.
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+
+ return true;
+ }
+
+ public static class PowerWidgetChooser extends SettingsPreferenceFragment
+ implements Preference.OnPreferenceChangeListener {
+
+ public PowerWidgetChooser() {
+ }
+
+ private static final String TAG = "PowerWidgetActivity";
+
+ private static final String BUTTONS_CATEGORY = "pref_buttons";
+ private static final String BUTTON_MODES_CATEGORY = "pref_buttons_modes";
+ private static final String SELECT_BUTTON_KEY_PREFIX = "pref_button_";
+
+ private static final String EXP_BRIGHTNESS_MODE = "pref_brightness_mode";
+ private static final String EXP_NETWORK_MODE = "pref_network_mode";
+ private static final String EXP_SCREENTIMEOUT_MODE = "pref_screentimeout_mode";
+ private static final String EXP_RING_MODE = "pref_ring_mode";
+ private static final String EXP_FLASH_MODE = "pref_flash_mode";
+
+ private HashMap<CheckBoxPreference, String> mCheckBoxPrefs = new HashMap<CheckBoxPreference, String>();
+
+ MultiSelectListPreference mBrightnessMode;
+ ListPreference mNetworkMode;
+ ListPreference mScreenTimeoutMode;
+ MultiSelectListPreference mRingMode;
+ ListPreference mFlashMode;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ addPreferencesFromResource(R.xml.power_widget);
+
+ PreferenceScreen prefSet = getPreferenceScreen();
+ PackageManager pm = getPackageManager();
+
+ if (getActivity().getApplicationContext() == null) {
+ return;
+ }
+
+ mBrightnessMode = (MultiSelectListPreference) prefSet
+ .findPreference(EXP_BRIGHTNESS_MODE);
+ String storedBrightnessMode = Settings.System.getString(getActivity()
+ .getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_BRIGHTNESS_MODE);
+ if (storedBrightnessMode != null) {
+ String[] brightnessModeArray = TextUtils.split(storedBrightnessMode, SEPARATOR);
+ mBrightnessMode.setValues(new HashSet<String>(Arrays.asList(brightnessModeArray)));
+ updateSummary(storedBrightnessMode, mBrightnessMode, R.string.pref_brightness_mode_summary);
+ }
+ mBrightnessMode.setOnPreferenceChangeListener(this);
+ mNetworkMode = (ListPreference) prefSet.findPreference(EXP_NETWORK_MODE);
+ mNetworkMode.setOnPreferenceChangeListener(this);
+ mScreenTimeoutMode = (ListPreference) prefSet.findPreference(EXP_SCREENTIMEOUT_MODE);
+ mScreenTimeoutMode.setOnPreferenceChangeListener(this);
+ mRingMode = (MultiSelectListPreference) prefSet.findPreference(EXP_RING_MODE);
+ String storedRingMode = Settings.System.getString(getActivity()
+ .getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_RING_MODE);
+ if (storedRingMode != null) {
+ String[] ringModeArray = TextUtils.split(storedRingMode, SEPARATOR);
+ mRingMode.setValues(new HashSet<String>(Arrays.asList(ringModeArray)));
+ updateSummary(storedRingMode, mRingMode, R.string.pref_ring_mode_summary);
+ }
+ mRingMode.setOnPreferenceChangeListener(this);
+ mFlashMode = (ListPreference) prefSet.findPreference(EXP_FLASH_MODE);
+ mFlashMode.setOnPreferenceChangeListener(this);
+
+ // TODO: set the default values of the items
+
+ // Update the summary text
+ mNetworkMode.setSummary(mNetworkMode.getEntry());
+ mScreenTimeoutMode.setSummary(mScreenTimeoutMode.getEntry());
+ mFlashMode.setSummary(mFlashMode.getEntry());
+
+ // Add the available buttons to the list
+ PreferenceCategory prefButtons = (PreferenceCategory) prefSet
+ .findPreference(BUTTONS_CATEGORY);
+
+ // Add the available mode buttons, incase they need to be removed later
+ PreferenceCategory prefButtonsModes = (PreferenceCategory) prefSet
+ .findPreference(BUTTON_MODES_CATEGORY);
+
+ // empty our preference category and set it to order as added
+ prefButtons.removeAll();
+ prefButtons.setOrderingAsAdded(false);
+
+ // emtpy our checkbox map
+ mCheckBoxPrefs.clear();
+
+ // get our list of buttons
+ ArrayList<String> buttonList = PowerWidgetUtil.getButtonListFromString(PowerWidgetUtil
+ .getCurrentButtons(getActivity().getApplicationContext()));
+
+ // Don't show WiMAX option if not supported
+ boolean isWimaxEnabled = WimaxHelper.isWimaxSupported(getActivity());
+ if (!isWimaxEnabled) {
+ PowerWidgetUtil.BUTTONS.remove(PowerWidgetUtil.BUTTON_WIMAX);
+ }
+
+ // Don't show mobile data options if not supported
+ boolean isMobileData = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ if (!isMobileData) {
+ PowerWidgetUtil.BUTTONS.remove(PowerWidgetUtil.BUTTON_MOBILEDATA);
+ PowerWidgetUtil.BUTTONS.remove(PowerWidgetUtil.BUTTON_NETWORKMODE);
+ prefButtonsModes.removePreference(mNetworkMode);
+ }
+
+ // fill that checkbox map!
+ for (PowerWidgetUtil.ButtonInfo button : PowerWidgetUtil.BUTTONS.values()) {
+ // create a checkbox
+ CheckBoxPreference cb = new CheckBoxPreference(getActivity()
+ .getApplicationContext());
+
+ // set a dynamic key based on button id
+ cb.setKey(SELECT_BUTTON_KEY_PREFIX + button.getId());
+
+ // set vanity info
+ cb.setTitle(button.getTitleResId());
+
+ // set our checked state
+ if (buttonList.contains(button.getId())) {
+ cb.setChecked(true);
+ } else {
+ cb.setChecked(false);
+ }
+
+ // add to our prefs set
+ mCheckBoxPrefs.put(cb, button.getId());
+
+ // specific checks for availability on some platforms
+ if (PowerWidgetUtil.BUTTON_FLASHLIGHT.equals(button.getId()) &&
+ !getResources().getBoolean(R.bool.has_led_flash)) {
+ // disable flashlight if it's not supported
+ cb.setEnabled(false);
+ mFlashMode.setEnabled(false);
+ } else if (PowerWidgetUtil.BUTTON_NETWORKMODE.equals(button.getId())) {
+ // some phones run on networks not supported by this button,
+ // so disable it
+ int network_state = -99;
+
+ try {
+ network_state = Settings.Secure.getInt(getActivity()
+ .getApplicationContext().getContentResolver(),
+ Settings.Global.PREFERRED_NETWORK_MODE);
+ } catch (Settings.SettingNotFoundException e) {
+ Log.e(TAG, "Unable to retrieve PREFERRED_NETWORK_MODE", e);
+ }
+
+ switch (network_state) {
+ // list of supported network modes
+ case Phone.NT_MODE_WCDMA_PREF:
+ case Phone.NT_MODE_WCDMA_ONLY:
+ case Phone.NT_MODE_GSM_UMTS:
+ case Phone.NT_MODE_GSM_ONLY:
+ break;
+ default:
+ cb.setEnabled(false);
+ break;
+ }
+ }
+
+ // add to the category
+ prefButtons.addPreference(cb);
+ }
+ }
+
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+ Preference preference) {
+ // we only modify the button list if it was one of our checks that
+ // was clicked
+ boolean buttonWasModified = false;
+ ArrayList<String> buttonList = new ArrayList<String>();
+ for (Map.Entry<CheckBoxPreference, String> entry : mCheckBoxPrefs.entrySet()) {
+ if (entry.getKey().isChecked()) {
+ buttonList.add(entry.getValue());
+ }
+
+ if (preference == entry.getKey()) {
+ buttonWasModified = true;
+ }
+ }
+
+ if (buttonWasModified) {
+ // now we do some wizardry and reset the button list
+ PowerWidgetUtil.saveCurrentButtons(getActivity().getApplicationContext(),
+ PowerWidgetUtil.mergeInNewButtonString(
+ PowerWidgetUtil.getCurrentButtons(getActivity()
+ .getApplicationContext()), PowerWidgetUtil
+ .getButtonStringFromList(buttonList)));
+ return true;
+ }
+
+ return false;
+ }
+
+ private class MultiSelectListPreferenceComparator implements Comparator<String> {
+ private MultiSelectListPreference pref;
+
+ MultiSelectListPreferenceComparator(MultiSelectListPreference p) {
+ pref = p;
+ }
+
+ @Override
+ public int compare(String lhs, String rhs) {
+ return Integer.compare(pref.findIndexOfValue(lhs),
+ pref.findIndexOfValue(rhs));
+ }
+ }
+
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mBrightnessMode) {
+ ArrayList<String> arrValue = new ArrayList<String>((Set<String>) newValue);
+ Collections.sort(arrValue, new MultiSelectListPreferenceComparator(mBrightnessMode));
+ Settings.System.putString(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_BRIGHTNESS_MODE, TextUtils.join(SEPARATOR, arrValue));
+ updateSummary(TextUtils.join(SEPARATOR, arrValue),
+ mBrightnessMode, R.string.pref_brightness_mode_summary);
+ } else if (preference == mNetworkMode) {
+ int value = Integer.valueOf((String) newValue);
+ int index = mNetworkMode.findIndexOfValue((String) newValue);
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_NETWORK_MODE, value);
+ mNetworkMode.setSummary(mNetworkMode.getEntries()[index]);
+ } else if (preference == mScreenTimeoutMode) {
+ int value = Integer.valueOf((String) newValue);
+ int index = mScreenTimeoutMode.findIndexOfValue((String) newValue);
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_SCREENTIMEOUT_MODE, value);
+ mScreenTimeoutMode.setSummary(mScreenTimeoutMode.getEntries()[index]);
+ } else if (preference == mRingMode) {
+ ArrayList<String> arrValue = new ArrayList<String>((Set<String>) newValue);
+ Collections.sort(arrValue, new MultiSelectListPreferenceComparator(mRingMode));
+ Settings.System.putString(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_RING_MODE, TextUtils.join(SEPARATOR, arrValue));
+ updateSummary(TextUtils.join(SEPARATOR, arrValue), mRingMode, R.string.pref_ring_mode_summary);
+ } else if (preference == mFlashMode) {
+ int value = Integer.valueOf((String) newValue);
+ int index = mFlashMode.findIndexOfValue((String) newValue);
+ Settings.System.putInt(getActivity().getApplicationContext().getContentResolver(),
+ Settings.System.EXPANDED_FLASH_MODE, value);
+ mFlashMode.setSummary(mFlashMode.getEntries()[index]);
+ }
+ return true;
+ }
+
+ private void updateSummary(String val, MultiSelectListPreference pref, int defSummary) {
+ // Update summary message with current values
+ final String[] values = parseStoredValue(val);
+ if (values != null) {
+ final int length = values.length;
+ final CharSequence[] entries = pref.getEntries();
+ StringBuilder summary = new StringBuilder();
+ for (int i = 0; i < (length); i++) {
+ CharSequence entry = entries[Integer.parseInt(values[i])];
+ if ((length - i) > 2) {
+ summary.append(entry).append(", ");
+ } else if ((length - i) == 2) {
+ summary.append(entry).append(" & ");
+ } else if ((length - i) == 1) {
+ summary.append(entry);
+ }
+ }
+ pref.setSummary(summary);
+ } else {
+ pref.setSummary(defSummary);
+ }
+ }
+
+ public static String[] parseStoredValue(CharSequence val) {
+ if (TextUtils.isEmpty(val)) {
+ return null;
+ } else {
+ return val.toString().split(SEPARATOR);
+ }
+ }
+
+ }
+
+ public static class PowerWidgetOrder extends ListFragment
+ {
+ private static final String TAG = "PowerWidgetOrderActivity";
+
+ private ListView mButtonList;
+ private ButtonAdapter mButtonAdapter;
+ View mContentView = null;
+ Context mContext;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mContentView = inflater.inflate(R.layout.order_power_widget_buttons_activity, null);
+ return mContentView;
+ }
+
+ /** Called when the activity is first created. */
+ // @Override
+ // public void onCreate(Bundle icicle)
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ mContext = getActivity().getApplicationContext();
+
+ mButtonList = getListView();
+ ((TouchInterceptor) mButtonList).setDropListener(mDropListener);
+ mButtonAdapter = new ButtonAdapter(mContext);
+ setListAdapter(mButtonAdapter);
+ }
+
+ @Override
+ public void onDestroy() {
+ ((TouchInterceptor) mButtonList).setDropListener(null);
+ setListAdapter(null);
+ super.onDestroy();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // reload our buttons and invalidate the views for redraw
+ mButtonAdapter.reloadButtons();
+ mButtonList.invalidateViews();
+ }
+
+ private TouchInterceptor.DropListener mDropListener = new TouchInterceptor.DropListener() {
+ public void drop(int from, int to) {
+ // get the current button list
+ ArrayList<String> buttons = PowerWidgetUtil.getButtonListFromString(
+ PowerWidgetUtil.getCurrentButtons(mContext));
+
+ // move the button
+ if (from < buttons.size()) {
+ String button = buttons.remove(from);
+
+ if (to <= buttons.size()) {
+ buttons.add(to, button);
+
+ // save our buttons
+ PowerWidgetUtil.saveCurrentButtons(mContext,
+ PowerWidgetUtil.getButtonStringFromList(buttons));
+
+ // tell our adapter/listview to reload
+ mButtonAdapter.reloadButtons();
+ mButtonList.invalidateViews();
+ }
+ }
+ }
+ };
+
+ private class ButtonAdapter extends BaseAdapter {
+ private Context mContext;
+ private Resources mSystemUIResources = null;
+ private LayoutInflater mInflater;
+ private ArrayList<PowerWidgetUtil.ButtonInfo> mButtons;
+
+ public ButtonAdapter(Context c) {
+ mContext = c;
+ mInflater = LayoutInflater.from(mContext);
+
+ PackageManager pm = mContext.getPackageManager();
+ if (pm != null) {
+ try {
+ mSystemUIResources = pm.getResourcesForApplication("com.android.systemui");
+ } catch (Exception e) {
+ mSystemUIResources = null;
+ Log.e(TAG, "Could not load SystemUI resources", e);
+ }
+ }
+
+ reloadButtons();
+ }
+
+ public void reloadButtons() {
+ ArrayList<String> buttons = PowerWidgetUtil.getButtonListFromString(
+ PowerWidgetUtil.getCurrentButtons(mContext));
+
+ mButtons = new ArrayList<PowerWidgetUtil.ButtonInfo>();
+ for (String button : buttons) {
+ if (PowerWidgetUtil.BUTTONS.containsKey(button)) {
+ mButtons.add(PowerWidgetUtil.BUTTONS.get(button));
+ }
+ }
+ }
+
+ public int getCount() {
+ return mButtons.size();
+ }
+
+ public Object getItem(int position) {
+ return mButtons.get(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final View v;
+ if (convertView == null) {
+ v = mInflater.inflate(R.layout.order_power_widget_button_list_item, null);
+ } else {
+ v = convertView;
+ }
+
+ PowerWidgetUtil.ButtonInfo button = mButtons.get(position);
+
+ final TextView name = (TextView) v.findViewById(R.id.name);
+ final ImageView icon = (ImageView) v.findViewById(R.id.icon);
+
+ name.setText(button.getTitleResId());
+
+ // assume no icon first
+ icon.setVisibility(View.GONE);
+
+ // attempt to load the icon for this button
+ if (mSystemUIResources != null) {
+ int resId = mSystemUIResources.getIdentifier(button.getIcon(), null, null);
+ if (resId > 0) {
+ try {
+ Drawable d = mSystemUIResources.getDrawable(resId);
+ icon.setVisibility(View.VISIBLE);
+ icon.setImageDrawable(d);
+ } catch (Exception e) {
+ Log.e(TAG, "Error retrieving icon drawable", e);
+ }
+ }
+ }
+
+ return v;
+ }
+ }
+ }
+
+}
diff --git a/src/com/android/settings/cyanogenmod/PowerWidgetEnabler.java b/src/com/android/settings/cyanogenmod/PowerWidgetEnabler.java
new file mode 100644
index 0000000..22a9aad
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/PowerWidgetEnabler.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.settings.cyanogenmod;
+
+import android.provider.Settings;
+import android.content.Context;
+import android.widget.CompoundButton;
+import android.widget.Switch;
+
+import com.android.settings.cyanogenmod.SwitchWidget;
+
+public class PowerWidgetEnabler extends SwitchWidget {
+ public PowerWidgetEnabler(Context context, Switch switch_) {
+ mContext = context;
+ mSwitch = switch_;
+ }
+
+ public void resume() {
+ mSwitch.setOnCheckedChangeListener(this);
+ }
+
+ public void pause() {
+ mSwitch.setOnCheckedChangeListener(null);
+ }
+
+ public void setState(Switch switch_) {
+ int isEnabled = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_VIEW_WIDGET, 1);
+ mSwitch.setChecked(isEnabled == 1 ? true : false);
+ return;
+ }
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ // Do nothing if called as a result of a state machine event
+ if (mStateMachineEvent) {
+ return;
+ }
+ Settings.System.putInt(mContext.getContentResolver(), Settings.System.EXPANDED_VIEW_WIDGET,
+ isChecked ? 1 : 0);
+ return;
+ }
+
+ private void setSwitchChecked(boolean checked) {
+ if (checked != mSwitch.isChecked()) {
+ mStateMachineEvent = true;
+ mSwitch.setChecked(checked);
+ mStateMachineEvent = false;
+ }
+ }
+}
diff --git a/src/com/android/settings/cyanogenmod/PowerWidgetUtil.java b/src/com/android/settings/cyanogenmod/PowerWidgetUtil.java
new file mode 100644
index 0000000..9dc70de
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/PowerWidgetUtil.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.settings.cyanogenmod;
+
+import com.android.internal.telephony.Phone;
+import com.android.settings.R;
+
+import android.content.Context;
+import android.net.wimax.WimaxHelper;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+/**
+ * THIS CLASS'S DATA MUST BE KEPT UP-TO-DATE WITH THE DATA IN
+ * com.android.systemui.statusbar.powerwidget.PowerWidget AND
+ * com.android.systemui.statusbar.powerwidget.PowerButton IN THE SystemUI
+ * PACKAGE.
+ */
+public class PowerWidgetUtil {
+ public static final String BUTTON_WIFI = "toggleWifi";
+ public static final String BUTTON_GPS = "toggleGPS";
+ public static final String BUTTON_BLUETOOTH = "toggleBluetooth";
+ public static final String BUTTON_BRIGHTNESS = "toggleBrightness";
+ public static final String BUTTON_SOUND = "toggleSound";
+ public static final String BUTTON_SYNC = "toggleSync";
+ public static final String BUTTON_WIFIAP = "toggleWifiAp";
+ public static final String BUTTON_SCREENTIMEOUT = "toggleScreenTimeout";
+ public static final String BUTTON_MOBILEDATA = "toggleMobileData";
+ public static final String BUTTON_LOCKSCREEN = "toggleLockScreen";
+ public static final String BUTTON_NETWORKMODE = "toggleNetworkMode";
+ public static final String BUTTON_AUTOROTATE = "toggleAutoRotate";
+ public static final String BUTTON_AIRPLANE = "toggleAirplane";
+ public static final String BUTTON_FLASHLIGHT = "toggleFlashlight";
+ public static final String BUTTON_SLEEP = "toggleSleepMode";
+ public static final String BUTTON_MEDIA_PLAY_PAUSE = "toggleMediaPlayPause";
+ public static final String BUTTON_MEDIA_PREVIOUS = "toggleMediaPrevious";
+ public static final String BUTTON_MEDIA_NEXT = "toggleMediaNext";
+ public static final String BUTTON_LTE = "toggleLte";
+ public static final String BUTTON_WIMAX = "toggleWimax";
+
+ public static final HashMap<String, ButtonInfo> BUTTONS = new HashMap<String, ButtonInfo>();
+ static {
+ BUTTONS.put(BUTTON_AIRPLANE, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_AIRPLANE, R.string.title_toggle_airplane,
+ "com.android.systemui:drawable/stat_airplane_on"));
+ BUTTONS.put(BUTTON_AUTOROTATE, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_AUTOROTATE, R.string.title_toggle_autorotate,
+ "com.android.systemui:drawable/stat_orientation_on"));
+ BUTTONS.put(BUTTON_BLUETOOTH, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_BLUETOOTH, R.string.title_toggle_bluetooth,
+ "com.android.systemui:drawable/stat_bluetooth_on"));
+ BUTTONS.put(BUTTON_BRIGHTNESS, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_BRIGHTNESS, R.string.title_toggle_brightness,
+ "com.android.systemui:drawable/stat_brightness_on"));
+ BUTTONS.put(BUTTON_FLASHLIGHT, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_FLASHLIGHT, R.string.title_toggle_flashlight,
+ "com.android.systemui:drawable/stat_flashlight_on"));
+ BUTTONS.put(BUTTON_GPS, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_GPS, R.string.title_toggle_gps, "com.android.systemui:drawable/stat_gps_on"));
+ BUTTONS.put(BUTTON_LOCKSCREEN, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_LOCKSCREEN, R.string.title_toggle_lockscreen,
+ "com.android.systemui:drawable/stat_lock_screen_on"));
+ BUTTONS.put(BUTTON_MOBILEDATA, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_MOBILEDATA, R.string.title_toggle_mobiledata,
+ "com.android.systemui:drawable/stat_data_on"));
+ BUTTONS.put(BUTTON_NETWORKMODE, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_NETWORKMODE, R.string.title_toggle_networkmode,
+ "com.android.systemui:drawable/stat_2g3g_on"));
+ BUTTONS.put(BUTTON_SCREENTIMEOUT, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_SCREENTIMEOUT, R.string.title_toggle_screentimeout,
+ "com.android.systemui:drawable/stat_screen_timeout_on"));
+ BUTTONS.put(BUTTON_SLEEP, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_SLEEP, R.string.title_toggle_sleep,
+ "com.android.systemui:drawable/stat_sleep"));
+ BUTTONS.put(BUTTON_SOUND, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_SOUND, R.string.title_toggle_sound,
+ "com.android.systemui:drawable/stat_ring_on"));
+ BUTTONS.put(BUTTON_SYNC, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_SYNC, R.string.title_toggle_sync,
+ "com.android.systemui:drawable/stat_sync_on"));
+ BUTTONS.put(BUTTON_WIFI, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_WIFI, R.string.title_toggle_wifi,
+ "com.android.systemui:drawable/stat_wifi_on"));
+ BUTTONS.put(BUTTON_WIFIAP, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_WIFIAP, R.string.title_toggle_wifiap,
+ "com.android.systemui:drawable/stat_wifi_ap_on"));
+ BUTTONS.put(BUTTON_MEDIA_PREVIOUS, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_MEDIA_PREVIOUS, R.string.title_toggle_media_previous,
+ "com.android.systemui:drawable/stat_media_previous"));
+ BUTTONS.put(BUTTON_MEDIA_PLAY_PAUSE, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_MEDIA_PLAY_PAUSE, R.string.title_toggle_media_play_pause,
+ "com.android.systemui:drawable/stat_media_play"));
+ BUTTONS.put(BUTTON_MEDIA_NEXT, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_MEDIA_NEXT, R.string.title_toggle_media_next,
+ "com.android.systemui:drawable/stat_media_next"));
+ /* Disabled until LTE support is re-added
+ if(Phone.LTE_ON_CDMA_TRUE == TelephonyManager.getDefault().getLteOnCdmaMode() ||
+ TelephonyManager.getDefault().getLteOnGsmMode() != 0) {
+ BUTTONS.put(BUTTON_LTE, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_LTE, R.string.title_toggle_lte,
+ "com.android.systemui:drawable/stat_lte_on"));
+ }*/
+ BUTTONS.put(BUTTON_WIMAX, new PowerWidgetUtil.ButtonInfo(
+ BUTTON_WIMAX, R.string.title_toggle_wimax,
+ "com.android.systemui:drawable/stat_wimax_on"));
+ }
+
+ private static final String BUTTON_DELIMITER = "|";
+ private static final String BUTTONS_DEFAULT = BUTTON_WIFI
+ + BUTTON_DELIMITER + BUTTON_BLUETOOTH
+ + BUTTON_DELIMITER + BUTTON_GPS
+ + BUTTON_DELIMITER + BUTTON_SOUND;
+
+ public static String getCurrentButtons(Context context) {
+ String buttons = Settings.System.getString(context.getContentResolver(),
+ Settings.System.WIDGET_BUTTONS);
+ if (buttons == null) {
+ buttons = BUTTONS_DEFAULT;
+ // Add the WiMAX button if it's supported
+ if (WimaxHelper.isWimaxSupported(context)) {
+ buttons += BUTTON_DELIMITER + BUTTON_WIMAX;
+ }
+ }
+ return buttons;
+ }
+
+ public static void saveCurrentButtons(Context context, String buttons) {
+ Settings.System.putString(context.getContentResolver(),
+ Settings.System.WIDGET_BUTTONS, buttons);
+ }
+
+ public static String mergeInNewButtonString(String oldString, String newString) {
+ ArrayList<String> oldList = getButtonListFromString(oldString);
+ ArrayList<String> newList = getButtonListFromString(newString);
+ ArrayList<String> mergedList = new ArrayList<String>();
+
+ // add any items from oldlist that are in new list
+ for (String button : oldList) {
+ if (newList.contains(button)) {
+ mergedList.add(button);
+ }
+ }
+
+ // append anything in newlist that isn't already in the merged list to
+ // the end of the list
+ for (String button : newList) {
+ if (!mergedList.contains(button)) {
+ mergedList.add(button);
+ }
+ }
+
+ // return merged list
+ return getButtonStringFromList(mergedList);
+ }
+
+ public static ArrayList<String> getButtonListFromString(String buttons) {
+ return new ArrayList<String>(Arrays.asList(buttons.split("\\|")));
+ }
+
+ public static String getButtonStringFromList(ArrayList<String> buttons) {
+ if (buttons == null || buttons.size() <= 0) {
+ return "";
+ } else {
+ String s = buttons.get(0);
+ for (int i = 1; i < buttons.size(); i++) {
+ s += BUTTON_DELIMITER + buttons.get(i);
+ }
+ return s;
+ }
+ }
+
+ public static class ButtonInfo {
+ private String mId;
+ private int mTitleResId;
+ private String mIcon;
+
+ public ButtonInfo(String id, int titleResId, String icon) {
+ mId = id;
+ mTitleResId = titleResId;
+ mIcon = icon;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public int getTitleResId() {
+ return mTitleResId;
+ }
+
+ public String getIcon() {
+ return mIcon;
+ }
+ }
+}
diff --git a/src/com/android/settings/cyanogenmod/SwitchWidget.java b/src/com/android/settings/cyanogenmod/SwitchWidget.java
new file mode 100644
index 0000000..d55ac71
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/SwitchWidget.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The CyanogenMod 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.settings.cyanogenmod;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import android.content.Context;
+import android.widget.CompoundButton;
+import android.widget.Switch;
+
+public class SwitchWidget implements CompoundButton.OnCheckedChangeListener {
+ public static Context mContext;
+ public Switch mSwitch;
+ public AtomicBoolean mConnected = new AtomicBoolean(false);
+
+ public boolean mStateMachineEvent;
+
+ /*
+ * public SwitchWidget(Context context, Switch switch_) { super(context,
+ * switch_); mContext = context; mSwitch = switch_; }
+ */
+ public SwitchWidget() {
+ }
+
+ public void resume() {
+ mSwitch.setOnCheckedChangeListener(this);
+ }
+
+ public void pause() {
+ mSwitch.setOnCheckedChangeListener(null);
+ }
+
+ public void setSwitch(Switch switch_) {
+ /* Stub! */
+ if (mSwitch == switch_)
+ return;
+ mSwitch.setOnCheckedChangeListener(null);
+ mSwitch = switch_;
+ mSwitch.setOnCheckedChangeListener(this);
+
+ setState(switch_);
+ }
+
+ public void setState(Switch switch_) {
+ /* Stub */
+ return;
+ }
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ /* Stub! */
+ return;
+ }
+
+ private void setSwitchChecked(boolean checked) {
+ if (checked != mSwitch.isChecked()) {
+ mStateMachineEvent = true;
+ mSwitch.setChecked(checked);
+ mStateMachineEvent = false;
+ }
+ }
+}
diff --git a/src/com/android/settings/cyanogenmod/SystemSettings.java b/src/com/android/settings/cyanogenmod/SystemSettings.java
new file mode 100644
index 0000000..44d2d96
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/SystemSettings.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2012 CyanogenMod
+ *
+ * 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.settings.cyanogenmod;
+
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+import android.view.IWindowManager;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
+
+public class SystemSettings extends SettingsPreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ private static final String TAG = "SystemSettings";
+
+ private static final String KEY_FONT_SIZE = "font_size";
+ private static final String KEY_NOTIFICATION_DRAWER = "notification_drawer";
+ private static final String KEY_NOTIFICATION_DRAWER_TABLET = "notification_drawer_tablet";
+ private static final String KEY_NAVIGATION_BAR = "navigation_bar";
+ private static final String KEY_HARDWARE_KEYS = "hardware_keys";
+
+ private PreferenceScreen mPhoneDrawer;
+ private PreferenceScreen mTabletDrawer;
+
+ private final Configuration mCurConfig = new Configuration();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.system_settings);
+
+ mPhoneDrawer = (PreferenceScreen) findPreference(KEY_NOTIFICATION_DRAWER);
+ mTabletDrawer = (PreferenceScreen) findPreference(KEY_NOTIFICATION_DRAWER_TABLET);
+
+ /*if (Utils.isTablet(getActivity())) {
+ if (mPhoneDrawer != null) {
+ getPreferenceScreen().removePreference(mPhoneDrawer);
+ }
+ } else*/ {
+ if (mTabletDrawer != null) {
+ getPreferenceScreen().removePreference(mTabletDrawer);
+ }
+ }
+
+ IWindowManager windowManager = IWindowManager.Stub.asInterface(
+ ServiceManager.getService(Context.WINDOW_SERVICE));
+ try {
+ if (!windowManager.hasNavigationBar()) {
+ Preference naviBar = findPreference(KEY_NAVIGATION_BAR);
+ if (naviBar != null) {
+ getPreferenceScreen().removePreference(naviBar);
+ }
+ } else {
+ Preference hardKeys = findPreference(KEY_HARDWARE_KEYS);
+ if (hardKeys != null) {
+ getPreferenceScreen().removePreference(hardKeys);
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ int floatToIndex(float val) {
+ String[] indices = getResources().getStringArray(R.array.entryvalues_font_size);
+ float lastVal = Float.parseFloat(indices[0]);
+ for (int i=1; i<indices.length; i++) {
+ float thisVal = Float.parseFloat(indices[i]);
+ if (val < (lastVal + (thisVal-lastVal)*.5f)) {
+ return i-1;
+ }
+ lastVal = thisVal;
+ }
+ return indices.length-1;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ updateState();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ private void updateState() {
+ }
+
+ public boolean onPreferenceChange(Preference preference, Object objValue) {
+ final String key = preference.getKey();
+
+ return true;
+ }
+}
diff --git a/src/com/android/settings/cyanogenmod/TouchInterceptor.java b/src/com/android/settings/cyanogenmod/TouchInterceptor.java
new file mode 100644
index 0000000..517df42
--- /dev/null
+++ b/src/com/android/settings/cyanogenmod/TouchInterceptor.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2008 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.settings.cyanogenmod;
+
+import com.android.settings.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.ListView;
+
+public class TouchInterceptor extends ListView {
+
+ private ImageView mDragView;
+ private WindowManager mWindowManager;
+ private WindowManager.LayoutParams mWindowParams;
+ private int mDragPos; // which item is being dragged
+ private int mFirstDragPos; // where was the dragged item originally
+ private int mDragPoint; // at what offset inside the item did the user grab
+ // it
+ private int mCoordOffset; // the difference between screen coordinates and
+ // coordinates in this view
+ private DragListener mDragListener;
+ private DropListener mDropListener;
+ private int mUpperBound;
+ private int mLowerBound;
+ private int mHeight;
+ private Rect mTempRect = new Rect();
+ private Bitmap mDragBitmap;
+ private final int mTouchSlop;
+ private int mItemHeightNormal;
+ private int mItemHeightExpanded;
+ private int mItemHeightHalf;
+
+ public TouchInterceptor(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ Resources res = getResources();
+ mItemHeightNormal = res.getDimensionPixelSize(R.dimen.normal_height);
+ mItemHeightHalf = mItemHeightNormal / 2;
+ mItemHeightExpanded = res.getDimensionPixelSize(R.dimen.expanded_height);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (mDragListener != null || mDropListener != null) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ int x = (int) ev.getX();
+ int y = (int) ev.getY();
+ int itemnum = pointToPosition(x, y);
+ if (itemnum == AdapterView.INVALID_POSITION) {
+ break;
+ }
+ ViewGroup item = (ViewGroup) getChildAt(itemnum - getFirstVisiblePosition());
+ mDragPoint = y - item.getTop();
+ mCoordOffset = ((int) ev.getRawY()) - y;
+ View dragger = item.findViewById(R.id.grabber);
+ Rect r = mTempRect;
+ dragger.getDrawingRect(r);
+ // The dragger icon itself is quite small, so pretend the
+ // touch area is bigger
+ if (x < r.right * 2) {
+ item.setDrawingCacheEnabled(true);
+ // Create a copy of the drawing cache so that it does
+ // not get recycled
+ // by the framework when the list tries to clean up
+ // memory
+ Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
+ startDragging(bitmap, y);
+ mDragPos = itemnum;
+ mFirstDragPos = mDragPos;
+ mHeight = getHeight();
+ int touchSlop = mTouchSlop;
+ mUpperBound = Math.min(y - touchSlop, mHeight / 3);
+ mLowerBound = Math.max(y + touchSlop, mHeight * 2 / 3);
+ return false;
+ }
+ stopDragging();
+ break;
+ }
+ }
+ return super.onInterceptTouchEvent(ev);
+ }
+
+ /*
+ * pointToPosition() doesn't consider invisible views, but we need to, so
+ * implement a slightly different version.
+ */
+ private int myPointToPosition(int x, int y) {
+
+ if (y < 0) {
+ // when dragging off the top of the screen, calculate position
+ // by going back from a visible item
+ int pos = myPointToPosition(x, y + mItemHeightNormal);
+ if (pos > 0) {
+ return pos - 1;
+ }
+ }
+
+ Rect frame = mTempRect;
+ final int count = getChildCount();
+ for (int i = count - 1; i >= 0; i--) {
+ final View child = getChildAt(i);
+ child.getHitRect(frame);
+ if (frame.contains(x, y)) {
+ return getFirstVisiblePosition() + i;
+ }
+ }
+ return INVALID_POSITION;
+ }
+
+ private int getItemForPosition(int y) {
+ int adjustedy = y - mDragPoint - mItemHeightHalf;
+ int pos = myPointToPosition(0, adjustedy);
+ if (pos >= 0) {
+ if (pos <= mFirstDragPos) {
+ pos += 1;
+ }
+ } else if (adjustedy < 0) {
+ // this shouldn't happen anymore now that myPointToPosition deals
+ // with this situation
+ pos = 0;
+ }
+ return pos;
+ }
+
+ private void adjustScrollBounds(int y) {
+ if (y >= mHeight / 3) {
+ mUpperBound = mHeight / 3;
+ }
+ if (y <= mHeight * 2 / 3) {
+ mLowerBound = mHeight * 2 / 3;
+ }
+ }
+
+ /*
+ * Restore size and visibility for all listitems
+ */
+ private void unExpandViews(boolean deletion) {
+ for (int i = 0;; i++) {
+ View v = getChildAt(i);
+ if (v == null) {
+ if (deletion) {
+ // HACK force update of mItemCount
+ int position = getFirstVisiblePosition();
+ int y = getChildAt(0).getTop();
+ setAdapter(getAdapter());
+ setSelectionFromTop(position, y);
+ // end hack
+ }
+ layoutChildren(); // force children to be recreated where needed
+ v = getChildAt(i);
+ if (v == null) {
+ break;
+ }
+ }
+ ViewGroup.LayoutParams params = v.getLayoutParams();
+ params.height = mItemHeightNormal;
+ v.setLayoutParams(params);
+ v.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /*
+ * Adjust visibility and size to make it appear as though an item is being
+ * dragged around and other items are making room for it: If dropping the
+ * item would result in it still being in the same place, then make the
+ * dragged listitem's size normal, but make the item invisible. Otherwise,
+ * if the dragged listitem is still on screen, make it as small as possible
+ * and expand the item below the insert point. If the dragged item is not on
+ * screen, only expand the item below the current insertpoint.
+ */
+ private void doExpansion() {
+ int childnum = mDragPos - getFirstVisiblePosition();
+ if (mDragPos > mFirstDragPos) {
+ childnum++;
+ }
+
+ View first = getChildAt(mFirstDragPos - getFirstVisiblePosition());
+
+ for (int i = 0;; i++) {
+ View vv = getChildAt(i);
+ if (vv == null) {
+ break;
+ }
+ int height = mItemHeightNormal;
+ int visibility = View.VISIBLE;
+ if (vv.equals(first)) {
+ // processing the item that is being dragged
+ if (mDragPos == mFirstDragPos) {
+ // hovering over the original location
+ visibility = View.INVISIBLE;
+ } else {
+ // not hovering over it
+ height = 1;
+ }
+ } else if (i == childnum) {
+ if (mDragPos < getCount() - 1) {
+ height = mItemHeightExpanded;
+ }
+ }
+ ViewGroup.LayoutParams params = vv.getLayoutParams();
+ params.height = height;
+ vv.setLayoutParams(params);
+ vv.setVisibility(visibility);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if ((mDragListener != null || mDropListener != null) && mDragView != null) {
+ int action = ev.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ Rect r = mTempRect;
+ mDragView.getDrawingRect(r);
+ stopDragging();
+ if (mDropListener != null && mDragPos >= 0 && mDragPos < getCount()) {
+ mDropListener.drop(mFirstDragPos, mDragPos);
+ }
+ unExpandViews(false);
+ break;
+
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ int x = (int) ev.getX();
+ int y = (int) ev.getY();
+ dragView(x, y);
+ int itemnum = getItemForPosition(y);
+ if (itemnum >= 0) {
+ if (action == MotionEvent.ACTION_DOWN || itemnum != mDragPos) {
+ if (mDragListener != null) {
+ mDragListener.drag(mDragPos, itemnum);
+ }
+ mDragPos = itemnum;
+ doExpansion();
+ }
+ int speed = 0;
+ adjustScrollBounds(y);
+ if (y > mLowerBound) {
+ // scroll the list up a bit
+ speed = y > (mHeight + mLowerBound) / 2 ? 16 : 4;
+ } else if (y < mUpperBound) {
+ // scroll the list down a bit
+ speed = y < mUpperBound / 2 ? -16 : -4;
+ }
+ if (speed != 0) {
+ int ref = pointToPosition(0, mHeight / 2);
+ if (ref == AdapterView.INVALID_POSITION) {
+ // we hit a divider or an invisible view, check
+ // somewhere else
+ ref = pointToPosition(0, mHeight / 2 + getDividerHeight() + 64);
+ }
+ View v = getChildAt(ref - getFirstVisiblePosition());
+ if (v != null) {
+ int pos = v.getTop();
+ setSelectionFromTop(ref, pos - speed);
+ }
+ }
+ }
+ break;
+ }
+ return true;
+ }
+ return super.onTouchEvent(ev);
+ }
+
+ private void startDragging(Bitmap bm, int y) {
+ stopDragging();
+
+ mWindowParams = new WindowManager.LayoutParams();
+ mWindowParams.gravity = Gravity.TOP;
+ mWindowParams.x = 0;
+ mWindowParams.y = y - mDragPoint + mCoordOffset;
+
+ mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+ mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+ mWindowParams.format = PixelFormat.TRANSLUCENT;
+ mWindowParams.windowAnimations = 0;
+
+ Context context = getContext();
+ ImageView v = new ImageView(context);
+ int backGroundColor = context.getResources().getColor(android.R.color.holo_blue_dark);
+ v.setAlpha((float) 0.7);
+ v.setBackgroundColor(backGroundColor);
+ v.setImageBitmap(bm);
+ mDragBitmap = bm;
+
+ mWindowManager = (WindowManager) context.getSystemService("window");
+ mWindowManager.addView(v, mWindowParams);
+ mDragView = v;
+ }
+
+ private void dragView(int x, int y) {
+ mWindowParams.y = y - mDragPoint + mCoordOffset;
+ mWindowManager.updateViewLayout(mDragView, mWindowParams);
+ }
+
+ private void stopDragging() {
+ if (mDragView != null) {
+ mDragView.setVisibility(GONE);
+ WindowManager wm = (WindowManager) getContext().getSystemService("window");
+ wm.removeView(mDragView);
+ mDragView.setImageDrawable(null);
+ mDragView = null;
+ }
+ if (mDragBitmap != null) {
+ mDragBitmap.recycle();
+ mDragBitmap = null;
+ }
+ }
+
+ public void setDragListener(DragListener l) {
+ mDragListener = l;
+ }
+
+ public void setDropListener(DropListener l) {
+ mDropListener = l;
+ }
+
+ public interface DragListener {
+ void drag(int from, int to);
+ }
+
+ public interface DropListener {
+ void drop(int from, int to);
+ }
+}