[2/2] OmniGears: custom button light

Change-Id: Ie296d6dbce34e73c6de5a806b297f46bed42285d
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index 5720353..a5020da 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -191,6 +191,7 @@
     <string name="battery_enable_title">Show battery</string>
 
     <string name="button_backlight_title">Button backlight</string>
+    <string name="button_backlight_summary">Configure enablement and brightness</string>
     <string name="button_backlight_on_touch_only_title">Button touch</string>
     <string name="button_backlight_on_touch_only_summary">Enable backlight with timout only on button touch</string>
     <string name="button_timeout_title">Backlight timeout</string>
diff --git a/res/xml/button_brightness_settings.xml b/res/xml/button_brightness_settings.xml
new file mode 100644
index 0000000..27f7ae2
--- /dev/null
+++ b/res/xml/button_brightness_settings.xml
@@ -0,0 +1,54 @@
+<?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"
+        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+    <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
+        android:key="button_backlight_enable"
+        android:title="@string/button_backlight_enable_title"
+        android:defaultValue="true"/>
+    <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
+        android:key="custom_button_use_screen_brightness"
+        android:title="@string/button_link_brightness"
+        android:summary="@string/button_link_brightness_summary"
+        android:defaultValue="false"
+        android:dependency="button_backlight_enable"
+        android:disableDependentsState="true" />
+    <org.omnirom.omnigears.preference.SeekBarPreference
+        android:key="button_manual_brightness_new"
+        android:title="@string/button_manual_brightness"
+        android:max="255"
+        settings:min="1"
+        android:persistent="false"
+        android:dependency="custom_button_use_screen_brightness" />
+    <org.omnirom.omnigears.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"
+        android:dependency="button_backlight_enable" />
+    <org.omnirom.omnigears.preference.SystemSettingSwitchPreference
+        android:key="button_backlight_on_touch_only"
+        android:title="@string/button_backlight_on_touch_only_title"
+        android:summary="@string/button_backlight_on_touch_only_summary"
+        android:defaultValue="false"
+        android:dependency="button_backlight_enable" />
+</PreferenceScreen>
diff --git a/res/xml/button_settings.xml b/res/xml/button_settings.xml
index 3944d82..10c0b58 100644
--- a/res/xml/button_settings.xml
+++ b/res/xml/button_settings.xml
@@ -50,6 +50,13 @@
             android:summary="@string/hardware_keys_disable_summary"
             android:persistent="false"
             android:dependency="navigation_bar_show"/>
