[2/3] OmniGears: button backlight support

Change-Id: Iae3d1819795d7c9a35aa64a5e86233480f32f016
diff --git a/res/layout/dialog_manual_brightness.xml b/res/layout/dialog_manual_brightness.xml
new file mode 100644
index 0000000..3b0b13a
--- /dev/null
+++ b/res/layout/dialog_manual_brightness.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--  Copyright (C) 2013 The OmniROM Project
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<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_horizontal"
+        android:padding="8dip">
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="2dip">
+
+        <SeekBar android:id="@+id/backlight"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+        <EditText android:id="@+id/backlight_input"
+                android:singleLine="true"
+                android:layout_width="80dip"
+                android:layout_height="wrap_content"
+                android:numeric="integer" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index d3efcb0..bad839a 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -145,4 +145,16 @@
     <string name="led_color_green">Green</string>
     <string name="led_color_red">Red</string>
     <string name="led_color_blue">Blue</string>
+
+    <string name="button_brightness_title">Brightness</string>
+    <string name="button_brightness_summary">Button backlight brightness</string>
+    <string name="button_timeout_title">Backlight timeout</string>
+    <string name="button_timeout_summary">Disabled on value 0</string>
+    <string name="button_no_brightness">Dark mode</string>
+    <string name="button_no_brightness_summary">Don\'t set button brightness</string>
+    <string name="button_link_brightness">Link to screen</string>
+    <string name="button_link_brightness_summary">Use screen brightness level</string>
+    <string name="button_manual_brightness">Brightness level</string>
+    <string name="dialog_manual_brightness_title">Brightness level</string>
+    <string name="unit_sec">sec</string>
 </resources>
diff --git a/res/xml/button_brightness_settings.xml b/res/xml/button_brightness_settings.xml
new file mode 100644
index 0000000..9904807
--- /dev/null
+++ b/res/xml/button_brightness_settings.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--  Copyright (C) 2014 The OmniROM Project
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+        android:title="@string/button_brightness_title"
+        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+        <Preference
+                android:key="button_manual_brightness"
+                android:title="@string/button_manual_brightness" />
+        <CheckBoxPreference
+                android:key="button_no_brightness"
+                android:title="@string/button_no_brightness"
+                android:summary="@string/button_no_brightness_summary"
+                android:persistent="false"/>
+        <CheckBoxPreference
+                android:key="button_link_brightness"
+                android:title="@string/button_link_brightness"
+                android:summary="@string/button_link_brightness_summary"
+                android:persistent="false"/>
+        <com.android.settings.preference.SeekBarPreference
+                android:key="button_timeout"
+                android:title="@string/button_timeout_title"
+                android:summary="@string/button_timeout_summary"
+                android:max="30"
+                settings:min="0"
+                settings:unitsLeft=""
+                settings:unitsRight="@string/unit_sec"
+                android:persistent="false" />
+</PreferenceScreen>
diff --git a/res/xml/button_settings.xml b/res/xml/button_settings.xml
index e3ed32e..cd23ce1 100644
--- a/res/xml/button_settings.xml
+++ b/res/xml/button_settings.xml
@@ -96,14 +96,13 @@
             android:key="force_show_overflow_menu"
             android:title="@string/force_show_overflow_menu_title"
             android:summary="@string/force_show_overflow_menu_summary"
-            android:persistent="false"/>
+                android:persistent="false"/>-->
 
         <PreferenceScreen
             android:key="button_brightness"
-            android:title="@string/brightness"
+            android:title="@string/button_brightness_title"
             android:summary="@string/button_brightness_summary"
             android:fragment="org.omnirom.omnigears.brightness.ButtonBrightnessSettings" />
--->
 
         <SwitchPreference
             android:key="keys_enable_custom"
