[3/3] OmniGears: Add ActiveDisplay settings to menu

Active display: Add options for date and am/pm [2/2]
Change-Id: I6af47b2fd47e77398eee98cc6e30b8fcf1a44d45

Active display: Add sunlight mode. [2/2]
Change-Id: I513c2ef1555ca48dfb553f80ca687d1ca9f27c55

Active display: allow hiding low priority notifications. [2/2]
Change-Id: I244743ed1a32f59065af3c4507f4132b7d3b0d72

Active display: Allow apps to be excluded from being displayed [2/2]
Change-Id: Ieb6368c050f5b46eec7398ab0162dc4fbf00a392

Active Display: Add always show pocket mode. [2/2]
Change-Id: I6f791c5727e98749780a5e9996e20d387ed98fa6

Base: https://gerrit.omnirom.org/#/c/2679/
Settings: https://gerrit.omnirom.org/#/c/2586/

Change-Id: Ibeb35ea4321cf8ee1bdfbb1c6c1f7ab841679932
diff --git a/res/layout/ad_excluded_app_item.xml b/res/layout/ad_excluded_app_item.xml
new file mode 100644
index 0000000..7c4364e
--- /dev/null
+++ b/res/layout/ad_excluded_app_item.xml
@@ -0,0 +1,58 @@
+<?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="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal" >
+
+    <ImageView
+        android:id="@+id/app_icon"
+        android:layout_width="@android:dimen/app_icon_size"
+        android:layout_height="@android:dimen/app_icon_size"
+        android:layout_marginEnd="8dip"
+        android:layout_gravity="center_vertical"
+        android:scaleType="centerInside"
+        android:contentDescription="@null" />
+
+    <TextView
+        android:id="@+id/app_name"
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textAlignment="viewStart" />
+
+    <CheckBox android:id="@android:id/checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dip"
+        android:layout_gravity="center_vertical"
+        android:clickable="false"
+        android:focusable="false" />
+
+</LinearLayout>
diff --git a/res/layout/seek_bar_preference.xml b/res/layout/seek_bar_preference.xml
new file mode 100644
index 0000000..f7cf081
--- /dev/null
+++ b/res/layout/seek_bar_preference.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/widget_frame"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="8dp"
+    android:paddingTop="5dp"
+    android:paddingRight="10dp"
+    android:paddingBottom="5dp"
+    >
+
+    <TextView android:id="@android:id/title"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+
+    <TextView android:id="@android:id/summary"
+            android:layout_alignParentLeft="true"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorSecondary" />
+
+    <TextView android:id="@+id/seekBarPrefUnitsRight"
+            android:layout_alignParentRight="true"
+            android:layout_below="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall" />
+
+    <TextView android:id="@+id/seekBarPrefValue"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toLeftOf="@id/seekBarPrefUnitsRight"
+            android:layout_below="@android:id/title"
+            android:gravity="right"
+            android:textAppearance="?android:attr/textAppearanceSmall" />
+
+    <TextView android:id="@+id/seekBarPrefUnitsLeft"
+            android:layout_below="@android:id/title"
+            android:layout_toLeftOf="@id/seekBarPrefValue"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall" />
+
+    <LinearLayout android:id="@+id/seekBarPrefBarContainer"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentBottom="true"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/summary">
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/res/values/custom_arrays.xml b/res/values/custom_arrays.xml
index 1cafba7..af57919 100644
--- a/res/values/custom_arrays.xml
+++ b/res/values/custom_arrays.xml
@@ -123,6 +123,41 @@
         <item>9</item>
     </string-array>
 
+    <!-- ActiveDisplay Notifications -->
+    <string-array name="ad_redisplay_entries" translatable="false">
+        <item>@string/ad_redisplay_never</item>
+        <item>@string/ad_redisplay_1m</item>
+        <item>@string/ad_redisplay_5m</item>
+        <item>@string/ad_redisplay_15m</item>
+        <item>@string/ad_redisplay_30m</item>
+        <item>@string/ad_redisplay_1h</item>
+        <item>@string/ad_redisplay_2h</item>
+        <item>@string/ad_redisplay_5h</item>
+    </string-array>
+
+    <string-array name="ad_redisplay_values" translatable="false">
+        <item>0</item>
+        <item>60000</item>
+        <item>300000</item>
+        <item>900000</item>
+        <item>1800000</item>
+        <item>3600000</item>
+        <item>7200000</item>
+        <item>18000000</item>
+    </string-array>
+
+    <string-array name="ad_pocket_mode_entries" translatable="false">
+        <item>@string/ad_pocket_mode_off</item>
+        <item>@string/ad_pocket_mode_notifications</item>
+        <item>@string/ad_pocket_mode_always</item>
+    </string-array>
+
+    <string-array name="ad_pocket_mode_values" translatable="false">
+        <item>0</item>
+        <item>1</item>
+        <item>2</item>
+    </string-array>
+
     <string-array name="recent_clear_all_button_location_entries" translatable="false">
         <item>@string/recent_clear_all_button_location_top_left</item>
         <item>@string/recent_clear_all_button_location_top_right</item>
