[2/4] omnigears: custom brightness support
screenshots:
http://www.mediafire.com/view/c4o6i5hfcowj2/screenies#2v66f7gy03ffqvq
PS2:
whitespace cleanup
PS3:
disabled level split and remove
I hardly believe anyone will ever need this
PS4:
moved general brightness settings from display into our fragment
string changes
PS5:
rename and license fixup
PS6:
typo
PS7:
PS6 broke the build, the ' needs to be escaped.
Change-Id: I9bb9b2d07af0726b68d2abda22e12f3b922e4aaf
diff --git a/res/layout/auto_brightness_level_setup.xml b/res/layout/auto_brightness_level_setup.xml
new file mode 100644
index 0000000..3961367
--- /dev/null
+++ b/res/layout/auto_brightness_level_setup.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<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">
+
+ <TextView android:id="@+id/lux_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dip"
+ android:text="@string/auto_brightness_lux" />
+
+ <EditText android:id="@+id/lux"
+ android:singleLine="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="2dip"
+ android:numeric="integer" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dip"
+ android:text="@string/auto_brightness_backlight" />
+
+ <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/layout/auto_brightness_list_item.xml b/res/layout/auto_brightness_list_item.xml
new file mode 100644
index 0000000..562cf08
--- /dev/null
+++ b/res/layout/auto_brightness_list_item.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012-2013 The CyanogenMod 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="wrap_content"
+ android:gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingStart="8dip"
+ android:paddingEnd="8dip"
+ android:descendantFocusability="blocksDescendants">
+
+ <TextView android:id="@+id/lux"
+ android:layout_width="50dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical" />
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <SeekBar android:id="@+id/backlight"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView android:id="@+id/backlight_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:layout_marginTop="-4dp"
+ style="?android:attr/textAppearanceSmall" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/auto_brightness_split_dialog.xml b/res/layout/auto_brightness_split_dialog.xml
new file mode 100644
index 0000000..229f172
--- /dev/null
+++ b/res/layout/auto_brightness_split_dialog.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<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">
+
+ <TextView
+ android:id="@+id/split_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dip" />
+
+ <EditText android:id="@+id/split_position"
+ android:singleLine="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="2dip"
+ android:numeric="integer" />
+
+</LinearLayout>
diff --git a/res/layout/dialog_auto_brightness_levels.xml b/res/layout/dialog_auto_brightness_levels.xml
new file mode 100644
index 0000000..ecb03b2
--- /dev/null
+++ b/res/layout/dialog_auto_brightness_levels.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2010 Daniel Nilsson
+ 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. -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:id="@+id/top_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:orientation="vertical"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="end"
+ android:dividerPadding="0dip">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layoutDirection="locale">
+
+ <TextView
+ android:id="@+id/light_sensor_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:padding="8dip" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/top_container"
+ android:layout_alignParentBottom="true" />
+
+</RelativeLayout>
diff --git a/res/layout/dialog_manual_brightness.xml b/res/layout/dialog_manual_brightness.xml
new file mode 100644
index 0000000..e1069b1
--- /dev/null
+++ b/res/layout/dialog_manual_brightness.xml
@@ -0,0 +1,49 @@
+<?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">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dip"
+ android:text="@string/auto_brightness_backlight" />
+
+ <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_arrays.xml b/res/values/custom_arrays.xml
index c4c7858..18eafe1 100644
--- a/res/values/custom_arrays.xml
+++ b/res/values/custom_arrays.xml
@@ -120,4 +120,21 @@
<item>2500</item>
<item>5000</item>
</string-array>
+
+ <!-- Auto-brightness sensitivity -->
+ <string-array name="auto_brightness_sensitivity_entries" translatable="false">
+ <item>@string/auto_brightness_sensitivity_verylow</item>
+ <item>@string/auto_brightness_sensitivity_low</item>
+ <item>@string/auto_brightness_sensitivity_medium</item>
+ <item>@string/auto_brightness_sensitivity_high</item>
+ <item>@string/auto_brightness_sensitivity_veryhigh</item>
+ </string-array>
+
+ <string-array name="auto_brightness_sensitivity_values">
+ <item>150</item>
+ <item>125</item>
+ <item>100</item>
+ <item>50</item>
+ <item>25</item>
+ </string-array>
</resources>
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
index c8293c9..f49bc2e 100644
--- a/res/values/custom_strings.xml
+++ b/res/values/custom_strings.xml
@@ -139,6 +139,54 @@
<string name="battery_light_medium_color_title">Charging</string>
<string name="battery_light_full_color_title">Fully charged</string>
+ <!-- brightness settings -->
+ <string name="brightness_settings_title">Brightness setup</string>
+ <string name="screen_current_value">Current screen value: <xliff:g id="screen_level">%d</xliff:g></string>
+ <string name="button_current_value">Current button value: <xliff:g id="button_level">%d</xliff:g></string>
+
+ <string name="auto_brightness_sensitivity_title">Adjustment sensitivity</string>
+ <string name="auto_brightness_sensitivity_summary">Medium</string>
+ <string name="auto_brightness_sensitivity_verylow">Very low</string>
+ <string name="auto_brightness_sensitivity_low">Low</string>
+ <string name="auto_brightness_sensitivity_medium">Medium</string>
+ <string name="auto_brightness_sensitivity_high">High</string>
+ <string name="auto_brightness_sensitivity_veryhigh">Very high</string>
+
+ <string name="screen_brightness_category">Screen</string>
+ <string name="screen_auto_brightness">Automatic levels</string>
+ <string name="screen_auto_brighness_summary">Screen brightness levels for automatic mode</string>
+ <string name="button_auto_brightness">Automatic levels</string>
+ <string name="button_auto_brighness_summary">Button brightness levels for automatic mode</string>
+ <string name="button_brightness_category">Buttons</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">Buttons brightness will use the same value as the screen</string>
+ <string name="button_manual_brightness">Manual level</string>
+ <string name="button_manual_brightness_summary">Button brightness level for manual mode</string>
+ <string name="dialog_manual_brightness_title">Button brightness</string>
+ <!-- Automatic brightness customization -->
+ <string name="auto_brightness_setup_title">Automatic brightness</string>
+ <string name="light_sensor_current_value">Current light sensor value: <xliff:g id="light_level">%d</xliff:g> lux</string>
+ <string name="auto_brightness_dialog_title">Automatic brightness levels</string>
+ <string name="auto_brightness_level_format"><xliff:g id="level">%1$d</xliff:g></string>
+ <string name="auto_brightness_last_level_format"><xliff:g id="level">%1$d</xliff:g>+</string>
+ <string name="auto_brightness_adjust_button">Adjust</string>
+ <string name="auto_brightness_close_button">Close</string>
+ <string name="auto_brightness_reset_button">Reset</string>
+ <string name="auto_brightness_split_dialog_title">Split brightness level</string>
+ <string name="auto_brightness_level_dialog_title">Brightness level</string>
+ <string name="auto_brightness_lux">Ambient brightness (lux)</string>
+ <string name="auto_brightness_backlight">Brightness</string>
+ <string name="auto_brightness_reset_dialog_title">Reset levels?</string>
+ <string name="auto_brightness_reset_confirmation">All brightness levels will be reset to their default settings.</string>
+ <string name="auto_brightness_split_lux_format">Split position (between <xliff:g id="min">%1$d</xliff:g> and <xliff:g id="max">%2$d</xliff:g> lux)</string>
+ <string name="auto_brightness_level_options">Light level options</string>
+ <string name="auto_brightness_menu_edit">Edit</string>
+ <string name="auto_brightness_menu_split">Split</string>
+ <string name="auto_brightness_menu_remove">Remove</string>
+ <string name="sensor_category">Sensor</string>
+
</resources>
diff --git a/res/xml/brightness_settings.xml b/res/xml/brightness_settings.xml
new file mode 100644
index 0000000..7f92c11
--- /dev/null
+++ b/res/xml/brightness_settings.xml
@@ -0,0 +1,72 @@
+<?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/>.
+ -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/brightness"
+ android:key="backlight_settings"
+ xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+ <PreferenceCategory
+ android:key="screen_brightness_category"
+ android:title="@string/screen_brightness_category">
+
+ <com.android.settings.BrightnessPreference
+ android:title="@string/brightness"
+ android:persistent="false"/>
+
+ <Preference
+ android:key="screen_auto_brightness"
+ android:title="@string/screen_auto_brightness"
+ android:summary="@string/screen_auto_brighness_summary"/>
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="button_brightness_category"
+ android:title="@string/button_brightness_category">
+
+ <CheckBoxPreference
+ android:key="button_no_brightness"
+ android:title="@string/button_no_brightness"
+ android:summary="@string/button_no_brightness_summary"/>
+ <CheckBoxPreference
+ android:key="button_link_brightness"
+ android:title="@string/button_link_brightness"
+ android:summary="@string/button_link_brightness_summary"/>
+ <Preference
+ android:key="button_auto_brightness"
+ android:title="@string/button_auto_brightness"
+ android:summary="@string/button_auto_brighness_summary"/>
+ <Preference
+ android:key="button_manual_brightness"
+ android:title="@string/button_manual_brightness"
+ android:summary="@string/button_manual_brightness_summary"/>
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="sensor_category"
+ android:title="@string/sensor_category">
+
+ <ListPreference
+ android:key="auto_brightness_sensitivity"
+ android:title="@string/auto_brightness_sensitivity_title"
+ android:summary="@string/auto_brightness_sensitivity_summary"
+ android:persistent="false"
+ android:entries="@array/auto_brightness_sensitivity_entries"
+ android:entryValues="@array/auto_brightness_sensitivity_values" />
+
+ </PreferenceCategory>
+</PreferenceScreen>
diff --git a/src/org/omnirom/omnigears/brightness/AutoBrightnessDialog.java b/src/org/omnirom/omnigears/brightness/AutoBrightnessDialog.java
new file mode 100644
index 0000000..801609f
--- /dev/null
+++ b/src/org/omnirom/omnigears/brightness/AutoBrightnessDialog.java
@@ -0,0 +1,836 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.os.IPowerManager;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.util.Spline;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.PopupMenu;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.omnirom.omnigears.R;
+
+public class AutoBrightnessDialog extends AlertDialog
+ implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+ private static final String TAG = "ScreenAutoBrightness";
+
+ private TextView mSensorLevel;
+ private ListView mConfigList;
+
+ private SensorManager mSensorManager;
+ private Sensor mLightSensor;
+
+ private static class SettingRow {
+ int lux;
+ int backlight;
+ public SettingRow(int lux, int backlight) {
+ this.lux = lux;
+ this.backlight = backlight;
+ }
+ };
+
+ private SettingRowAdapter mAdapter;
+ private int mMinLevel;
+ private boolean mIsDefault;
+
+ private AlertDialog mSetupDialog;
+ private AlertDialog mSplitDialog;
+
+ private boolean mAllowLuxEdit;
+ private String mSettingsValues;
+ private boolean mScreenMode;
+ private IPowerManager mPowerService;
+ private int mCurrentButtonBrightness;
+ private boolean mAllowLevelChange = false;
+
+ private SensorEventListener mLightSensorListener = new SensorEventListener() {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ final int lux = Math.round(event.values[0]);
+ mSensorLevel.setText(getContext().getString(R.string.light_sensor_current_value, lux));
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+ };
+
+ public AutoBrightnessDialog(Context context, boolean screenMode) {
+ super(context);
+
+ mScreenMode = screenMode;
+ if (mScreenMode){
+ mAllowLuxEdit = true;
+ mSettingsValues = Settings.System.AUTO_BRIGHTNESS_SCREEN_BACKLIGHT;
+ } else {
+ mAllowLuxEdit = false;
+ mSettingsValues = Settings.System.AUTO_BRIGHTNESS_BUTTON_BACKLIGHT;
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ final Context context = getContext();
+ View view = getLayoutInflater().inflate(R.layout.dialog_auto_brightness_levels, null);
+ setView(view);
+ setTitle(R.string.auto_brightness_dialog_title);
+ setCancelable(true);
+
+ setButton(DialogInterface.BUTTON_POSITIVE, context.getString(android.R.string.ok), this);
+ setButton(DialogInterface.BUTTON_NEUTRAL,
+ context.getString(R.string.auto_brightness_reset_button), this);
+ setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(android.R.string.cancel), this);
+
+ super.onCreate(savedInstanceState);
+
+ mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+
+ if (mScreenMode){
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mMinLevel = pm.getMinimumAbsoluteScreenBrightness();
+ } else {
+ mMinLevel = 0;
+ mPowerService = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
+ // get the current level to reset to
+ try {
+ mCurrentButtonBrightness = mPowerService.getCurrentButtonBrightnessValue();
+ } catch(Exception e){
+ }
+ }
+
+ mSensorLevel = (TextView) view.findViewById(R.id.light_sensor_value);
+
+ mConfigList = (ListView) view.findViewById(android.R.id.list);
+ mAdapter = new SettingRowAdapter(context, new ArrayList<SettingRow>());
+ mConfigList.setAdapter(mAdapter);
+
+ if (mAllowLevelChange){
+ registerForContextMenu(mConfigList);
+ } else {
+ mConfigList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+ public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
+ showSetup(position, null);
+ return true;
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void onStart() {
+ updateSettings(false);
+
+ super.onStart();
+
+ mSensorManager.registerListener(mLightSensorListener,
+ mLightSensor, SensorManager.SENSOR_DELAY_NORMAL);
+
+ Button neutralButton = getButton(DialogInterface.BUTTON_NEUTRAL);
+ neutralButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showResetConfirmation();
+ }
+ });
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mSensorManager.unregisterListener(mLightSensorListener, mLightSensor);
+ if (mSetupDialog != null) {
+ mSetupDialog.dismiss();
+ }
+ if (mSplitDialog != null) {
+ mSplitDialog.dismiss();
+ }
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+
+ menu.setHeaderTitle(R.string.auto_brightness_level_options);
+
+ menu.add(Menu.NONE, Menu.FIRST, 0, R.string.auto_brightness_menu_edit)
+ .setEnabled(!mAdapter.isLastItem(info.position));
+
+ if (mAllowLuxEdit && mAllowLevelChange){
+ menu.add(Menu.NONE, Menu.FIRST + 1, 1, R.string.auto_brightness_menu_split)
+ .setEnabled(mAdapter.canSplitRow(info.position));
+ menu.add(Menu.NONE, Menu.FIRST + 2, 2, R.string.auto_brightness_menu_remove)
+ .setEnabled(mAdapter.getCount() > 1);
+ }
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ AdapterView.AdapterContextMenuInfo info =
+ (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ int position = info.position;
+
+ switch (item.getItemId() - Menu.FIRST) {
+ case 0:
+ showSetup(position, null);
+ return true;
+ case 1:
+ showSplitDialog(position, null);
+ break;
+ case 2:
+ mAdapter.removeRow(position);
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ putSettings();
+ } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+ cancel();
+ }
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (dialog == mSetupDialog) {
+ mSetupDialog = null;
+ } else if (dialog == mSplitDialog) {
+ mSplitDialog = null;
+ }
+ }
+
+ private void updateSettings(boolean forceDefault) {
+ int[] lux = null, values = null;
+
+ if (!forceDefault) {
+ lux = fetchItems(Settings.System.AUTO_BRIGHTNESS_LUX);
+ values = fetchItems(mSettingsValues);
+ }
+
+ if (lux != null && values != null && lux.length != values.length - 1) {
+ Log.e(TAG, "Found invalid backlight settings, ignoring");
+ values = null;
+ }
+
+ if (lux == null || values == null) {
+ final Resources res = getContext().getResources();
+ lux = res.getIntArray(com.android.internal.R.array.config_autoBrightnessLevels);
+ if (mScreenMode){
+ values = res.getIntArray(com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+ } else {
+ values = res.getIntArray(com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
+ }
+ mIsDefault = true;
+ } else {
+ mIsDefault = false;
+ }
+
+ mAdapter.initFromSettings(lux, values);
+ }
+
+ private void showSetup(int position, Bundle state) {
+ if (mSetupDialog != null && mSetupDialog.isShowing()) {
+ return;
+ }
+
+ mSetupDialog = new RowSetupDialog(getContext(), position);
+ mSetupDialog.setOnDismissListener(this);
+ mSetupDialog.show();
+ }
+
+ private void showSplitDialog(final int position, Bundle state) {
+ if (mSplitDialog != null && mSplitDialog.isShowing()) {
+ return;
+ }
+
+ mSplitDialog = new RowSplitDialog(getContext(), position);
+ mSplitDialog.setOnDismissListener(this);
+ mSplitDialog.show();
+ }
+
+ private void showResetConfirmation() {
+ final AlertDialog d = new AlertDialog.Builder(getContext())
+ .setTitle(R.string.auto_brightness_reset_dialog_title)
+ .setCancelable(true)
+ .setMessage(R.string.auto_brightness_reset_confirmation)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface d, int which) {
+ updateSettings(true);
+ }
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .create();
+
+ d.show();
+ }
+
+ private void putSettings() {
+ int[] lux = null, values = null;
+
+ if (!mIsDefault) {
+ lux = mAdapter.getLuxValues();
+ values = mAdapter.getBacklightValues();
+ }
+
+ if (mAllowLuxEdit){
+ putItems(Settings.System.AUTO_BRIGHTNESS_LUX, lux);
+ }
+ putItems(mSettingsValues, values);
+ }
+
+ private int[] fetchItems(String setting) {
+ String value = Settings.System.getString(getContext().getContentResolver(), setting);
+ if (value != null) {
+ String[] values = value.split(",");
+ if (values != null && values.length != 0) {
+ int[] result = new int[values.length];
+ int i;
+
+ for (i = 0; i < values.length; i++) {
+ try {
+ result[i] = Integer.valueOf(values[i]);
+ } catch (NumberFormatException e) {
+ break;
+ }
+ }
+ if (i == values.length) {
+ return result;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private void putItems(String setting, int[] values) {
+ String value = null;
+ if (values != null) {
+ final StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < values.length; i++) {
+ if (i > 0) {
+ builder.append(",");
+ }
+ builder.append(values[i]);
+ }
+ value = builder.toString();
+ }
+ Settings.System.putString(getContext().getContentResolver(), setting, value);
+ }
+
+ private class RowSetupDialog extends AlertDialog implements DialogInterface.OnClickListener {
+
+ private EditText mLuxInput;
+ private SeekBar mBacklightBar;
+ private EditText mBacklightInput;
+ private TextView mLuxText;
+
+ private int mPosition;
+
+ public RowSetupDialog(Context context, int position) {
+ super(context);
+ mPosition = position;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ final View v = getLayoutInflater().inflate(R.layout.auto_brightness_level_setup, null);
+ final Context context = getContext();
+
+ mLuxInput = (EditText) v.findViewById(R.id.lux);
+ mLuxText = (TextView) v.findViewById(R.id.lux_text);
+
+ if (!mAllowLuxEdit){
+ mLuxInput.setVisibility(View.GONE);
+ mLuxText.setVisibility(View.GONE);
+ }
+ mBacklightBar = (SeekBar) v.findViewById(R.id.backlight);
+ mBacklightInput = (EditText) v.findViewById(R.id.backlight_input);
+
+ setTitle(R.string.auto_brightness_level_dialog_title);
+ setCancelable(true);
+ setView(v);
+
+ mBacklightBar.setMax(brightnessToProgress(PowerManager.BRIGHTNESS_ON));
+ initListeners();
+ initFromPosition();
+
+ setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.ok), this);
+ setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), this);
+
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ try {
+ int newLux = Integer.valueOf(mLuxInput.getText().toString());
+ int newBacklight = Integer.valueOf(mBacklightInput.getText().toString());
+ mAdapter.setValuesForRow(mPosition, newLux, newBacklight);
+ } catch (NumberFormatException e) {
+ Log.d(TAG, "NumberFormatException " + e);
+ }
+ }
+ }
+
+ private void initFromPosition() {
+ final SettingRow row = mAdapter.getItem(mPosition);
+
+ mLuxInput.setText(String.valueOf(row.lux));
+ mBacklightBar.setProgress(brightnessToProgress(row.backlight));
+ mBacklightInput.setText(String.valueOf(row.backlight));
+ }
+
+ private void initListeners() {
+ mBacklightBar.setOnSeekBarChangeListener(new BrightnessSeekBarChangeListener() {
+ @Override
+ protected int getPosition(SeekBar seekBar) {
+ return mPosition;
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ super.onProgressChanged(seekBar, progress, fromUser);
+
+ int brightness = progressToBrightness(seekBar.getProgress());
+ mBacklightInput.setText(String.valueOf(brightness));
+ }
+ });
+
+ 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 = mPosition == 0
+ ? mMinLevel
+ : mAdapter.getItem(mPosition - 1).backlight;
+ int maxValue = mAdapter.isLastItem(mPosition)
+ ? PowerManager.BRIGHTNESS_ON
+ : mAdapter.getItem(mPosition + 1).backlight;
+ int newBrightness = Integer.valueOf(s.toString());
+
+ if (newBrightness >= minValue && newBrightness <= maxValue) {
+ ok = true;
+ mBacklightBar.setProgress(brightnessToProgress(newBrightness));
+ }
+ } catch (NumberFormatException e) {
+ //ignored, ok is false anyway
+ }
+
+ Button okButton = mSetupDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ if (okButton != null) {
+ okButton.setEnabled(ok);
+ }
+ }
+ });
+ }
+ }
+
+ private class RowSplitDialog extends AlertDialog implements DialogInterface.OnClickListener {
+
+ private TextView mLabel;
+ private EditText mValue;
+
+ private int mPosition;
+ private int mMinLux, mMaxLux;
+
+ public RowSplitDialog(Context context, int position) {
+ super(context);
+ mPosition = position;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ final View v = getLayoutInflater().inflate(R.layout.auto_brightness_split_dialog, null);
+ final Context context = getContext();
+
+ mLabel = (TextView) v.findViewById(R.id.split_label);
+ mValue = (EditText) v.findViewById(R.id.split_position);
+
+ setTitle(R.string.auto_brightness_split_dialog_title);
+ setCancelable(true);
+ setView(v);
+
+ initValues();
+ initListener();
+
+ setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.ok), this);
+ setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), this);
+
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ int splitLux = Integer.valueOf(mValue.getText().toString());
+ mAdapter.splitRow(mPosition, splitLux);
+ }
+ }
+
+ private void initValues() {
+ final SettingRow row = mAdapter.getItem(mPosition);
+
+ mMinLux = row.lux + 1;
+ mMaxLux = mAdapter.isLastItem(mPosition) ? 0 : mAdapter.getItem(mPosition + 1).lux - 1;
+
+ mLabel.setText(getContext().getString(R.string.auto_brightness_split_lux_format,
+ mMinLux, mMaxLux));
+ mValue.setText(String.valueOf(mMinLux));
+ }
+
+ private void initListener() {
+ mValue.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 newLux = Integer.valueOf(s.toString());
+ ok = newLux >= mMinLux && newLux <= mMaxLux;
+ } catch (NumberFormatException e) {
+ //ignored, ok is false anyway
+ }
+ Button okButton = getButton(DialogInterface.BUTTON_POSITIVE);
+ if (okButton != null) {
+ okButton.setEnabled(ok);
+ }
+ }
+ });
+ }
+ }
+
+ private class SettingRowAdapter extends ArrayAdapter<SettingRow> {
+ public SettingRowAdapter(Context context, ArrayList<SettingRow> rows) {
+ super(context, 0, rows);
+ setNotifyOnChange(false);
+ }
+
+ private boolean isLastItem(int position) {
+ return position == getCount() - 1;
+ }
+
+ public boolean canSplitRow(int position) {
+ if (isLastItem(position)) {
+ return false;
+ }
+
+ SettingRow row = getItem(position);
+ SettingRow next = getItem(position + 1);
+ return next.lux > (row.lux + 1);
+ }
+
+ public void initFromSettings(int[] lux, int[] values) {
+ ArrayList<SettingRow> settings = new ArrayList<SettingRow>(values.length);
+ for (int i = 0; i < lux.length; i++) {
+ settings.add(new SettingRow(i == 0 ? 0 : lux[i - 1], values[i]));
+ }
+ settings.add(new SettingRow(lux[lux.length - 1], values[values.length - 1]));
+
+ clear();
+ addAll(settings);
+ notifyDataSetChanged();
+ }
+
+ public int[] getLuxValues() {
+ int count = getCount();
+ int[] lux = new int[count - 1];
+
+ for (int i = 1; i < count; i++) {
+ lux[i - 1] = getItem(i).lux;
+ }
+
+ return lux;
+ }
+
+ public int[] getBacklightValues() {
+ int count = getCount();
+ int[] values = new int[count];
+
+ for (int i = 0; i < count; i++) {
+ values[i] = getItem(i).backlight;
+ }
+ return values;
+ }
+
+ public void splitRow(int position, int splitLux) {
+ if (!canSplitRow(position)) {
+ return;
+ }
+
+ ArrayList<SettingRow> rows = new ArrayList<SettingRow>();
+ for (int i = 0; i <= position; i++) {
+ rows.add(getItem(i));
+ }
+
+ SettingRow lastRow = getItem(position);
+ rows.add(new SettingRow(splitLux, lastRow.backlight));
+
+ for (int i = position + 1; i < getCount(); i++) {
+ rows.add(getItem(i));
+ }
+
+ clear();
+ addAll(rows);
+ sanitizeValuesAndNotify();
+ }
+
+ public void removeRow(int position) {
+ if (getCount() <= 1) {
+ return;
+ }
+
+ remove(getItem(position));
+ sanitizeValuesAndNotify();
+ }
+
+ public void setValuesForRow(final int position, int newLux, int newBacklight) {
+ final SettingRow row = getItem(position);
+ boolean changed = false;
+
+ if (isLastItem(position)) {
+ return;
+ }
+
+ if (row.lux != newLux){
+ row.lux = newLux;
+ changed = true;
+ }
+ if (row.backlight != newBacklight){
+ row.backlight = newBacklight;
+ changed = true;
+ }
+
+ if (changed){
+ sanitizeValuesAndNotify();
+ }
+ }
+
+ public void sanitizeValuesAndNotify() {
+ final int count = getCount();
+
+ getItem(0).lux = 0;
+ for (int i = 1; i < count; i++) {
+ SettingRow lastRow = getItem(i - 1);
+ SettingRow thisRow = getItem(i);
+
+ thisRow.lux = Math.max(lastRow.lux + 1, thisRow.lux);
+ thisRow.backlight = Math.max(lastRow.backlight, thisRow.backlight);
+ }
+
+ mIsDefault = false;
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final Holder holder;
+
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(
+ R.layout.auto_brightness_list_item, parent, false);
+ holder = new Holder();
+ holder.lux = (TextView) convertView.findViewById(R.id.lux);
+ holder.backlight = (SeekBar) convertView.findViewById(R.id.backlight);
+ holder.backlightValue = (TextView) convertView.findViewById(R.id.backlight_value);
+ convertView.setTag(holder);
+
+ holder.backlight.setMax(brightnessToProgress(PowerManager.BRIGHTNESS_ON));
+ holder.backlight.setOnSeekBarChangeListener(new BrightnessSeekBarChangeListener() {
+ @Override
+ protected int getPosition(SeekBar seekBar) {
+ return (Integer) seekBar.getTag();
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ super.onProgressChanged(seekBar, progress, fromUser);
+
+ if (fromUser) {
+ int pos = getPosition(seekBar);
+ progress = seekBar.getProgress();
+ getItem(pos).backlight = progressToBrightness(progress);
+ mIsDefault = false;
+ }
+
+ holder.updateBacklight();
+ }
+ });
+ } else {
+ holder = (Holder) convertView.getTag();
+ }
+
+ SettingRow row = (SettingRow) getItem(position);
+
+ final int resId = isLastItem(position)
+ ? R.string.auto_brightness_last_level_format
+ : R.string.auto_brightness_level_format;
+
+ holder.lux.setText(getContext().getString(resId, row.lux));
+
+ holder.backlight.setTag(position);
+ holder.backlight.setProgress(brightnessToProgress(row.backlight));
+ holder.updateBacklight();
+
+ return convertView;
+ }
+
+ private class Holder {
+ TextView lux;
+ SeekBar backlight;
+ TextView backlightValue;
+
+ public void updateBacklight() {
+ backlightValue.setText(String.valueOf(progressToBrightness(backlight.getProgress())));
+ }
+ };
+ };
+
+ private int brightnessToProgress(int brightness) {
+ brightness -= mMinLevel;
+ return brightness * 100;
+ }
+
+ private int progressToBrightness(int progress) {
+ int brightness = progress / 100;
+ return brightness + mMinLevel;
+ }
+
+ private abstract class BrightnessSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
+ private boolean mIsDragging = false;
+
+ private void updateBrightness(float brightness) {
+ if (mScreenMode){
+ final Window window = getWindow();
+ final WindowManager.LayoutParams params = window.getAttributes();
+ params.screenBrightness = brightness;
+ window.setAttributes(params);
+ } else {
+ try {
+ mPowerService.setButtonBrightness((int)brightness);
+ } catch(Exception e){
+ }
+ }
+ }
+
+ protected abstract int getPosition(SeekBar seekBar);
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int pos = getPosition(seekBar);
+ if (fromUser) {
+ int minValue = pos == 0
+ ? 0
+ : brightnessToProgress(mAdapter.getItem(pos - 1).backlight);
+ int maxValue = mAdapter.isLastItem(pos)
+ ? seekBar.getMax()
+ : brightnessToProgress(mAdapter.getItem(pos + 1).backlight);
+
+ if (progress < minValue) {
+ seekBar.setProgress(minValue);
+ progress = minValue;
+ } else if (progress > maxValue) {
+ seekBar.setProgress(maxValue);
+ progress = maxValue;
+ }
+ }
+
+ if (mIsDragging) {
+ float brightness = progressToBrightness(progress);
+ if (mScreenMode){
+ updateBrightness(brightness / PowerManager.BRIGHTNESS_ON);
+ } else {
+ updateBrightness(brightness);
+ }
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ float brightness = progressToBrightness(seekBar.getProgress());
+ if (mScreenMode){
+ updateBrightness(brightness / PowerManager.BRIGHTNESS_ON);
+ } else {
+ updateBrightness(brightness);
+ }
+
+ mIsDragging = true;
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ if (mScreenMode){
+ updateBrightness(WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE);
+ } else {
+ updateBrightness(mCurrentButtonBrightness);
+ }
+
+ mIsDragging = false;
+ }
+ };
+}
diff --git a/src/org/omnirom/omnigears/brightness/BrightnessSettings.java b/src/org/omnirom/omnigears/brightness/BrightnessSettings.java
new file mode 100644
index 0000000..568742a
--- /dev/null
+++ b/src/org/omnirom/omnigears/brightness/BrightnessSettings.java
@@ -0,0 +1,343 @@
+/*
+ * 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/>.
+ *
+ */
+
+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.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 org.omnirom.omnigears.R;
+
+public class BrightnessSettings extends SettingsPreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ private static final String TAG = "BrightnessSettings";
+
+ private static final String KEY_AUTOMATIC_SENSITIVITY = "auto_brightness_sensitivity";
+ private static final String KEY_BUTTON_BRIGHTNESS_CATEGORY = "button_brightness_category";
+ 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_SCREEN_AUTO_BRIGHTNESS = "screen_auto_brightness";
+ private static final String KEY_BUTTON_AUTO_BRIGHTNESS = "button_auto_brightness";
+ private static final String KEY_BUTTON_MANUAL_BRIGHTNESS = "button_manual_brightness";
+
+ private ListPreference mAutomaticSensitivity;
+ private CheckBoxPreference mNoButtonBrightness;
+ private CheckBoxPreference mLinkButtonBrightness;
+ private Preference mAutomaticScreenBrightness;
+ private Preference mAutomaticButtonBrightness;
+ private Preference mManualButtonBrightness;
+ private AutoBrightnessDialog mScreenBrightnessDialog;
+ private AutoBrightnessDialog mButtonBrightnessDialog;
+ private ManualButtonBrightnessDialog mManualBrightnessDialog;
+ private boolean mButtonBrightnessSupport;
+ private IPowerManager mPowerService;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.brightness_settings);
+
+ PreferenceScreen prefSet = getPreferenceScreen();
+ ContentResolver resolver = getActivity().getContentResolver();
+
+ mButtonBrightnessSupport = getResources().getBoolean(com.android.internal.R.bool.config_button_brightness_support);
+
+ mAutomaticSensitivity = (ListPreference) findPreference(KEY_AUTOMATIC_SENSITIVITY);
+ float currentSensitivity = Settings.System.getFloat(resolver,
+ Settings.System.AUTO_BRIGHTNESS_RESPONSIVENESS, 1.0f);
+
+ int currentSensitivityInt = (int) (currentSensitivity * 100);
+ mAutomaticSensitivity.setValue(String.valueOf(currentSensitivityInt));
+ updateAutomaticSensityDescription(currentSensitivityInt);
+ mAutomaticSensitivity.setOnPreferenceChangeListener(this);
+
+ mAutomaticScreenBrightness = (Preference) findPreference(KEY_SCREEN_AUTO_BRIGHTNESS);
+
+ if (!mButtonBrightnessSupport){
+ removePreference(KEY_BUTTON_BRIGHTNESS_CATEGORY);
+ } else {
+ 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);
+
+ mAutomaticButtonBrightness = (Preference) findPreference(KEY_BUTTON_AUTO_BRIGHTNESS);
+ mManualButtonBrightness = (Preference) findPreference(KEY_BUTTON_MANUAL_BRIGHTNESS);
+
+ mPowerService = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ if (mScreenBrightnessDialog != null) {
+ mScreenBrightnessDialog.dismiss();
+ }
+ if (mButtonBrightnessDialog != null) {
+ mButtonBrightnessDialog.dismiss();
+ }
+ if (mManualBrightnessDialog != null) {
+ mManualBrightnessDialog.dismiss();
+ }
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ if (preference == mAutomaticScreenBrightness) {
+ showScreenAutoBrightnessDialog();
+ } else if (preference == mAutomaticButtonBrightness) {
+ showButtonAutoBrightnessDialog();
+ } else if (preference == mManualButtonBrightness) {
+ showButtonManualBrightnessDialog();
+ } else if (preference == mNoButtonBrightness) {
+ boolean checked = ((CheckBoxPreference)preference).isChecked();
+ Settings.System.putInt(getActivity().getContentResolver(),
+ Settings.System.CUSTOM_BUTTON_DISABLE_BRIGHTNESS, checked ? 1:0);
+ } else if (preference == mLinkButtonBrightness) {
+ boolean checked = ((CheckBoxPreference)preference).isChecked();
+ Settings.System.putInt(getActivity().getContentResolver(),
+ Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS, checked ? 1:0);
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object objValue) {
+ final String key = preference.getKey();
+
+ if (KEY_AUTOMATIC_SENSITIVITY.equals(key)) {
+ int value = Integer.parseInt((String) objValue);
+ float sensitivity = 0.01f * value;
+
+ Settings.System.putFloat(getContentResolver(),
+ Settings.System.AUTO_BRIGHTNESS_RESPONSIVENESS, sensitivity);
+
+ updateAutomaticSensityDescription(value);
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ private void updateAutomaticSensityDescription(int value) {
+ String[] sensitivityValues = getResources().getStringArray(
+ R.array.auto_brightness_sensitivity_values);
+
+ for (int i = 0; i < sensitivityValues.length; i++) {
+ if (sensitivityValues[i].equals(String.valueOf(value))) {
+ mAutomaticSensitivity.setSummary(getResources().getStringArray(
+ R.array.auto_brightness_sensitivity_entries)[i]);
+ break;
+ }
+ }
+ }
+
+ private void showScreenAutoBrightnessDialog() {
+ if (mScreenBrightnessDialog != null && mScreenBrightnessDialog.isShowing()) {
+ return;
+ }
+
+ mScreenBrightnessDialog = new AutoBrightnessDialog(getActivity(), true);
+ mScreenBrightnessDialog.show();
+ }
+
+ private void showButtonAutoBrightnessDialog() {
+ if (mButtonBrightnessDialog != null && mButtonBrightnessDialog.isShowing()) {
+ return;
+ }
+
+ mButtonBrightnessDialog = new AutoBrightnessDialog(getActivity(), false);
+ mButtonBrightnessDialog.show();
+ }
+
+ 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);
+
+ try {
+ mCurrentBrightness = mPowerService.getCurrentButtonBrightnessValue();
+ } catch(Exception e){
+ }
+
+ mBacklightBar.setMax(brightnessToProgress(PowerManager.BRIGHTNESS_ON));
+ initListeners();
+ init();
+
+ 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(getActivity().getContentResolver(),
+ Settings.System.CUSTOM_BUTTON_BRIGHTNESS, newBacklight);
+ } catch (NumberFormatException e) {
+ Log.d(TAG, "NumberFormatException " + e);
+ }
+ }
+ }
+
+ private void init() {
+ int currentValue = Settings.System.getInt(getActivity().getContentResolver(),
+ Settings.System.CUSTOM_BUTTON_BRIGHTNESS, 100);
+
+ mBacklightBar.setProgress(brightnessToProgress(currentValue));
+ mBacklightInput.setText(String.valueOf(currentValue));
+ }
+
+ 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.setButtonBrightness(brightness);
+ } catch(Exception e){
+ }
+ }
+ }
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ int brightness = progressToBrightness(seekBar.getProgress());
+ try {
+ mPowerService.setButtonBrightness(brightness);
+ } catch(Exception e){
+ }
+ mIsDragging = true;
+ }
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ try {
+ mPowerService.setButtonBrightness(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 anyway
+ }
+
+ Button okButton = mManualBrightnessDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ if (okButton != null) {
+ okButton.setEnabled(ok);
+ }
+ }
+ });
+ }
+ }
+}
+