diff --git a/src/org/omnirom/omnigears/ButtonBrightnessSettings.java b/src/org/omnirom/omnigears/ButtonBrightnessSettings.java
new file mode 100644
index 0000000..3c16546
--- /dev/null
+++ b/src/org/omnirom/omnigears/ButtonBrightnessSettings.java
@@ -0,0 +1,325 @@
+/*
+ *  Copyright (C) 2014 The OmniROM Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package org.omnirom.omnigears.brightness;
+
+import com.android.settings.SettingsPreferenceFragment;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.IPowerManager;
+import android.os.ServiceManager;
+import android.preference.Preference;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.preference.ListPreference;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceCategory;
+import android.provider.Settings;
+import android.provider.SearchIndexableResource;
+import android.view.View;
+import android.util.Log;
+import android.app.AlertDialog;
+import android.text.TextWatcher;
+import android.text.Editable;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import org.omnirom.omnigears.R;
+
+import com.android.settings.preference.SeekBarPreference;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class ButtonBrightnessSettings extends SettingsPreferenceFragment implements
+        Preference.OnPreferenceChangeListener, Indexable {
+    private static final String TAG = "ButtonBrightnessSettings";
+
+    private static final String KEY_BUTTON_NO_BRIGHTNESS = "button_no_brightness";
+    private static final String KEY_BUTTON_LINK_BRIGHTNESS = "button_link_brightness";
+    private static final String KEY_BUTTON_MANUAL_BRIGHTNESS = "button_manual_brightness";
+    private static final String KEY_BUTTON_TIMEOUT = "button_timeout";
+
+    private CheckBoxPreference mNoButtonBrightness;
+    private CheckBoxPreference mLinkButtonBrightness;
+    private Preference mManualButtonBrightness;
+    private ManualButtonBrightnessDialog mManualBrightnessDialog;
+    private IPowerManager mPowerService;
+    private SeekBarPreference mButtonTimoutBar;
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.button_brightness_settings);
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+        ContentResolver resolver = getActivity().getContentResolver();
+
+        mNoButtonBrightness = (CheckBoxPreference) findPreference(KEY_BUTTON_NO_BRIGHTNESS);
+        mNoButtonBrightness.setChecked(Settings.System.getInt(resolver,
+                Settings.System.CUSTOM_BUTTON_DISABLE_BRIGHTNESS, 0) != 0);
+
+        mLinkButtonBrightness = (CheckBoxPreference) findPreference(KEY_BUTTON_LINK_BRIGHTNESS);
+        mLinkButtonBrightness.setChecked(Settings.System.getInt(resolver,
+                Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS, 0) != 0);
+
+        mManualButtonBrightness = (Preference) findPreference(KEY_BUTTON_MANUAL_BRIGHTNESS);
+
+        mButtonTimoutBar = (SeekBarPreference) findPreference(KEY_BUTTON_TIMEOUT);
+        int currentTimeout = Settings.System.getInt(resolver,
+                        Settings.System.BUTTON_BACKLIGHT_TIMEOUT, 0);
+        mButtonTimoutBar.setValue(currentTimeout);
+        mButtonTimoutBar.setOnPreferenceChangeListener(this);
+
+        mPowerService = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
+
+        updateEnablement();
+    }
+
+    private void updateEnablement() {
+        if (mNoButtonBrightness.isChecked()){
+            mLinkButtonBrightness.setEnabled(false);
+            mButtonTimoutBar.setEnabled(false);
+            mManualButtonBrightness.setEnabled(false);
+        } else if (mLinkButtonBrightness.isChecked()){
+            mNoButtonBrightness.setEnabled(false);
+            mManualButtonBrightness.setEnabled(false);
+        } else {
+            mNoButtonBrightness.setEnabled(true);
+            mLinkButtonBrightness.setEnabled(true);
+            mButtonTimoutBar.setEnabled(true);
+            mManualButtonBrightness.setEnabled(true);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        if (mManualBrightnessDialog != null) {
+            mManualBrightnessDialog.dismiss();
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mManualButtonBrightness) {
+            showButtonManualBrightnessDialog();
+            return true;
+        } else if (preference == mNoButtonBrightness) {
+            boolean checked = ((CheckBoxPreference)preference).isChecked();
+            Settings.System.putInt(getActivity().getContentResolver(),
+                    Settings.System.CUSTOM_BUTTON_DISABLE_BRIGHTNESS, checked ? 1:0);
+            updateEnablement();
+            return true;
+        } else if (preference == mLinkButtonBrightness) {
+            boolean checked = ((CheckBoxPreference)preference).isChecked();
+            Settings.System.putInt(getActivity().getContentResolver(),
+                    Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS, checked ? 1:0);
+            updateEnablement();
+            return true;
+        }
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        final String key = preference.getKey();
+
+        if (preference == mButtonTimoutBar) {
+            int buttonTimeout = (Integer) objValue;
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.BUTTON_BACKLIGHT_TIMEOUT, buttonTimeout);
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    private void showButtonManualBrightnessDialog() {
+        if (mManualBrightnessDialog != null && mManualBrightnessDialog.isShowing()) {
+            return;
+        }
+
+        mManualBrightnessDialog = new ManualButtonBrightnessDialog(getActivity());
+        mManualBrightnessDialog.show();
+    }
+
+    private class ManualButtonBrightnessDialog extends AlertDialog implements DialogInterface.OnClickListener {
+
+        private SeekBar mBacklightBar;
+        private EditText mBacklightInput;
+        private int mCurrentBrightness;
+        private boolean mIsDragging = false;
+
+        public ManualButtonBrightnessDialog(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            final View v = getLayoutInflater().inflate(R.layout.dialog_manual_brightness, null);
+            final Context context = getContext();
+
+            mBacklightBar = (SeekBar) v.findViewById(R.id.backlight);
+            mBacklightInput = (EditText) v.findViewById(R.id.backlight_input);
+
+            setTitle(R.string.dialog_manual_brightness_title);
+            setCancelable(true);
+            setView(v);
+
+            final int customButtonBrightness = getResources().getInteger(
+                    com.android.internal.R.integer.config_button_brightness_default);
+            mCurrentBrightness = Settings.System.getInt(getContext().getContentResolver(),
+                    Settings.System.CUSTOM_BUTTON_BRIGHTNESS, customButtonBrightness);
+
+            mBacklightBar.setMax(brightnessToProgress(PowerManager.BRIGHTNESS_ON));
+            mBacklightBar.setProgress(brightnessToProgress(mCurrentBrightness));
+            mBacklightInput.setText(String.valueOf(mCurrentBrightness));
+
+            initListeners();
+
+            setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.ok), this);
+            setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), this);
+
+            super.onCreate(savedInstanceState);
+        }
+
+        private int brightnessToProgress(int brightness) {
+            return brightness * 100;
+        }
+
+        private int progressToBrightness(int progress) {
+            int brightness = progress / 100;
+            return brightness;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which == DialogInterface.BUTTON_POSITIVE) {
+                try {
+                    int newBacklight = Integer.valueOf(mBacklightInput.getText().toString());
+                    Settings.System.putInt(getContext().getContentResolver(),
+                            Settings.System.CUSTOM_BUTTON_BRIGHTNESS, newBacklight);
+                } catch (NumberFormatException e) {
+                    Log.d(TAG, "NumberFormatException " + e);
+                }
+            }
+        }
+
+        private void initListeners() {
+            mBacklightBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+                @Override
+                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                    if (mIsDragging) {
+                        int brightness = progressToBrightness(seekBar.getProgress());
+                        mBacklightInput.setText(String.valueOf(brightness));
+                        try {
+                            mPowerService.setTemporaryButtonBrightnessSettingOverride(brightness);
+                        } catch(Exception e){
+                        }
+                    }
+                }
+                @Override
+                public void onStartTrackingTouch(SeekBar seekBar) {
+                    int brightness = progressToBrightness(seekBar.getProgress());
+                    try {
+                        mPowerService.setTemporaryButtonBrightnessSettingOverride(brightness);
+                    } catch(Exception e){
+                    }
+                    mIsDragging = true;
+                }
+                @Override
+                public void onStopTrackingTouch(SeekBar seekBar) {
+                    try {
+                        mPowerService.setTemporaryButtonBrightnessSettingOverride(mCurrentBrightness);
+                    } catch(Exception e){
+                    }
+                    mIsDragging = false;
+                }
+            });
+
+            mBacklightInput.addTextChangedListener(new TextWatcher() {
+                @Override
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                }
+                @Override
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                }
+                @Override
+                public void afterTextChanged(Editable s) {
+                    boolean ok = false;
+                    try {
+                        int minValue = 0;
+                        int maxValue = PowerManager.BRIGHTNESS_ON;
+                        int newBrightness = Integer.valueOf(s.toString());
+
+                        if (newBrightness >= minValue && newBrightness <= maxValue) {
+                            ok = true;
+                            mBacklightBar.setProgress(brightnessToProgress(newBrightness));
+                        }
+                    } catch (NumberFormatException e) {
+                        //ignored, ok is false ayway
+                    }
+
+                    Button okButton = mManualBrightnessDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+                    if (okButton != null) {
+                        okButton.setEnabled(ok);
+                    }
+                }
+            });
+        }
+    }
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                        boolean enabled) {
+                    ArrayList<SearchIndexableResource> result =
+                            new ArrayList<SearchIndexableResource>();
+                    boolean buttonBrightnessSupport = context.getResources().getBoolean(com.android.internal.R.bool.config_button_brightness_support);
+                    if (buttonBrightnessSupport) {
+                        SearchIndexableResource sir = new SearchIndexableResource(context);
+                        sir.xmlResId = R.xml.button_brightness_settings;
+                        result.add(sir);
+                    }
+                    return result;
+                }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    ArrayList<String> result = new ArrayList<String>();
+                    return result;
+                }
+            };
+}
+
diff --git a/src/org/omnirom/omnigears/ButtonSettings.java b/src/org/omnirom/omnigears/ButtonSettings.java
index 85fa68b..e69c1a7 100644
--- a/src/org/omnirom/omnigears/ButtonSettings.java
+++ b/src/org/omnirom/omnigears/ButtonSettings.java
@@ -101,7 +101,7 @@
 
 //    private static final String VIRTUAL_KEY_HAPTIC_FEEDBACK = "virtual_key_haptic_feedback";
 //    private static final String FORCE_SHOW_OVERFLOW_MENU = "force_show_overflow_menu";
-//    private static final String KEYS_BRIGHTNESS_KEY = "button_brightness";
+    private static final String KEYS_BRIGHTNESS_KEY = "button_brightness";
 //    private static final String KEYS_SHOW_NAVBAR_KEY = "navigation_bar_show";
 //    private static final String KEYS_DISABLE_HW_KEY = "hardware_keys_disable";
 
@@ -150,7 +150,7 @@
 //    private CheckBoxPreference mHeadsetHookLaunchVoice;
 //    private CheckBoxPreference mVirtualKeyHapticFeedback;
 //    private CheckBoxPreference mForceShowOverflowMenu;
-//    private boolean mButtonBrightnessSupport;
+    private boolean mButtonBrightnessSupport;
 //    private CheckBoxPreference mEnableNavBar;
 //    private CheckBoxPreference mDisabkeHWKeys;
     private PreferenceScreen mButtonBrightness;
@@ -175,7 +175,7 @@
         final PreferenceCategory volumeCategory =
                 (PreferenceCategory) prefScreen.findPreference(CATEGORY_VOLUME);
 
-//        mButtonBrightnessSupport = getResources().getBoolean(com.android.internal.R.bool.config_button_brightness_support);
+        mButtonBrightnessSupport = getResources().getBoolean(com.android.internal.R.bool.config_button_brightness_support);
 
         if (hasVolumeRocker()) {
             mVolumeWake = (CheckBoxPreference) findPreference(BUTTON_VOLUME_WAKE);
@@ -277,8 +277,8 @@
 //                    KEYS_SHOW_NAVBAR_KEY);
 //            mDisabkeHWKeys = (CheckBoxPreference) prefScreen.findPreference(
 //                    KEYS_DISABLE_HW_KEY);
-//            mButtonBrightness = (PreferenceScreen) prefScreen.findPreference(
-//                    KEYS_BRIGHTNESS_KEY);
+            mButtonBrightness = (PreferenceScreen) prefScreen.findPreference(
+                    KEYS_BRIGHTNESS_KEY);
 
             if (hasBackKey) {
                 int backPressAction = Settings.System.getInt(resolver,
@@ -458,9 +458,9 @@
 //                        Settings.System.HARDWARE_KEYS_DISABLE, 0) == 1;
 //            mDisabkeHWKeys.setChecked(harwareKeysDisable);
 //
-//            if (!mButtonBrightnessSupport) {
-//                keysCategory.removePreference(mButtonBrightness);
-//            }
+            if (!mButtonBrightnessSupport) {
+                keysCategory.removePreference(mButtonBrightness);
+            }
 //            updateDisableHWKeyEnablement(harwareKeysDisable);
         }