diff --git a/res/values/custom_attrs.xml b/res/values/custom_attrs.xml
new file mode 100644
index 0000000..b856986
--- /dev/null
+++ b/res/values/custom_attrs.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, The ChameleonOS Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <declare-styleable name="SeekBarPreference">
+        <attr name="min" format="integer" />
+        <attr name="unitsLeft" format="string" />
+        <attr name="unitsRight" format="string" />
+    </declare-styleable>
+
+</resources>
\ No newline at end of file
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index c9ee678..ce949ee 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -22,6 +22,7 @@
     <string name="reset">Reset</string>
 
     <string name="bars_and_menus_settings">Bars and menus</string>
+    <string name="active_display_settings">ActiveDisplay</string>
     <string name="bars_and_menus_category_status_bar_title">Status bar</string>
     <string name="status_bar_battery_title">Battery style</string>
     <string name="status_bar_toggle_brightness">Brightness control</string>
@@ -198,6 +199,44 @@
     <string name="dialog_no_home_key_title">No home action</string>
     <string name="no_home_key">You have no button assigned to the \"Home\" action! This can make your device unusable!</string>
 
+    <!-- Active Display Notifications -->
+    <string name="ad_settings_title">Active display</string>
+    <string name="ad_settings_summary">Change active display settings</string>
+    <string name="ad_enable_title">Enable</string>
+    <string name="ad_enable_summary_on">Active display enabled</string>
+    <string name="ad_enable_summary_off">Active display disabled</string>
+    <string name="ad_text_title">Notification text</string>
+    <string name="ad_text_summary">Show the notification text around the ring.</string>
+    <string name="ad_all_notifications_title">All notifications</string>
+    <string name="ad_all_notifications_summary">Show all notifications including ongoing, non-clearable notifications.</string>
+    <string name="ad_hide_low_priority_title">Hide low priority</string>
+    <string name="ad_hide_low_priority_title">Hide low priority</string>
+    <string name="ad_hide_low_priority_summary">Hide low priority notifications such as those from Google Now.</string>
+    <string name="ad_pocket_mode_title">Pocket mode</string>
+    <string name="ad_pocket_mode_summary">Show active display notifications when you take the device out of your pocket.</string>
+    <string name="ad_redisplay_title">Redisplay notifications</string>
+    <string name="ad_brightness_title">Notification brightness</string>
+    <string name="ad_customizations_title">Customizations</string>
+    <string name="ad_excluded_apps_title">Excluded applications</string>
+    <string name="ad_excluded_apps_summary">Excluded applications will not show up in active display.</string>
+    <string name="ad_show_date_title">Show date</string>
+    <string name="ad_show_ampm_title">Show AM/PM</string>
+    <string name="ad_sunlight_mode_title">Sunlight mode</string>
+    <string name="ad_brightness_summary">Brightness level for displaying notifications when automatic brightness is not enabled.</string>
+    <string name="ad_show_date_summary">Show the date above the clock</string>
+    <string name="ad_show_ampm_summary">Show AM/PM indicator next to time when using 12hour format</string>
+    <string name="ad_sunlight_mode_summary">Invert the colors when in areas with bright light such as direct sunlight.</string>
+    <string name="ad_redisplay_never">Never</string>
+    <string name="ad_redisplay_1m">1 minute</string>
+    <string name="ad_redisplay_5m">5 minutes</string>
+    <string name="ad_redisplay_15m">15 minutes</string>
+    <string name="ad_redisplay_30m">30 minutes</string>
+    <string name="ad_redisplay_1h">1 hour</string>
+    <string name="ad_redisplay_2h">2 hours</string>
+    <string name="ad_redisplay_5h">5 hours</string>
+    <string name="ad_pocket_mode_off">Off</string>
+    <string name="ad_pocket_mode_notifications">Notifications only</string>
+    <string name="ad_pocket_mode_always">Always</string>
     <string name="bars_and_menus_category_recent_panel_title" >Recents menu</string>
 
     <!--  Recents clear all -->