+        <Preference
+            android:key="button_brightness"
+            android:title="@string/button_backlight_title"
+            android:summary="@string/button_backlight_summary"
+            android:persistent="false"
+            android:fragment="org.omnirom.omnigears.ButtonBrightnessSettings" />
+
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/src/org/omnirom/omnigears/ButtonBrightnessSettings.java b/src/org/omnirom/omnigears/ButtonBrightnessSettings.java
new file mode 100644
index 0000000..6ff3614
--- /dev/null
+++ b/src/org/omnirom/omnigears/ButtonBrightnessSettings.java
@@ -0,0 +1,141 @@
+/*
+ *  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;
+
+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.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.ListPreference;
+import android.support.v14.preference.SwitchPreference;
+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 org.omnirom.omnigears.preference.SeekBarPreference;
+
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+
+import java.util.List;
+import java.util.Arrays;
+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_MANUAL_BRIGHTNESS_NEW = "button_manual_brightness_new";
+    private static final String KEY_BUTTON_TIMEOUT = "button_timeout";
+
+    private IPowerManager mPowerService;
+    private SeekBarPreference mButtonTimoutBar;
+    private SeekBarPreference mManualButtonBrightness;
+
+    @Override
+    public int getMetricsCategory() {
+        return OmniDashboardFragment.ACTION_SETTINGS_OMNI;
+    }
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.button_brightness_settings);
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+        ContentResolver resolver = getContentResolver();
+
+        mManualButtonBrightness = (SeekBarPreference) findPreference(KEY_BUTTON_MANUAL_BRIGHTNESS_NEW);
+        final int customButtonBrightness = getResources().getInteger(
+                com.android.internal.R.integer.config_button_brightness_default);
+        final int currentBrightness = Settings.System.getInt(resolver,
+                Settings.System.CUSTOM_BUTTON_BRIGHTNESS, customButtonBrightness);
+        PowerManager pm = (PowerManager)getActivity().getSystemService(Context.POWER_SERVICE);
+        mManualButtonBrightness.setMaxValue(pm.getMaximumScreenBrightnessSetting());
+        mManualButtonBrightness.setValue(currentBrightness);
+        mManualButtonBrightness.setOnPreferenceChangeListener(this);
+
+        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"));
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(Preference preference) {
+        return super.onPreferenceTreeClick(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 if (preference == mManualButtonBrightness) {
+            int buttonBrightness = (Integer) objValue;
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.CUSTOM_BUTTON_BRIGHTNESS, buttonBrightness);
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * For Search.
+     */
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+
+            @Override
+            public List<SearchIndexableResource> getXmlResourcesToIndex(
+                    Context context, boolean enabled) {
+                final SearchIndexableResource sir = new SearchIndexableResource(context);
+                sir.xmlResId = R.xml.button_brightness_settings;
+                return Arrays.asList(sir);
+            }
+	};
+}
+
diff --git a/src/org/omnirom/omnigears/preference/SeekBarPreference.java b/src/org/omnirom/omnigears/preference/SeekBarPreference.java
new file mode 100644
index 0000000..5dd88ee
--- /dev/null
+++ b/src/org/omnirom/omnigears/preference/SeekBarPreference.java
@@ -0,0 +1,211 @@
+/*
+** Copyright 2013, The ChameleonOS Open Source Project
+** Copyright 2016, The OmniROM 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.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+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.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 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);
+        setLayoutResource(R.layout.seek_bar_preference);
+    }
+
+    private void setValuesFromXml(AttributeSet attrs) {
+        final TypedArray typedArray = getContext().obtainStyledAttributes(
+                      attrs, R.styleable.SeekBarPreference);
+
+        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);
+
+        Integer id = typedArray.getResourceId(R.styleable.SeekBarPreference_unitsRight, 0);
+        if (id > 0) {
+            mUnitsRight = getContext().getResources().getString(id);
+        }
+        id = typedArray.getResourceId(R.styleable.SeekBarPreference_unitsLeft, 0);
+        if (id > 0) {
+            mUnitsLeft = getContext().getResources().getString(id);
+        }
+
+        try {
+            String newInterval = attrs.getAttributeValue(SETTINGS, "interval");
+            if(newInterval != null)
+                mInterval = Integer.parseInt(newInterval);
+        } catch(Exception e) {
+            Log.e(TAG, "Invalid interval value", e);
+        }
+        typedArray.recycle();
+    }
+
+    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 (mSeekBar != null) {
+            mSeekBar.setEnabled(!disableDependent);
+        }
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        mSeekBar = (SeekBar) holder.findViewById(R.id.seekbar);
+        mSeekBar.setMax(mMaxValue - mMinValue);
+        mSeekBar.setProgress(mCurrentValue - mMinValue);
+        mSeekBar.setOnSeekBarChangeListener(this);
+        mSeekBar.setEnabled(isEnabled());
+
+        mStatusText = (TextView)holder.findViewById(R.id.seekBarPrefValue);
+        mStatusText.setText(String.valueOf(mCurrentValue));
+        mStatusText.setMinimumWidth(30);
+
+        TextView unitsRight = (TextView)holder.findViewById(R.id.seekBarPrefUnitsRight);
+        unitsRight.setText(mUnitsRight);
+        TextView unitsLeft = (TextView)holder.findViewById(R.id.seekBarPrefUnitsLeft);
+        unitsLeft.setText(mUnitsLeft);
+    }
+
+    @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;
+    }
+
+    public void setMaxValue(int value) {
+        mMaxValue = value;
+        if (mSeekBar != null) {
+            mSeekBar.setMax(mMaxValue - mMinValue);
+        }
+    }
+
+    public void setMinValue(int value) {
+        mMinValue = value;
+        if (mSeekBar != null) {
+            mSeekBar.setMax(mMaxValue - mMinValue);
+        }
+    }
+
+    @Override
+    public void setEnabled (boolean enabled) {
+        if (mSeekBar != null) {
+            mSeekBar.setEnabled(enabled);
+        }
+        super.setEnabled(enabled);
+    }
+}