diff --git a/res/xml/active_display_settings.xml b/res/xml/active_display_settings.xml
new file mode 100644
index 0000000..2f55c2f
--- /dev/null
+++ b/res/xml/active_display_settings.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The ChameleonOS 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"
+    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+    android:title="@string/ad_settings_title" >
+
+    <SwitchPreference
+        android:key="ad_enable"
+        android:persistent="false"
+        android:title="@string/ad_enable_title"
+        android:summaryOff="@string/ad_enable_summary_off"
+        android:summaryOn="@string/ad_enable_summary_on" />
+
+    <CheckBoxPreference
+        android:key="ad_text"
+        android:persistent="false"
+        android:title="@string/ad_text_title"
+        android:summary="@string/ad_text_summary"
+        android:dependency="ad_enable"/>
+
+    <CheckBoxPreference
+        android:key="ad_all_notifications"
+        android:persistent="false"
+        android:title="@string/ad_all_notifications_title"
+        android:summary="@string/ad_all_notifications_summary"
+        android:dependency="ad_enable"/>
+
+    <CheckBoxPreference
+        android:key="ad_hide_low_priority"
+        android:persistent="false"
+        android:title="@string/ad_hide_low_priority_title"
+        android:summary="@string/ad_hide_low_priority_summary"
+        android:dependency="ad_enable"/>
+
+    <ListPreference
+        android:key="ad_pocket_mode"
+        android:persistent="false"
+        android:title="@string/ad_pocket_mode_title"
+        android:summary="@string/ad_pocket_mode_summary"
+        android:entries="@array/ad_pocket_mode_entries"
+        android:entryValues="@array/ad_pocket_mode_values"
+        android:dependency="ad_enable"/>
+
+    <CheckBoxPreference
+        android:key="ad_sunlight_mode"
+        android:persistent="false"
+        android:title="@string/ad_sunlight_mode_title"
+        android:summary="@string/ad_sunlight_mode_summary"
+        android:dependency="ad_enable"/>
+
+    <ListPreference
+        android:key="ad_redisplay"
+        android:persistent="false"
+        android:dialogTitle="@string/ad_redisplay_title"
+        android:title="@string/ad_redisplay_title"
+        android:entries="@array/ad_redisplay_entries"
+        android:entryValues="@array/ad_redisplay_values"
+        android:dependency="ad_enable"/>
+
+    <PreferenceCategory
+        android:key="ad_customizations"
+        android:title="@string/ad_customizations_title" />
+
+        <org.omnirom.omnigears.chameleonos.AppMultiSelectListPreference
+            android:key="ad_excluded_apps"
+            android:persistent="false"
+            android:title="@string/ad_excluded_apps_title"
+            android:summary="@string/ad_excluded_apps_summary"
+            android:dependency="ad_enable" />
+
+        <CheckBoxPreference
+            android:key="ad_show_date"
+            android:persistent="false"
+            android:title="@string/ad_show_date_title"
+            android:summary="@string/ad_show_date_summary"
+            android:dependency="ad_enable"/>
+
+        <CheckBoxPreference
+            android:key="ad_show_ampm"
+            android:persistent="false"
+            android:title="@string/ad_show_ampm_title"
+            android:summary="@string/ad_show_ampm_summary"
+            android:dependency="ad_enable"/>
+
+        <org.omnirom.omnigears.chameleonos.SeekBarPreference
+            android:key="ad_brightness"
+            android:persistent="false"
+            android:title="@string/ad_brightness_title"
+            android:summary="@string/ad_brightness_summary"
+            android:max="100"
+            settings:min="0"
+            settings:unitsLeft=""
+            settings:unitsRight="%"
+            android:defaultValue="100"
+            android:dependency="ad_enable" />
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/src/org/omnirom/omnigears/chameleonos/ActiveDisplaySettings.java b/src/org/omnirom/omnigears/chameleonos/ActiveDisplaySettings.java
new file mode 100644
index 0000000..f758881
--- /dev/null
+++ b/src/org/omnirom/omnigears/chameleonos/ActiveDisplaySettings.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2013 The ChameleonOS 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 org.omnirom.omnigears.chameleonos;
+
+import android.content.Context;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+import android.provider.Settings;
+import android.text.TextUtils;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static android.hardware.Sensor.TYPE_LIGHT;
+import static android.hardware.Sensor.TYPE_PROXIMITY;
+
+public class ActiveDisplaySettings extends SettingsPreferenceFragment implements
+        OnPreferenceChangeListener {
+    private static final String TAG = "ActiveDisplaySettings";
+
+    private static final String KEY_ENABLED = "ad_enable";
+    private static final String KEY_SHOW_TEXT = "ad_text";
+    private static final String KEY_ALL_NOTIFICATIONS = "ad_all_notifications";
+    private static final String KEY_HIDE_LOW_PRIORITY = "ad_hide_low_priority";
+    private static final String KEY_POCKET_MODE = "ad_pocket_mode";
+    private static final String KEY_SUNLIGHT_MODE = "ad_sunlight_mode";
+    private static final String KEY_REDISPLAY = "ad_redisplay";
+    private static final String KEY_EXCLUDED_APPS = "ad_excluded_apps";
+    private static final String KEY_SHOW_DATE = "ad_show_date";
+    private static final String KEY_SHOW_AMPM = "ad_show_ampm";
+    private static final String KEY_BRIGHTNESS = "ad_brightness";
+
+    private SwitchPreference mEnabledPref;
+    private CheckBoxPreference mShowTextPref;
+    private CheckBoxPreference mAllNotificationsPref;
+    private CheckBoxPreference mHideLowPriorityPref;
+    private ListPreference mPocketModePref;
+    private CheckBoxPreference mSunlightModePref;
+    private ListPreference mRedisplayPref;
+    private AppMultiSelectListPreference mExcludedAppsPref;
+    private CheckBoxPreference mShowDatePref;
+    private CheckBoxPreference mShowAmPmPref;
+    private SeekBarPreference mBrightnessLevel;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.active_display_settings);
+
+        mEnabledPref = (SwitchPreference) findPreference(KEY_ENABLED);
+        mEnabledPref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ENABLE_ACTIVE_DISPLAY, 0) == 1));
+        mEnabledPref.setOnPreferenceChangeListener(this);
+
+        mShowTextPref = (CheckBoxPreference) findPreference(KEY_SHOW_TEXT);
+        mShowTextPref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_TEXT, 0) == 1));
+
+        mAllNotificationsPref = (CheckBoxPreference) findPreference(KEY_ALL_NOTIFICATIONS);
+        mAllNotificationsPref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_ALL_NOTIFICATIONS, 0) == 1));
+
+        mHideLowPriorityPref = (CheckBoxPreference) findPreference(KEY_HIDE_LOW_PRIORITY);
+        mHideLowPriorityPref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_HIDE_LOW_PRIORITY_NOTIFICATIONS, 0) == 1));
+
+        mPocketModePref = (ListPreference) findPreference(KEY_POCKET_MODE);
+            mPocketModePref.setOnPreferenceChangeListener(this);
+            int mode = Settings.System.getInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_POCKET_MODE, 0);
+            mPocketModePref.setValue(String.valueOf(mode));
+            updatePocketModeSummary(mode);
+        if (!hasProximitySensor()) {
+            getPreferenceScreen().removePreference(mPocketModePref);
+        }
+        mSunlightModePref = (CheckBoxPreference) findPreference(KEY_SUNLIGHT_MODE);
+        mSunlightModePref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_SUNLIGHT_MODE, 0) == 1));
+        if (!hasLightSensor()) {
+                getPreferenceScreen().removePreference(mSunlightModePref);
+        }
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+        mRedisplayPref = (ListPreference) prefSet.findPreference(KEY_REDISPLAY);
+        mRedisplayPref.setOnPreferenceChangeListener(this);
+        long timeout = Settings.System.getLong(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_REDISPLAY, 0);
+        mRedisplayPref.setValue(String.valueOf(timeout));
+        updateRedisplaySummary(timeout);
+
+        mExcludedAppsPref = (AppMultiSelectListPreference) findPreference(KEY_EXCLUDED_APPS);
+        Set<String> excludedApps = getExcludedApps();
+        if (excludedApps != null) mExcludedAppsPref.setValues(excludedApps);
+        mExcludedAppsPref.setOnPreferenceChangeListener(this);
+
+        mShowDatePref = (CheckBoxPreference) findPreference(KEY_SHOW_DATE);
+        mShowDatePref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_SHOW_DATE, 0) == 1));
+
+        mShowAmPmPref = (CheckBoxPreference) findPreference(KEY_SHOW_AMPM);
+        mShowAmPmPref.setChecked((Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_SHOW_AMPM, 0) == 1));
+
+        mBrightnessLevel = (SeekBarPreference) findPreference(KEY_BRIGHTNESS);
+        mBrightnessLevel.setValue(Settings.System.getInt(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_BRIGHTNESS, 100));
+        mBrightnessLevel.setOnPreferenceChangeListener(this);
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mRedisplayPref) {
+            int timeout = Integer.valueOf((String) newValue);
+            updateRedisplaySummary(timeout);
+            return true;
+        } else if (preference == mEnabledPref) {
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ENABLE_ACTIVE_DISPLAY,
+                    ((Boolean) newValue).booleanValue() ? 1 : 0);
+            return true;
+        } else if (preference == mPocketModePref) {
+	        int mode = Integer.valueOf((String) newValue);
+	        updatePocketModeSummary(mode);
+            return true;
+        } else if (preference == mExcludedAppsPref) {
+            storeExcludedApps((Set<String>) newValue);
+            return true;
+        } else if (preference == mBrightnessLevel) {
+            int brightness = ((Integer)newValue).intValue();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_BRIGHTNESS, brightness);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        boolean value;
+
+        if (preference == mShowTextPref) {
+            value = mShowTextPref.isChecked();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_TEXT,
+                    value ? 1 : 0);
+        } else if (preference == mAllNotificationsPref) {
+            value = mAllNotificationsPref.isChecked();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_ALL_NOTIFICATIONS,
+                    value ? 1 : 0);
+        } else if (preference == mHideLowPriorityPref) {
+            value = mHideLowPriorityPref.isChecked();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_HIDE_LOW_PRIORITY_NOTIFICATIONS,
+                    value ? 1 : 0);
+        } else if (preference == mSunlightModePref) {
+            value = mSunlightModePref.isChecked();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_SUNLIGHT_MODE,
+                    value ? 1 : 0);
+        } else if (preference == mShowDatePref) {
+            value = mShowDatePref.isChecked();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_SHOW_DATE,
+                    value ? 1 : 0);
+        } else if (preference == mShowAmPmPref) {
+            value = mShowAmPmPref.isChecked();
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.ACTIVE_DISPLAY_SHOW_AMPM,
+                    value ? 1 : 0);
+        } else {
+            return super.onPreferenceTreeClick(preferenceScreen, preference);
+        }
+
+        return true;
+    }
+
+    private void updatePocketModeSummary(int value) {
+        mPocketModePref.setSummary(
+            mPocketModePref.getEntries()[mPocketModePref.findIndexOfValue("" + value)]);
+        Settings.System.putInt(getContentResolver(),
+            Settings.System.ACTIVE_DISPLAY_POCKET_MODE, value);
+    }
+
+    private void updateRedisplaySummary(long value) {
+        mRedisplayPref.setSummary(mRedisplayPref.getEntries()[mRedisplayPref.findIndexOfValue("" + value)]);
+        Settings.System.putLong(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_REDISPLAY, value);
+    }
+
+    private boolean hasProximitySensor() {
+        SensorManager sm = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
+        return sm.getDefaultSensor(TYPE_PROXIMITY) != null;
+    }
+
+    private boolean hasLightSensor() {
+        SensorManager sm = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
+        return sm.getDefaultSensor(TYPE_LIGHT) != null;
+    }
+
+    private Set<String> getExcludedApps() {
+        String excluded = Settings.System.getString(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_EXCLUDED_APPS);
+        if (TextUtils.isEmpty(excluded))
+            return null;
+
+        return new HashSet<String>(Arrays.asList(excluded.split("\\|")));
+    }
+
+    private void storeExcludedApps(Set<String> values) {
+        StringBuilder builder = new StringBuilder();
+        String delimiter = "";
+        for (String value : values) {
+            builder.append(delimiter);
+            builder.append(value);
+            delimiter = "|";
+        }
+        Settings.System.putString(getContentResolver(),
+                Settings.System.ACTIVE_DISPLAY_EXCLUDED_APPS, builder.toString());
+    }
+}
diff --git a/src/org/omnirom/omnigears/chameleonos/AppMultiSelectListPreference.java b/src/org/omnirom/omnigears/chameleonos/AppMultiSelectListPreference.java
new file mode 100644
index 0000000..137a7fa
--- /dev/null
+++ b/src/org/omnirom/omnigears/chameleonos/AppMultiSelectListPreference.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2013 The ChameleonOS 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 org.omnirom.omnigears.chameleonos;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.android.settings.R;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A preference that lists installed applications, with icons, as a multi choice list.
+ *
+ * @author Clark Scheff
+ */
+public class AppMultiSelectListPreference extends DialogPreference {
+    private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
+    private CharSequence[] mEntries;
+    private CharSequence[] mEntryValues;
+    private Set<String> mValues = new HashSet<String>();
+    private Set<String> mNewValues = new HashSet<String>();
+    private boolean mPreferenceChanged;
+
+    public AppMultiSelectListPreference(Context context) {
+        this(context, null);
+    }
+
+    public AppMultiSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        List<ApplicationInfo> pkgs = context.getPackageManager()
+                .getInstalledApplications(PackageManager.PERMISSION_GRANTED);
+        for (int i=0; i<pkgs.size(); i++) {
+            ApplicationInfo ai = pkgs.get(i);
+            if(context.getPackageManager().getLaunchIntentForPackage(ai.packageName) == null) {
+                continue;
+            }
+            MyApplicationInfo info = new MyApplicationInfo();
+            info.info = ai;
+            info.label = info.info.loadLabel(getContext().getPackageManager()).toString();
+            mPackageInfoList.add(info);
+        }
+
+        List<CharSequence> entries = new ArrayList<CharSequence>();
+        List<CharSequence> entryValues = new ArrayList<CharSequence>();
+        Collections.sort(mPackageInfoList, sDisplayNameComparator);
+        for (MyApplicationInfo info : mPackageInfoList) {
+            entries.add(info.label);
+            entryValues.add(info.info.packageName);
+        }
+        MyApplicationInfo info = new MyApplicationInfo();
+        mEntries = new CharSequence[entries.size()];
+        mEntryValues = new CharSequence[entries.size()];
+        entries.toArray(mEntries);
+        entryValues.toArray(mEntryValues);
+    }
+
+    /**
+     * Sets the value of the key. This should contain entries in
+     * {@link #getEntryValues()}.
+     *
+     * @param values The values to set for the key.
+     */
+    public void setValues(Set<String> values) {
+        mValues.clear();
+        mValues.addAll(values);
+
+        persistStringSet(values);
+    }
+
+    /**
+     * Retrieves the current value of the key.
+     */
+    public Set<String> getValues() {
+        return mValues;
+    }
+
+    /**
+     * Returns the index of the given value (in the entry values array).
+     *
+     * @param value The value whose index should be returned.
+     * @return The index of the value, or -1 if not found.
+     */
+    public int findIndexOfValue(String value) {
+        if (value != null && mEntryValues != null) {
+            for (int i = mEntryValues.length - 1; i >= 0; i--) {
+                if (mEntryValues[i].equals(value)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+        super.onPrepareDialogBuilder(builder);
+        builder.setAdapter(new AppListAdapter(getContext()), null);
+        mNewValues.clear();
+        mNewValues.addAll(mValues);
+    }
+
+    @Override
+    protected void showDialog(Bundle state) {
+        super.showDialog(state);
+        final AlertDialog dialog = (AlertDialog) getDialog();
+        final ListView listView = dialog.getListView();
+        listView.setItemsCanFocus(false);
+        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                final AppViewHolder holder = (AppViewHolder) view.getTag();
+                final boolean isChecked = !holder.checkBox.isChecked();
+                holder.checkBox.setChecked(isChecked);
+                if (isChecked) {
+                    mPreferenceChanged |= mNewValues.add(mEntryValues[position].toString());
+                } else {
+                    mPreferenceChanged |= mNewValues.remove(mEntryValues[position].toString());
+                }
+            }
+        });
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (positiveResult && mPreferenceChanged) {
+            final Set<String> values = mNewValues;
+            if (callChangeListener(values)) {
+                setValues(values);
+            }
+        }
+        mPreferenceChanged = false;
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray a, int index) {
+        final CharSequence[] defaultValues = a.getTextArray(index);
+        final int valueCount = defaultValues.length;
+        final Set<String> result = new HashSet<String>();
+
+        for (int i = 0; i < valueCount; i++) {
+            result.add(defaultValues[i].toString());
+        }
+
+        return result;
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        setValues(restoreValue ? getPersistedStringSet(mValues) : (Set<String>) defaultValue);
+    }
+
+    class MyApplicationInfo {
+        ApplicationInfo info;
+        CharSequence label;
+    }
+
+    public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
+        private final LayoutInflater mInflater;
+
+        public AppListAdapter(Context context) {
+            super(context, 0);
+            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            addAll(mPackageInfoList);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            // A ViewHolder keeps references to children views to avoid unnecessary calls
+            // to findViewById() on each row.
+            AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
+            convertView = holder.rootView;
+            MyApplicationInfo info = getItem(position);
+            holder.appName.setText(info.label);
+            if (info.info != null) {
+                holder.appIcon.setImageDrawable(info.info.loadIcon(getContext().getPackageManager()));
+            } else {
+                holder.appIcon.setImageDrawable(null);
+            }
+            holder.checkBox.setChecked(mNewValues.contains(mEntryValues[position].toString()));
+            return convertView;
+        }
+
+        @Override
+        public MyApplicationInfo getItem(int position) {
+            return mPackageInfoList.get(position);
+        }
+    }
+
+    public static class AppViewHolder {
+        public View rootView;
+        public TextView appName;
+        public ImageView appIcon;
+        public CheckBox checkBox;
+
+        public static AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
+            if (convertView == null) {
+                convertView = inflater.inflate(R.layout.ad_excluded_app_item, null);
+
+                // Creates a ViewHolder and store references to the two children views
+                // we want to bind data to.
+                AppViewHolder holder = new AppViewHolder();
+                holder.rootView = convertView;
+                holder.appName = (TextView) convertView.findViewById(R.id.app_name);
+                holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
+                holder.checkBox = (CheckBox) convertView.findViewById(android.R.id.checkbox);
+                convertView.setTag(holder);
+                return holder;
+            } else {
+                // Get the ViewHolder back to get fast access to the TextView
+                // and the ImageView.
+                return (AppViewHolder)convertView.getTag();
+            }
+        }
+    }
+
+    private final static Comparator<MyApplicationInfo> sDisplayNameComparator
+            = new Comparator<MyApplicationInfo>() {
+        public final int
+        compare(MyApplicationInfo a, MyApplicationInfo b) {
+            return collator.compare(a.label, b.label);
+        }
+
+        private final Collator collator = Collator.getInstance();
+    };
+}
diff --git a/src/org/omnirom/omnigears/chameleonos/SeekBarPreference.java b/src/org/omnirom/omnigears/chameleonos/SeekBarPreference.java
new file mode 100644
index 0000000..1272621
--- /dev/null
+++ b/src/org/omnirom/omnigears/chameleonos/SeekBarPreference.java
@@ -0,0 +1,209 @@
+package org.omnirom.omnigears.chameleonos;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+import com.android.settings.R;
+
+public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
+
+    private final String TAG = getClass().getName();
+
+    private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
+    private static final String SETTINGS = "http://schemas.android.com/apk/res/com.android.settings";
+    private static final int DEFAULT_VALUE = 50;
+
+    private int mMaxValue      = 100;
+    private int mMinValue      = 0;
+    private int mInterval      = 1;
+    private int mCurrentValue;
+    private String mUnitsLeft  = "";
+    private String mUnitsRight = "";
+    private SeekBar mSeekBar;
+    private TextView mTitle;
+
+    private TextView mStatusText;
+
+    public SeekBarPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initPreference(context, attrs);
+    }
+
+    public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        initPreference(context, attrs);
+    }
+
+    private void initPreference(Context context, AttributeSet attrs) {
+        setValuesFromXml(attrs);
+        mSeekBar = new SeekBar(context, attrs);
+        mSeekBar.setMax(mMaxValue - mMinValue);
+        mSeekBar.setOnSeekBarChangeListener(this);
+    }
+
+    private void setValuesFromXml(AttributeSet attrs) {
+        mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100);
+        mMinValue = attrs.getAttributeIntValue(SETTINGS, "min", 0);
+        mUnitsLeft = getAttributeStringValue(attrs, SETTINGS, "unitsLeft", "");
+        String units = getAttributeStringValue(attrs, SETTINGS, "units", "");
+        mUnitsRight = getAttributeStringValue(attrs, SETTINGS, "unitsRight", units);
+        try {
+            String newInterval = attrs.getAttributeValue(SETTINGS, "interval");
+            if(newInterval != null)
+                mInterval = Integer.parseInt(newInterval);
+        }
+        catch(Exception e) {
+            Log.e(TAG, "Invalid interval value", e);
+        }
+    }
+    
+    private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) {
+        String value = attrs.getAttributeValue(namespace, name);
+        if(value == null)
+            value = defaultValue;
+        
+        return value;
+    }
+
+    @Override
+    public void onDependencyChanged(Preference dependency, boolean disableDependent) {
+        super.onDependencyChanged(dependency, disableDependent);
+        this.setShouldDisableView(true);
+        if (mTitle != null)
+            mTitle.setEnabled(!disableDependent);
+        if (mSeekBar != null)
+            mSeekBar.setEnabled(!disableDependent);
+    }
+
+    @Override
+    protected View onCreateView(ViewGroup parent){
+        
+        RelativeLayout layout =  null;
+        try {
+            LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            layout = (RelativeLayout)mInflater.inflate(R.layout.seek_bar_preference, parent, false);
+            mTitle = (TextView) layout.findViewById(android.R.id.title);
+        }
+        catch(Exception e)
+        {
+            Log.e(TAG, "Error creating seek bar preference", e);
+        }
+        return layout;
+    }
+    
+    @Override
+    public void onBindView(View view) {
+        super.onBindView(view);
+        try
+        {
+            // move our seekbar to the new view we've been given
+            ViewParent oldContainer = mSeekBar.getParent();
+            ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer);
+            
+            if (oldContainer != newContainer) {
+                // remove the seekbar from the old view
+                if (oldContainer != null) {
+                    ((ViewGroup) oldContainer).removeView(mSeekBar);
+                }
+                // remove the existing seekbar (there may not be one) and add ours
+                newContainer.removeAllViews();
+                newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT,
+                        ViewGroup.LayoutParams.WRAP_CONTENT);
+            }
+        }
+        catch(Exception ex) {
+            Log.e(TAG, "Error binding view: " + ex.toString());
+        }
+        updateView(view);
+    }
+
+    /**
+     * Update a SeekBarPreference view with our current state
+     * @param view
+     */
+    protected void updateView(View view) {
+
+        try {
+            RelativeLayout layout = (RelativeLayout)view;
+            mStatusText = (TextView)layout.findViewById(R.id.seekBarPrefValue);
+            mStatusText.setText(String.valueOf(mCurrentValue));
+            mStatusText.setMinimumWidth(30);
+            mSeekBar.setProgress(mCurrentValue - mMinValue);
+
+            TextView unitsRight = (TextView)layout.findViewById(R.id.seekBarPrefUnitsRight);
+            unitsRight.setText(mUnitsRight);
+            TextView unitsLeft = (TextView)layout.findViewById(R.id.seekBarPrefUnitsLeft);
+            unitsLeft.setText(mUnitsLeft);
+        }
+        catch(Exception e) {
+            Log.e(TAG, "Error updating seek bar preference", e);
+        }
+    }
+    
+    @Override
+    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+        int newValue = progress + mMinValue;
+        if(newValue > mMaxValue)
+            newValue = mMaxValue;
+        else if(newValue < mMinValue)
+            newValue = mMinValue;
+        else if(mInterval != 1 && newValue % mInterval != 0)
+            newValue = Math.round(((float)newValue)/mInterval)*mInterval;  
+        
+        // change rejected, revert to the previous value
+        if(!callChangeListener(newValue)){
+            seekBar.setProgress(mCurrentValue - mMinValue); 
+            return; 
+        }
+        // change accepted, store it
+        mCurrentValue = newValue;
+        mStatusText.setText(String.valueOf(newValue));
+        persistInt(newValue);
+    }
+
+    @Override
+    public void onStartTrackingTouch(SeekBar seekBar) {}
+
+    @Override
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        notifyChanged();
+    }
+
+    @Override 
+    protected Object onGetDefaultValue(TypedArray ta, int index){
+        int defaultValue = ta.getInt(index, DEFAULT_VALUE);
+        return defaultValue;
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        if(restoreValue) {
+            mCurrentValue = getPersistedInt(mCurrentValue);
+        }
+        else {
+            int temp = 0;
+            try {
+                temp = (Integer)defaultValue;
+            }
+            catch(Exception ex) {
+                Log.e(TAG, "Invalid default value: " + defaultValue.toString());
+            }
+            persistInt(temp);
+            mCurrentValue = temp;
+        }
+    }
+
+    public void setValue(int value) {
+        mCurrentValue = value;
+    }
+}
\ No newline at end of file