Merge changes Ie427a2d8,I213f1f76 into nyc-dev
* changes: SysUI Tuner: UI cleanup and grouping SysUI Tuner: Night mode v3
This commit is contained in:
@@ -211,6 +211,9 @@ public abstract class DisplayManagerInternal {
|
||||
public int dozeScreenBrightness;
|
||||
public int dozeScreenState;
|
||||
|
||||
// If true, use twilight to affect the brightness.
|
||||
public boolean useTwilight;
|
||||
|
||||
public DisplayPowerRequest() {
|
||||
policy = POLICY_BRIGHT;
|
||||
useProximitySensor = false;
|
||||
@@ -242,6 +245,7 @@ public abstract class DisplayManagerInternal {
|
||||
boostScreenBrightness = other.boostScreenBrightness;
|
||||
dozeScreenBrightness = other.dozeScreenBrightness;
|
||||
dozeScreenState = other.dozeScreenState;
|
||||
useTwilight = other.useTwilight;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -262,7 +266,8 @@ public abstract class DisplayManagerInternal {
|
||||
&& lowPowerMode == other.lowPowerMode
|
||||
&& boostScreenBrightness == other.boostScreenBrightness
|
||||
&& dozeScreenBrightness == other.dozeScreenBrightness
|
||||
&& dozeScreenState == other.dozeScreenState;
|
||||
&& dozeScreenState == other.dozeScreenState
|
||||
&& useTwilight == other.useTwilight;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -282,7 +287,8 @@ public abstract class DisplayManagerInternal {
|
||||
+ ", lowPowerMode=" + lowPowerMode
|
||||
+ ", boostScreenBrightness=" + boostScreenBrightness
|
||||
+ ", dozeScreenBrightness=" + dozeScreenBrightness
|
||||
+ ", dozeScreenState=" + Display.stateToString(dozeScreenState);
|
||||
+ ", dozeScreenState=" + Display.stateToString(dozeScreenState)
|
||||
+ ", useTwilight=" + useTwilight;
|
||||
}
|
||||
|
||||
public static String policyToString(int policy) {
|
||||
|
||||
@@ -5923,6 +5923,52 @@ public final class Settings {
|
||||
public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED =
|
||||
"camera_double_tap_power_gesture_disabled";
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Behavior of twilight on the device.
|
||||
* One of {@link #TWILIGHT_MODE_LOCKED_OFF}, {@link #TWILIGHT_MODE_LOCKED_ON}
|
||||
* or {@link #TWILIGHT_MODE_AUTO}.
|
||||
* @hide
|
||||
*/
|
||||
public static final String TWILIGHT_MODE = "twilight_mode";
|
||||
|
||||
/**
|
||||
* Twilight mode always off.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TWILIGHT_MODE_LOCKED_OFF = 0;
|
||||
|
||||
/**
|
||||
* Twilight mode always on.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TWILIGHT_MODE_LOCKED_ON = 1;
|
||||
|
||||
/**
|
||||
* Twilight mode auto.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TWILIGHT_MODE_AUTO = 2;
|
||||
|
||||
/**
|
||||
* Twilight mode auto, temporarily overriden to on.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TWILIGHT_MODE_AUTO_OVERRIDE_OFF = 3;
|
||||
|
||||
/**
|
||||
* Twilight mode auto, temporarily overriden to off.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TWILIGHT_MODE_AUTO_OVERRIDE_ON = 4;
|
||||
|
||||
/**
|
||||
* Whether brightness should automatically adjust based on twilight state.
|
||||
* @hide
|
||||
*/
|
||||
public static final String BRIGHTNESS_USE_TWILIGHT = "brightness_use_twilight";
|
||||
|
||||
/**
|
||||
* This are the settings to be backed up.
|
||||
*
|
||||
|
||||
@@ -452,6 +452,8 @@
|
||||
<protected-broadcast android:name="android.bluetooth.input.profile.action.HANDSHAKE" />
|
||||
<protected-broadcast android:name="android.bluetooth.input.profile.action.REPORT" />
|
||||
|
||||
<protected-broadcast android:name="android.intent.action.TWILIGHT_CHANGED" />
|
||||
|
||||
<!-- ====================================================================== -->
|
||||
<!-- RUNTIME PERMISSIONS -->
|
||||
<!-- ====================================================================== -->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
24
packages/SystemUI/res/drawable/ic_night_mode_disabled.xml
Normal file
24
packages/SystemUI/res/drawable/ic_night_mode_disabled.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#4DFFFFFF"
|
||||
android:pathData="M20.71,5.63l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-3.12,3.12 -1.93,-1.91 -1.41,1.41 1.42,1.42L3.0,16.25L3.0,21.0l4.75,0.0l8.92,-8.92 1.42,1.42 1.41,-1.41 -1.92,-1.92 3.12,-3.12c0.4,0.0 0.4,-1.0 0.01,-1.42zM6.92,19.0L5.0,17.08l8.06,-8.06 1.92,1.92L6.92,19.0z"/>
|
||||
</vector>
|
||||
@@ -94,11 +94,4 @@
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/apply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/color_apply" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1234,29 +1234,43 @@
|
||||
<!-- Notification: Control panel: Label for button that dismisses control panel. [CHAR LIMIT=NONE] -->
|
||||
<string name="notification_done">Done</string>
|
||||
|
||||
<!-- Label for no color transform [CHAR LIMIT=30] -->
|
||||
<string name="color_matrix_none">Normal colors</string>
|
||||
<!-- SysUI Tuner: Color and appearance screen title [CHAR LIMIT=50] -->
|
||||
<string name="color_and_appearance">Color and appearance</string>
|
||||
|
||||
<!-- Label for night color transform [CHAR LIMIT=30] -->
|
||||
<string name="color_matrix_night">Night colors</string>
|
||||
<!-- SysUI Tuner: Name of the night mode feature [CHAR LIMIT=30] -->
|
||||
<string name="night_mode">Night mode</string>
|
||||
|
||||
<!-- Label for custom color transform [CHAR LIMIT=30] -->
|
||||
<string name="color_matrix_custom">Custom colors</string>
|
||||
<!-- SysUI Tuner: Name of calibrate display dialog [CHAR LIMIT=30] -->
|
||||
<string name="calibrate_display">Calibrate display</string>
|
||||
|
||||
<!-- Label for auto color transforms [CHAR LIMIT=30] -->
|
||||
<string name="color_matrix_auto">Auto</string>
|
||||
<!-- SysUI Tuner: Summary of night mode when its on [CHAR LIMIT=NONE] -->
|
||||
<string name="night_mode_on">On</string>
|
||||
|
||||
<!-- Label for unknown color transform [CHAR LIMIT=30] -->
|
||||
<string name="color_matrix_unknown">Unknown colors</string>
|
||||
<!-- SysUI Tuner: Summary of night mode when its off [CHAR LIMIT=NONE] -->
|
||||
<string name="night_mode_off">Off</string>
|
||||
|
||||
<!-- Title for color transform [CHAR LIMIT=30] -->
|
||||
<string name="color_transform">Color modification</string>
|
||||
<!-- SysUI Tuner: Label for switch to turn on night mode automatically [CHAR LIMIT=50] -->
|
||||
<string name="turn_on_automatically">Turn on automatically</string>
|
||||
|
||||
<!-- Title for setting to show Quick Settings tile [CHAR LIMIT=60] -->
|
||||
<string name="color_matrix_show_qs">Show Quick Settings tile</string>
|
||||
<!-- SysUI Tuner: Summary for switch to turn on night mode automatically [CHAR LIMIT=NONE] -->
|
||||
<string name="turn_on_auto_summary">Switch into Night Mode as appropriate for location and time of day</string>
|
||||
|
||||
<!-- Title for switch to enable custom color transform [CHAR LIMIT=60] -->
|
||||
<string name="color_enable_custom">Enable custom transform</string>
|
||||
<!-- SysUI Tuner: Label for section controlling what night mode does [CHAR LIMIT=60] -->
|
||||
<string name="when_night_mode_on">When Night Mode is on</string>
|
||||
|
||||
<!-- SysUI Tuner: Switch controlling whether dark theme is turned on with night mode [CHAR LIMIT=45] -->
|
||||
<string name="use_dark_theme">Use dark theme for Android OS</string>
|
||||
|
||||
<!-- SysUI Tuner: Switch controlling whether tint is changed with night mode [CHAR LIMIT=45] -->
|
||||
<string name="adjust_tint">Adjust tint</string>
|
||||
|
||||
<!-- SysUI Tuner: Switch controlling whether brightness is changed with night mode [CHAR LIMIT=45] -->
|
||||
<string name="adjust_brightness">Adjust brightness</string>
|
||||
|
||||
<!-- SysUI Tuner: Disclaimer about using dark theme with night mode [CHAR LIMIT=NONE] -->
|
||||
<string name="night_mode_disclaimer">The dark theme is applied to
|
||||
core areas of Android OS that are normally displayed in a light theme,
|
||||
such as Settings and notifications.</string>
|
||||
|
||||
<!-- Button to apply settings [CHAR LIMIT=30] -->
|
||||
<string name="color_apply">Apply</string>
|
||||
@@ -1295,15 +1309,14 @@
|
||||
<string name="keyboard_shortcut_group_system_back">Back</string>
|
||||
|
||||
<!-- SysUI Tuner: Option to show full do not disturb panel in volume [CHAR LIMIT=60] -->
|
||||
<string name="tuner_full_zen_title">Show do not disturb in volume</string>
|
||||
<!-- SysUI Tuner: Summary of option to show full do not disturb panel in volume [CHAR LIMIT=NONE] -->
|
||||
<string name="tuner_full_zen_summary">Allow full control of do not disturb in the volume dialog.</string>
|
||||
<string name="tuner_full_zen_title">Show with volume controls</string>
|
||||
|
||||
<!-- SysUI Tuner: Label for screen about volume and do not disturb settings [CHAR LIMIT=60] -->
|
||||
<string name="volume_and_do_not_disturb">Volume and Do not disturb</string>
|
||||
<!-- SysUI Tuner: Label for screen about do not disturb settings [CHAR LIMIT=60] -->
|
||||
<string name="volume_and_do_not_disturb">Do not disturb</string>
|
||||
|
||||
<!-- SysUI Tuner: Switch to control volume down behavior [CHAR LIMIT=60] -->
|
||||
<string name="volume_down_silent">Enter do not disturb on volume down</string>
|
||||
<!-- SysUI Tuner: Switch to control whether volume buttons enter/exit do
|
||||
not disturb [CHAR LIMIT=60] -->
|
||||
<string name="volume_dnd_silent">Volume buttons shortcut</string>
|
||||
|
||||
<!-- SysUI Tuner: Switch to control volume up behavior [CHAR LIMIT=60] -->
|
||||
<string name="volume_up_silent">Exit do not disturb on volume up</string>
|
||||
@@ -1323,9 +1336,6 @@
|
||||
<!-- Accessibility description of headset icon [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_status_bar_headset">Headset connected</string>
|
||||
|
||||
<!-- Explanation of the status bar section of the tuner [CHAR LIMIT=NONE] -->
|
||||
<string name="tuner_status_bar_explanation">Enable or disable icons from being shown in the status bar.</string>
|
||||
|
||||
<!-- Label for quick settings tile for data saver [CHAR LIMIT=30] -->
|
||||
<string name="data_saver">Data Saver</string>
|
||||
|
||||
@@ -1338,6 +1348,9 @@
|
||||
<!-- Label for feature switch [CHAR LIMIT=30] -->
|
||||
<string name="switch_bar_on">On</string>
|
||||
|
||||
<!-- Label for feature switch [CHAR LIMIT=30] -->
|
||||
<string name="switch_bar_off">Off</string>
|
||||
|
||||
<!-- SysUI Tuner: Button that leads to the navigation bar customization screen [CHAR LIMIT=60] -->
|
||||
<string name="nav_bar">Navigation bar</string>
|
||||
|
||||
@@ -1398,4 +1411,21 @@
|
||||
<!-- Button to edit the tile ordering of quick settings [CHAR LIMIT=60] -->
|
||||
<string name="qs_edit">Edit</string>
|
||||
|
||||
<!-- SysUI Tuner: Options for how clock is displayed [CHAR LIMIT=NONE] -->
|
||||
<string name="tuner_time">Time</string>
|
||||
|
||||
<!-- SysUI Tuner: Options for how clock is displayed [CHAR LIMIT=NONE] -->
|
||||
<string-array name="clock_options">
|
||||
<item>Show hours, minutes, and seconds</item>
|
||||
<item>Show hours and minutes (default)</item>
|
||||
<item>Don\'t show this icon</item>
|
||||
</string-array>
|
||||
|
||||
<!-- SysUI Tuner: Options for how battery is displayed [CHAR LIMIT=NONE] -->
|
||||
<string-array name="battery_options">
|
||||
<item>Always show percentage</item>
|
||||
<item>Show percentage when charging (default)</item>
|
||||
<item>Don\'t show this icon</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
30
packages/SystemUI/res/xml/color_and_appearance.xml
Normal file
30
packages/SystemUI/res/xml/color_and_appearance.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:sysui="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/color_and_appearance">
|
||||
|
||||
<Preference
|
||||
android:key="night_mode"
|
||||
android:title="@string/night_mode"
|
||||
android:fragment="com.android.systemui.tuner.NightModeFragment" />
|
||||
|
||||
<com.android.systemui.tuner.CalibratePreference
|
||||
android:key="calibrate"
|
||||
android:title="@string/calibrate_display" />
|
||||
|
||||
</PreferenceScreen>
|
||||
47
packages/SystemUI/res/xml/night_mode.xml
Normal file
47
packages/SystemUI/res/xml/night_mode.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:sysui="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/night_mode">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="auto"
|
||||
android:title="@string/turn_on_automatically"
|
||||
android:summary="@string/turn_on_auto_summary" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/when_night_mode_on">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="dark_theme"
|
||||
android:title="@string/use_dark_theme" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="adjust_tint"
|
||||
android:title="@string/adjust_tint" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="adjust_brightness"
|
||||
android:title="@string/adjust_brightness" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<Preference
|
||||
android:selectable="false"
|
||||
android:summary="@string/night_mode_disclaimer" />
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -18,19 +18,10 @@
|
||||
xmlns:sysui="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/system_ui_tuner">
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="qs_show_brightness"
|
||||
android:title="@string/show_brightness"
|
||||
sysui:defValue="true" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="status_bar"
|
||||
android:title="@string/status_bar" >
|
||||
|
||||
<Preference
|
||||
android:selectable="false"
|
||||
android:summary="@string/tuner_status_bar_explanation" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="rotate"
|
||||
android:title="@string/status_bar_settings_auto_rotation" />
|
||||
@@ -91,9 +82,10 @@
|
||||
|
||||
<!-- other weird signal stuff -->
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="battery"
|
||||
android:title="@string/battery" />
|
||||
<com.android.systemui.tuner.BatteryPreference
|
||||
android:title="@string/battery"
|
||||
android:summary="%s"
|
||||
android:entries="@array/battery_options" />
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="alarm_clock"
|
||||
@@ -101,12 +93,37 @@
|
||||
|
||||
<!-- secure -->
|
||||
|
||||
<com.android.systemui.tuner.StatusBarSwitch
|
||||
android:key="clock"
|
||||
android:title="@string/clock" />
|
||||
<com.android.systemui.tuner.ClockPreference
|
||||
android:title="@string/tuner_time"
|
||||
android:summary="%s"
|
||||
android:entries="@array/clock_options" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<Preference
|
||||
android:key="color_transform"
|
||||
android:title="@string/color_and_appearance"
|
||||
android:fragment="com.android.systemui.tuner.ColorAndAppearanceFragment" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="volume_and_do_not_disturb"
|
||||
android:title="@string/volume_and_do_not_disturb">
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="sysui_show_full_zen"
|
||||
android:title="@string/tuner_full_zen_title" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="sysui_volume_down_silent,sysui_volume_up_silent"
|
||||
android:title="@string/volume_dnd_silent"
|
||||
sysui:defValue="true" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<Preference
|
||||
android:key="nav_bar"
|
||||
android:title="@string/nav_bar"
|
||||
android:fragment="com.android.systemui.tuner.NavBarTuner" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="overview"
|
||||
@@ -124,53 +141,6 @@
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="battery_pct"
|
||||
android:title="@string/show_battery_percentage"
|
||||
android:summary="@string/show_battery_percentage_summary"
|
||||
android:persistent="false" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="clock_seconds"
|
||||
android:title="@string/clock_seconds"
|
||||
android:summary="@string/clock_seconds_desc" />
|
||||
|
||||
<Preference
|
||||
android:key="demo_mode"
|
||||
android:title="@string/demo_mode"
|
||||
android:fragment="com.android.systemui.tuner.DemoModeFragment" />
|
||||
|
||||
<Preference
|
||||
android:key="color_transform"
|
||||
android:title="@string/color_transform"
|
||||
android:fragment="com.android.systemui.tuner.ColorMatrixFragment" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="volume_and_do_not_disturb"
|
||||
android:title="@string/volume_and_do_not_disturb">
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="sysui_show_full_zen"
|
||||
android:title="@string/tuner_full_zen_title"
|
||||
android:summary="@string/tuner_full_zen_summary" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="sysui_volume_down_silent"
|
||||
android:title="@string/volume_down_silent"
|
||||
sysui:defValue="true" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="sysui_volume_up_silent"
|
||||
android:title="@string/volume_up_silent"
|
||||
sysui:defValue="true" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<Preference
|
||||
android:key="nav_bar"
|
||||
android:title="@string/nav_bar"
|
||||
android:fragment="com.android.systemui.tuner.NavBarTuner" />
|
||||
|
||||
<!-- Warning, this goes last. -->
|
||||
<Preference
|
||||
android:summary="@string/tuner_persistent_warning"
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.android.systemui.statusbar.phone.ManagedProfileController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.CastController;
|
||||
import com.android.systemui.statusbar.policy.DisplayController;
|
||||
import com.android.systemui.statusbar.policy.NightModeController;
|
||||
import com.android.systemui.statusbar.policy.FlashlightController;
|
||||
import com.android.systemui.statusbar.policy.HotspotController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
@@ -400,7 +400,7 @@ public abstract class QSTile<TState extends State> implements Listenable {
|
||||
UserInfoController getUserInfoController();
|
||||
BatteryController getBatteryController();
|
||||
TileServices getTileServices();
|
||||
DisplayController getDisplayController();
|
||||
NightModeController getNightModeController();
|
||||
void removeTile(String tileSpec);
|
||||
ManagedProfileController getManagedProfileController();
|
||||
|
||||
|
||||
@@ -53,9 +53,9 @@ public class TileQueryHelper {
|
||||
}
|
||||
|
||||
private void addSystemTiles(QSTileHost host) {
|
||||
boolean hasColorMod = host.getDisplayController().isEnabled();
|
||||
boolean hasColorMod = host.getNightModeController().isEnabled();
|
||||
String possible = mContext.getString(R.string.quick_settings_tiles_default)
|
||||
+ ",hotspot,inversion,saver,work,cast" + (hasColorMod ? ",colors" : "");
|
||||
+ ",hotspot,inversion,saver,work,cast" + (hasColorMod ? ",night" : "");
|
||||
String[] possibleTiles = possible.split(",");
|
||||
final Handler qsHandler = new Handler(host.getLooper());
|
||||
final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
@@ -456,11 +456,9 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
|
||||
mContext.getString(R.string.accessibility_rotation_lock_on_landscape));
|
||||
}
|
||||
mIconController.setIconVisibility(mSlotRotate, true);
|
||||
} else {
|
||||
mIconController.setIcon(mSlotRotate, portrait
|
||||
? R.drawable.stat_sys_auto_rotate_portrait
|
||||
: R.drawable.stat_sys_auto_rotate_landscape,
|
||||
mContext.getString(R.string.accessibility_rotation_lock_off));
|
||||
mIconController.setIconVisibility(mSlotRotate, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ import com.android.systemui.qs.tiles.WorkModeTile;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.CastController;
|
||||
import com.android.systemui.statusbar.policy.DisplayController;
|
||||
import com.android.systemui.statusbar.policy.NightModeController;
|
||||
import com.android.systemui.statusbar.policy.FlashlightController;
|
||||
import com.android.systemui.statusbar.policy.HotspotController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
@@ -68,7 +68,7 @@ import com.android.systemui.statusbar.policy.SecurityController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
import com.android.systemui.tuner.ColorMatrixTile;
|
||||
import com.android.systemui.tuner.NightModeTile;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
@@ -108,7 +108,7 @@ public final class QSTileHost implements QSTile.Host, Tunable {
|
||||
private final TileServices mServices;
|
||||
|
||||
private final List<Callback> mCallbacks = new ArrayList<>();
|
||||
private final DisplayController mDisplayController;
|
||||
private final NightModeController mNightModeController;
|
||||
private final AutoTileManager mAutoTiles;
|
||||
private final ManagedProfileController mProfileController;
|
||||
private View mHeader;
|
||||
@@ -137,7 +137,7 @@ public final class QSTileHost implements QSTile.Host, Tunable {
|
||||
mSecurity = security;
|
||||
mBattery = battery;
|
||||
mIconController = iconController;
|
||||
mDisplayController = new DisplayController(mContext);
|
||||
mNightModeController = new NightModeController(mContext, true);
|
||||
mProfileController = new ManagedProfileController(this);
|
||||
|
||||
final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(),
|
||||
@@ -292,8 +292,8 @@ public final class QSTileHost implements QSTile.Host, Tunable {
|
||||
return mIconController;
|
||||
}
|
||||
|
||||
public DisplayController getDisplayController() {
|
||||
return mDisplayController;
|
||||
public NightModeController getNightModeController() {
|
||||
return mNightModeController;
|
||||
}
|
||||
|
||||
public ManagedProfileController getManagedProfileController() {
|
||||
@@ -422,8 +422,8 @@ public final class QSTileHost implements QSTile.Host, Tunable {
|
||||
else if (tileSpec.equals("user")) return new UserTile(this);
|
||||
else if (tileSpec.equals("battery")) return new BatteryTile(this);
|
||||
else if (tileSpec.equals("saver")) return new DataSaverTile(this);
|
||||
else if (tileSpec.equals(ColorMatrixTile.COLOR_MATRIX_SPEC))
|
||||
return new ColorMatrixTile(this);
|
||||
else if (tileSpec.equals(NightModeTile.NIGHT_MODE_SPEC))
|
||||
return new NightModeTile(this);
|
||||
// Intent tiles.
|
||||
else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
|
||||
else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec);
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import libcore.util.Objects;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DisplayController implements TunerService.Tunable {
|
||||
|
||||
public static final String COLOR_MATRIX_CUSTOM_ENABLED = "tuner_color_custom_enabled";
|
||||
public static final String COLOR_MATRIX_CUSTOM_VALUES = "tuner_color_custom_values";
|
||||
|
||||
public static final String COLOR_STATE = "sysui_color_matrix_state";
|
||||
|
||||
public static final int COLOR_STATE_DISABLED = 0;
|
||||
public static final int COLOR_STATE_ENABLED = 1;
|
||||
public static final int COLOR_STATE_AUTO = 2;
|
||||
|
||||
public static final String AUTO_STRING = "auto_mode";
|
||||
public static final String NONE_STRING = "none";
|
||||
|
||||
public static final int AUTO_INDEX = 2;
|
||||
public static final int CUSTOM_INDEX = 3;
|
||||
|
||||
// Night mode ~= 3400 K
|
||||
private static final float[] NIGHT_VALUES = new float[] {
|
||||
1, 0, 0, 0,
|
||||
0, .754f, 0, 0,
|
||||
0, 0, .516f, 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
public static final float[] IDENTITY_MATRIX = new float[] {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
|
||||
private final ArrayList<Listener> mListeners = new ArrayList<>();
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private String mCurrentValue;
|
||||
private boolean mListening;
|
||||
|
||||
public DisplayController(Context context) {
|
||||
mContext = context;
|
||||
TunerService.get(mContext).addTunable(this, COLOR_STATE,
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX);
|
||||
}
|
||||
|
||||
public void addListener(Listener listener) {
|
||||
mListeners.add(listener);
|
||||
listener.onCurrentMatrixChanged();
|
||||
}
|
||||
|
||||
public void removeListener(Listener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return TunerService.get(mContext).getValue(COLOR_STATE, COLOR_STATE_DISABLED)
|
||||
!= COLOR_STATE_DISABLED;
|
||||
}
|
||||
|
||||
public boolean isAuto() {
|
||||
return mListening;
|
||||
}
|
||||
|
||||
public void setAuto(boolean auto) {
|
||||
TunerService.get(mContext).setValue(COLOR_STATE, auto ? COLOR_STATE_AUTO
|
||||
: COLOR_STATE_DISABLED);
|
||||
}
|
||||
|
||||
public boolean isCustomSet() {
|
||||
return isCustomEnabled() && Objects.equal(getCurrentMatrix(), getCustomValues());
|
||||
}
|
||||
|
||||
public String getCurrentMatrix() {
|
||||
return mCurrentValue;
|
||||
}
|
||||
|
||||
public String getCustomValues() {
|
||||
return TunerService.get(mContext).getValue(COLOR_MATRIX_CUSTOM_VALUES);
|
||||
}
|
||||
|
||||
public boolean isCustomEnabled() {
|
||||
return TunerService.get(mContext).getValue(COLOR_MATRIX_CUSTOM_ENABLED, 0) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX.equals(key)) {
|
||||
mCurrentValue = newValue;
|
||||
for (int i = 0; i < mListeners.size(); i++) {
|
||||
mListeners.get(i).onCurrentMatrixChanged();
|
||||
}
|
||||
} else if (COLOR_STATE.equals(key)) {
|
||||
final boolean listening = newValue != null
|
||||
&& Integer.parseInt(newValue) == COLOR_STATE_AUTO;
|
||||
if (listening && !mListening) {
|
||||
mListening = true;
|
||||
mContext.registerReceiver(mReceiver,
|
||||
new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
|
||||
updateNightMode();
|
||||
} else if (!listening && mListening) {
|
||||
mListening = false;
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
}
|
||||
for (int i = 0; i < mListeners.size(); i++) {
|
||||
mListeners.get(i).onCurrentMatrixChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNightMode() {
|
||||
final int uiMode = mContext.getResources().getConfiguration().uiMode;
|
||||
final boolean isNightMode = (uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
||||
== Configuration.UI_MODE_NIGHT_YES;
|
||||
String value = null;
|
||||
if (isNightMode) {
|
||||
value = toString(NIGHT_VALUES);
|
||||
}
|
||||
TunerService.get(mContext).setValue(Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
|
||||
value);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
|
||||
updateNightMode();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public interface Listener {
|
||||
void onCurrentMatrixChanged();
|
||||
}
|
||||
|
||||
public static String[] getColorTransforms(Context context) {
|
||||
return new String[] {
|
||||
NONE_STRING,
|
||||
toString(NIGHT_VALUES),
|
||||
AUTO_STRING, // Blank spot for auto values
|
||||
null, // Blank spot for custom values
|
||||
};
|
||||
}
|
||||
|
||||
public static CharSequence[] getColorTitles(Context context) {
|
||||
// TODO: Move to string array resource.
|
||||
return new CharSequence[]{
|
||||
context.getString(R.string.color_matrix_none),
|
||||
context.getString(R.string.color_matrix_night),
|
||||
context.getString(R.string.color_matrix_auto),
|
||||
context.getString(R.string.color_matrix_custom),
|
||||
};
|
||||
}
|
||||
|
||||
public static String toString(float[] values) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append(values[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import libcore.util.Objects;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.opengl.Matrix;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.MathUtils;
|
||||
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Listens for changes to twilight from the TwilightService.
|
||||
*
|
||||
* Also pushes the current matrix to accessibility based on the current twilight
|
||||
* and various tuner settings.
|
||||
*/
|
||||
public class NightModeController implements TunerService.Tunable {
|
||||
|
||||
public static final String NIGHT_MODE_ADJUST_TINT = "tuner_night_mode_adjust_tint";
|
||||
private static final String COLOR_MATRIX_CUSTOM_VALUES = "tuner_color_custom_values";
|
||||
|
||||
private static final String ACTION_TWILIGHT_CHANGED = "android.intent.action.TWILIGHT_CHANGED";
|
||||
|
||||
private static final String EXTRA_IS_NIGHT = "isNight";
|
||||
private static final String EXTRA_AMOUNT = "amount";
|
||||
|
||||
// Night mode ~= 3400 K
|
||||
private static final float[] NIGHT_VALUES = new float[] {
|
||||
1, 0, 0, 0,
|
||||
0, .754f, 0, 0,
|
||||
0, 0, .516f, 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
public static final float[] IDENTITY_MATRIX = new float[] {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
|
||||
private final ArrayList<Listener> mListeners = new ArrayList<>();
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
// This is whether or not this is the main NightMode controller in SysUI that should be
|
||||
// updating relevant color matrixes or if its in the tuner process getting current state
|
||||
// for UI.
|
||||
private final boolean mUpdateMatrix;
|
||||
|
||||
private float[] mCustomMatrix;
|
||||
private boolean mListening;
|
||||
private boolean mAdjustTint;
|
||||
|
||||
private boolean mIsNight;
|
||||
private float mAmount;
|
||||
private boolean mIsAuto;
|
||||
|
||||
public NightModeController(Context context) {
|
||||
this(context, false);
|
||||
}
|
||||
|
||||
public NightModeController(Context context, boolean updateMatrix) {
|
||||
mContext = context;
|
||||
mUpdateMatrix = updateMatrix;
|
||||
TunerService.get(mContext).addTunable(this, NIGHT_MODE_ADJUST_TINT,
|
||||
COLOR_MATRIX_CUSTOM_VALUES, Secure.TWILIGHT_MODE);
|
||||
}
|
||||
|
||||
public void setNightMode(boolean isNight) {
|
||||
if (mIsAuto) {
|
||||
if (mIsNight != isNight) {
|
||||
TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, isNight
|
||||
? Secure.TWILIGHT_MODE_AUTO_OVERRIDE_ON
|
||||
: Secure.TWILIGHT_MODE_AUTO_OVERRIDE_OFF);
|
||||
} else {
|
||||
TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE,
|
||||
Secure.TWILIGHT_MODE_AUTO);
|
||||
}
|
||||
} else {
|
||||
TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, isNight
|
||||
? Secure.TWILIGHT_MODE_LOCKED_ON : Secure.TWILIGHT_MODE_LOCKED_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAuto(boolean auto) {
|
||||
mIsAuto = auto;
|
||||
if (auto) {
|
||||
TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, Secure.TWILIGHT_MODE_AUTO);
|
||||
} else {
|
||||
// Lock into the current state
|
||||
TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, mIsNight
|
||||
? Secure.TWILIGHT_MODE_LOCKED_ON : Secure.TWILIGHT_MODE_LOCKED_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAuto() {
|
||||
return mIsAuto;
|
||||
}
|
||||
|
||||
public void setAdjustTint(Boolean newValue) {
|
||||
TunerService.get(mContext).setValue(NIGHT_MODE_ADJUST_TINT, ((Boolean) newValue) ? 1 : 0);
|
||||
}
|
||||
|
||||
public void addListener(Listener listener) {
|
||||
mListeners.add(listener);
|
||||
listener.onNightModeChanged();
|
||||
updateListening();
|
||||
}
|
||||
|
||||
public void removeListener(Listener listener) {
|
||||
mListeners.remove(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
private void updateListening() {
|
||||
boolean shouldListen = mListeners.size() != 0 || (mUpdateMatrix && mAdjustTint);
|
||||
if (shouldListen == mListening) return;
|
||||
mListening = shouldListen;
|
||||
if (mListening) {
|
||||
mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_TWILIGHT_CHANGED));
|
||||
} else {
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
if (!mListening) {
|
||||
updateNightMode(mContext.registerReceiver(null,
|
||||
new IntentFilter(ACTION_TWILIGHT_CHANGED)));
|
||||
}
|
||||
return mIsNight;
|
||||
}
|
||||
|
||||
public String getCustomValues() {
|
||||
return TunerService.get(mContext).getValue(COLOR_MATRIX_CUSTOM_VALUES);
|
||||
}
|
||||
|
||||
public void setCustomValues(String values) {
|
||||
TunerService.get(mContext).setValue(COLOR_MATRIX_CUSTOM_VALUES, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (COLOR_MATRIX_CUSTOM_VALUES.equals(key)) {
|
||||
mCustomMatrix = newValue != null ? toValues(newValue) : null;
|
||||
updateCurrentMatrix();
|
||||
} else if (NIGHT_MODE_ADJUST_TINT.equals(key)) {
|
||||
mAdjustTint = newValue == null || Integer.parseInt(newValue) != 0;
|
||||
updateListening();
|
||||
updateCurrentMatrix();
|
||||
} else if (Secure.TWILIGHT_MODE.equals(key)) {
|
||||
mIsAuto = newValue != null && Integer.parseInt(newValue) >= Secure.TWILIGHT_MODE_AUTO;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCurrentMatrix() {
|
||||
if (!mUpdateMatrix) return;
|
||||
if ((!mAdjustTint || mAmount == 0) && mCustomMatrix == null) {
|
||||
TunerService.get(mContext).setValue(Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
|
||||
return;
|
||||
}
|
||||
float[] values = scaleValues(IDENTITY_MATRIX, NIGHT_VALUES, mAdjustTint ? mAmount : 0);
|
||||
if (mCustomMatrix != null) {
|
||||
values = multiply(values, mCustomMatrix);
|
||||
}
|
||||
TunerService.get(mContext).setValue(Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
|
||||
toString(values));
|
||||
}
|
||||
|
||||
private void updateNightMode(Intent intent) {
|
||||
mIsNight = intent.getBooleanExtra(EXTRA_IS_NIGHT, false);
|
||||
mAmount = intent.getFloatExtra(EXTRA_AMOUNT, 0);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ACTION_TWILIGHT_CHANGED.equals(intent.getAction())) {
|
||||
updateNightMode(intent);
|
||||
updateCurrentMatrix();
|
||||
for (int i = 0; i < mListeners.size(); i++) {
|
||||
mListeners.get(i).onNightModeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public interface Listener {
|
||||
void onNightModeChanged();
|
||||
void onTwilightAutoChanged();
|
||||
}
|
||||
|
||||
private static float[] multiply(float[] matrix, float[] other) {
|
||||
if (matrix == null) {
|
||||
return other;
|
||||
}
|
||||
float[] result = new float[16];
|
||||
Matrix.multiplyMM(result, 0, matrix, 0, other, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
private float[] scaleValues(float[] identityMatrix, float[] nightValues, float amount) {
|
||||
float[] values = new float[identityMatrix.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = MathUtils.lerp(identityMatrix[i], nightValues[i], amount);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static String toString(float[] values) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append(values[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static float[] toValues(String customValues) {
|
||||
String[] strValues = customValues.split(",");
|
||||
float[] values = new float[strValues.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = Float.parseFloat(strValues[i]);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.DropDownPreference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AttributeSet;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
|
||||
import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
|
||||
|
||||
public class BatteryPreference extends DropDownPreference implements TunerService.Tunable {
|
||||
|
||||
private static final String PERCENT = "percent";
|
||||
private static final String DEFAULT = "default";
|
||||
private static final String DISABLED = "disabled";
|
||||
|
||||
private final String mBattery;
|
||||
private boolean mBatteryEnabled;
|
||||
private boolean mHasPercentage;
|
||||
private ArraySet<String> mBlacklist;
|
||||
private boolean mHasSetValue;
|
||||
|
||||
public BatteryPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mBattery = context.getString(com.android.internal.R.string.status_bar_battery);
|
||||
setEntryValues(new CharSequence[] {PERCENT, DEFAULT, DISABLED });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttached() {
|
||||
super.onAttached();
|
||||
TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
|
||||
mHasPercentage = Settings.System.getInt(getContext().getContentResolver(),
|
||||
SHOW_PERCENT_SETTING, 0) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetached() {
|
||||
TunerService.get(getContext()).removeTunable(this);
|
||||
super.onDetached();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
|
||||
mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
|
||||
mBatteryEnabled = !mBlacklist.contains(mBattery);
|
||||
}
|
||||
if (!mHasSetValue) {
|
||||
// Because of the complicated tri-state it can end up looping and setting state back to
|
||||
// what the user didn't choose. To avoid this, just set the state once and rely on the
|
||||
// preference to handle updates.
|
||||
mHasSetValue = true;
|
||||
if (mBatteryEnabled && mHasPercentage) {
|
||||
setValue(PERCENT);
|
||||
} else if (mBatteryEnabled) {
|
||||
setValue(DEFAULT);
|
||||
} else {
|
||||
setValue(DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean persistString(String value) {
|
||||
final boolean v = PERCENT.equals(value);
|
||||
MetricsLogger.action(getContext(), MetricsEvent.TUNER_BATTERY_PERCENTAGE, v);
|
||||
Settings.System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
|
||||
if (DISABLED.equals(value)) {
|
||||
mBlacklist.add(mBattery);
|
||||
} else {
|
||||
mBlacklist.remove(mBattery);
|
||||
}
|
||||
TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
|
||||
TextUtils.join(",", mBlacklist));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
public class CalibratePreference extends DialogPreference {
|
||||
public CalibratePreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.DropDownPreference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AttributeSet;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.policy.Clock;
|
||||
|
||||
public class ClockPreference extends DropDownPreference implements TunerService.Tunable {
|
||||
|
||||
private static final String SECONDS = "seconds";
|
||||
private static final String DEFAULT = "default";
|
||||
private static final String DISABLED = "disabled";
|
||||
|
||||
private final String mClock;
|
||||
private boolean mClockEnabled;
|
||||
private boolean mHasSeconds;
|
||||
private ArraySet<String> mBlacklist;
|
||||
private boolean mHasSetValue;
|
||||
|
||||
public ClockPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mClock = context.getString(com.android.internal.R.string.status_bar_clock);
|
||||
setEntryValues(new CharSequence[] { SECONDS, DEFAULT, DISABLED });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttached() {
|
||||
super.onAttached();
|
||||
TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
|
||||
Clock.CLOCK_SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetached() {
|
||||
TunerService.get(getContext()).removeTunable(this);
|
||||
super.onDetached();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
|
||||
mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
|
||||
mClockEnabled = !mBlacklist.contains(mClock);
|
||||
} else if (Clock.CLOCK_SECONDS.equals(key)) {
|
||||
mHasSeconds = newValue != null && Integer.parseInt(newValue) != 0;
|
||||
}
|
||||
if (!mHasSetValue) {
|
||||
// Because of the complicated tri-state it can end up looping and setting state back to
|
||||
// what the user didn't choose. To avoid this, just set the state once and rely on the
|
||||
// preference to handle updates.
|
||||
mHasSetValue = true;
|
||||
if (mClockEnabled && mHasSeconds) {
|
||||
setValue(SECONDS);
|
||||
} else if (mClockEnabled) {
|
||||
setValue(DEFAULT);
|
||||
} else {
|
||||
setValue(DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean persistString(String value) {
|
||||
TunerService.get(getContext()).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1 : 0);
|
||||
if (DISABLED.equals(value)) {
|
||||
mBlacklist.add(mClock);
|
||||
} else {
|
||||
mBlacklist.remove(mClock);
|
||||
}
|
||||
TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
|
||||
TextUtils.join(",", mBlacklist));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.NightModeController;
|
||||
|
||||
public class ColorAndAppearanceFragment extends PreferenceFragment {
|
||||
|
||||
private static final String KEY_CALIBRATE = "calibrate";
|
||||
|
||||
private static final long RESET_DELAY = 10000;
|
||||
private static final CharSequence KEY_NIGHT_MODE = "night_mode";
|
||||
|
||||
private NightModeController mNightModeController;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mNightModeController = new NightModeController(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.color_and_appearance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// TODO: Figure out better title model for Tuner, to avoid any more of this.
|
||||
getActivity().setTitle(R.string.color_and_appearance);
|
||||
|
||||
Preference nightMode = findPreference(KEY_NIGHT_MODE);
|
||||
nightMode.setSummary(mNightModeController.isEnabled()
|
||||
? R.string.night_mode_on : R.string.night_mode_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayPreferenceDialog(Preference preference) {
|
||||
if (preference instanceof CalibratePreference) {
|
||||
CalibrateDialog.show(this);
|
||||
} else {
|
||||
super.onDisplayPreferenceDialog(preference);
|
||||
}
|
||||
}
|
||||
|
||||
private void startRevertTimer() {
|
||||
getView().postDelayed(mResetColorMatrix, RESET_DELAY);
|
||||
}
|
||||
|
||||
private void onApply() {
|
||||
mNightModeController.setCustomValues(Settings.Secure.getString(
|
||||
getContext().getContentResolver(), Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX));
|
||||
getView().removeCallbacks(mResetColorMatrix);
|
||||
}
|
||||
|
||||
private void onRevert() {
|
||||
getView().removeCallbacks(mResetColorMatrix);
|
||||
mResetColorMatrix.run();
|
||||
}
|
||||
|
||||
private final Runnable mResetColorMatrix = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((DialogFragment) getFragmentManager().findFragmentByTag("RevertWarning")).dismiss();
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
|
||||
}
|
||||
};
|
||||
|
||||
public static class CalibrateDialog extends DialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
private float[] mValues;
|
||||
private NightModeController mNightModeController;
|
||||
|
||||
public static void show(ColorAndAppearanceFragment fragment) {
|
||||
CalibrateDialog dialog = new CalibrateDialog();
|
||||
dialog.setTargetFragment(fragment, 0);
|
||||
dialog.show(fragment.getFragmentManager(), "Calibrate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mNightModeController = new NightModeController(getContext());
|
||||
String customValues = mNightModeController.getCustomValues();
|
||||
if (customValues == null) {
|
||||
// Generate this as a string because its the easiest way to generate a copy of the
|
||||
// identity.
|
||||
customValues = NightModeController.toString(NightModeController.IDENTITY_MATRIX);
|
||||
}
|
||||
mValues = NightModeController.toValues(customValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
View v = LayoutInflater.from(getContext()).inflate(R.layout.calibrate_sliders, null);
|
||||
bindView(v.findViewById(R.id.r_group), 0);
|
||||
bindView(v.findViewById(R.id.g_group), 5);
|
||||
bindView(v.findViewById(R.id.b_group), 10);
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.calibrate_display)
|
||||
.setView(v)
|
||||
.setPositiveButton(R.string.color_apply, this)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create();
|
||||
}
|
||||
|
||||
private void bindView(View view, final int index) {
|
||||
SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
|
||||
seekBar.setMax(1000);
|
||||
seekBar.setProgress((int) (1000 * mValues[index]));
|
||||
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
mValues[index] = progress / 1000f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (mValues[0] == 1 && mValues[5] == 1 && mValues[10] == 1) {
|
||||
// Allow removal of matrix by all values set to highest.
|
||||
mNightModeController.setCustomValues(null);
|
||||
return;
|
||||
}
|
||||
((ColorAndAppearanceFragment) getTargetFragment()).startRevertTimer();
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
|
||||
NightModeController.toString(mValues));
|
||||
RevertWarning.show((ColorAndAppearanceFragment) getTargetFragment());
|
||||
}
|
||||
}
|
||||
|
||||
public static class RevertWarning extends DialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
|
||||
public static void show(ColorAndAppearanceFragment fragment) {
|
||||
RevertWarning warning = new RevertWarning();
|
||||
warning.setTargetFragment(fragment, 0);
|
||||
warning.show(fragment.getFragmentManager(), "RevertWarning");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog alertDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.color_revert_title)
|
||||
.setMessage(R.string.color_revert_message)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.create();
|
||||
alertDialog.setCanceledOnTouchOutside(true);
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
((ColorAndAppearanceFragment) getTargetFragment()).onRevert();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
((ColorAndAppearanceFragment) getTargetFragment()).onApply();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.DropDownPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.QSTileHost;
|
||||
import com.android.systemui.statusbar.policy.DisplayController;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ColorMatrixFragment extends PreferenceFragment implements TunerService.Tunable {
|
||||
|
||||
private static final String TAG = "ColorMatrixFragment";
|
||||
|
||||
private static final long RESET_DELAY = 10000;
|
||||
|
||||
private boolean mCustomEnabled;
|
||||
private DropDownPreference mSelectPreference;
|
||||
private String mCurrentValue;
|
||||
private String mCustomValues;
|
||||
private SwitchPreference mEnableCustomPreference;
|
||||
private MatrixPreference mCustomPreference;
|
||||
private int mState;
|
||||
private Switch mSwitch;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Context context = getContext();
|
||||
TunerService.get(context).addTunable(this, DisplayController.COLOR_MATRIX_CUSTOM_ENABLED,
|
||||
DisplayController.COLOR_MATRIX_CUSTOM_VALUES, DisplayController.COLOR_STATE,
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final View view = LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.color_matrix_settings, container, false);
|
||||
((ViewGroup) view).addView(super.onCreateView(inflater, container, savedInstanceState));
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
final Context context = getPreferenceManager().getContext();
|
||||
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(context));
|
||||
|
||||
mSelectPreference = new DropDownPreference(context);
|
||||
mSelectPreference.setTitle(R.string.color_transform);
|
||||
mSelectPreference.setSummary("%s");
|
||||
mSelectPreference.setOnPreferenceChangeListener(
|
||||
new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (Objects.equals(newValue, DisplayController.AUTO_STRING)) {
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
DisplayController.COLOR_STATE,
|
||||
DisplayController.COLOR_STATE_AUTO);
|
||||
return true;
|
||||
}
|
||||
if (Objects.equals(newValue, DisplayController.NONE_STRING)) {
|
||||
Settings.Secure.putString(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
|
||||
return true;
|
||||
}
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
DisplayController.COLOR_STATE,
|
||||
DisplayController.COLOR_STATE_ENABLED);
|
||||
final String value = (String) newValue;
|
||||
Settings.Secure.putString(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
|
||||
value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
getPreferenceScreen().addPreference(mSelectPreference);
|
||||
|
||||
mEnableCustomPreference = new SwitchPreference(context);
|
||||
mEnableCustomPreference.setTitle(R.string.color_enable_custom);
|
||||
mEnableCustomPreference.setOnPreferenceChangeListener(
|
||||
new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (!enabled && Objects.equals(mCurrentValue, mCustomValues)) {
|
||||
Settings.Secure.putString(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
|
||||
}
|
||||
Settings.Secure.putInt(context.getContentResolver(),
|
||||
DisplayController.COLOR_MATRIX_CUSTOM_ENABLED, enabled ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
getPreferenceScreen().addPreference(mEnableCustomPreference);
|
||||
|
||||
mCustomPreference = new MatrixPreference(context);
|
||||
getPreferenceScreen().addPreference(mCustomPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
View switchBar = view.findViewById(R.id.switch_bar);
|
||||
mSwitch = (Switch) switchBar.findViewById(android.R.id.switch_widget);
|
||||
mSwitch.setChecked(mState != DisplayController.COLOR_STATE_DISABLED);
|
||||
switchBar.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int newState = mState != DisplayController.COLOR_STATE_DISABLED
|
||||
? DisplayController.COLOR_STATE_DISABLED
|
||||
: DisplayController.COLOR_STATE_ENABLED;
|
||||
ContentResolver contentResolver = getContext().getContentResolver();
|
||||
if (newState == DisplayController.COLOR_STATE_DISABLED) {
|
||||
String tiles = Settings.Secure.getString(contentResolver,
|
||||
QSTileHost.TILES_SETTING);
|
||||
if (tiles != null) {
|
||||
if (tiles.contains(",colors")) {
|
||||
tiles = tiles.replace(",colors", "");
|
||||
} else if (tiles.contains("colors,")) {
|
||||
tiles = tiles.replace("colors,", "");
|
||||
}
|
||||
Settings.Secure.putString(contentResolver, QSTileHost.TILES_SETTING,
|
||||
tiles);
|
||||
}
|
||||
}
|
||||
Settings.Secure.putInt(contentResolver,
|
||||
DisplayController.COLOR_STATE, newState);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
TunerService.get(getContext()).removeTunable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (DisplayController.COLOR_MATRIX_CUSTOM_ENABLED.equals(key)) {
|
||||
mCustomEnabled = newValue != null && Integer.parseInt(newValue) != 0;
|
||||
mEnableCustomPreference.setChecked(mCustomEnabled);
|
||||
mCustomPreference.setEnabled(mCustomEnabled
|
||||
&& mState != DisplayController.COLOR_STATE_DISABLED);
|
||||
updateSelectOptions();
|
||||
} else if (DisplayController.COLOR_MATRIX_CUSTOM_VALUES.equals(key)) {
|
||||
mCustomValues = newValue;
|
||||
if (mCustomValues == null) {
|
||||
mCustomValues = DisplayController.toString(DisplayController.IDENTITY_MATRIX);
|
||||
}
|
||||
mCustomPreference.setValues(mCustomValues);
|
||||
updateSelectOptions();
|
||||
} else if (DisplayController.COLOR_STATE.equals(key)) {
|
||||
mState = newValue != null ? Integer.parseInt(newValue) : 0;
|
||||
if (mSwitch != null) {
|
||||
mSwitch.setChecked(mState != DisplayController.COLOR_STATE_DISABLED);
|
||||
}
|
||||
mSelectPreference.setEnabled(mState != DisplayController.COLOR_STATE_DISABLED);
|
||||
mEnableCustomPreference.setEnabled(mState != DisplayController.COLOR_STATE_DISABLED);
|
||||
mCustomPreference.setEnabled(mCustomEnabled
|
||||
&& mState != DisplayController.COLOR_STATE_DISABLED);
|
||||
} else {
|
||||
mCurrentValue = newValue;
|
||||
updateSelectOptions();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSelectOptions() {
|
||||
final int N = DisplayController.CUSTOM_INDEX + (mCustomEnabled ? 1 : 0);
|
||||
String[] values = new String[N];
|
||||
CharSequence[] names = new CharSequence[N];
|
||||
CharSequence[] totalNames = DisplayController.getColorTitles(getContext());
|
||||
String[] entries = DisplayController.getColorTransforms(getContext());
|
||||
entries[DisplayController.CUSTOM_INDEX] = mCustomValues != null ? mCustomValues : "";
|
||||
for (int i = 0; i < N; i++) {
|
||||
values[i] = entries[i];
|
||||
names[i] = totalNames[i];
|
||||
}
|
||||
mSelectPreference.setEntries(names);
|
||||
mSelectPreference.setEntryValues(values);
|
||||
int index = 0;
|
||||
if (mState == DisplayController.COLOR_STATE_AUTO) {
|
||||
index = DisplayController.AUTO_INDEX;
|
||||
} else if (mCustomValues != null && Objects.equals(mCurrentValue, mCustomValues)) {
|
||||
index = DisplayController.CUSTOM_INDEX;
|
||||
} else if (Objects.equals(mCurrentValue, entries[1])) {
|
||||
index = 1;
|
||||
}
|
||||
mSelectPreference.setValueIndex(index);
|
||||
mSelectPreference.setSummary("%s");
|
||||
return;
|
||||
}
|
||||
|
||||
private void startRevertTimer() {
|
||||
getView().postDelayed(mResetColorMatrix, RESET_DELAY);
|
||||
}
|
||||
|
||||
private void onApply() {
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
DisplayController.COLOR_MATRIX_CUSTOM_VALUES, mCurrentValue);
|
||||
getView().removeCallbacks(mResetColorMatrix);
|
||||
}
|
||||
|
||||
private void onRevert() {
|
||||
getView().removeCallbacks(mResetColorMatrix);
|
||||
mResetColorMatrix.run();
|
||||
}
|
||||
|
||||
private final Runnable mResetColorMatrix = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((DialogFragment) getFragmentManager().findFragmentByTag("RevertWarning")).dismiss();
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
|
||||
}
|
||||
};
|
||||
|
||||
private class MatrixPreference extends Preference implements View.OnClickListener {
|
||||
private float[] mValues;
|
||||
|
||||
public MatrixPreference(Context context) {
|
||||
super(context);
|
||||
setLayoutResource(R.layout.preference_matrix);
|
||||
}
|
||||
|
||||
public void setValues(String customValues) {
|
||||
String[] strValues = customValues.split(",");
|
||||
mValues = new float[strValues.length];
|
||||
for (int i = 0; i < mValues.length; i++) {
|
||||
mValues[i] = Float.parseFloat(strValues[i]);
|
||||
}
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
bindView(holder.findViewById(R.id.r_group), 0);
|
||||
bindView(holder.findViewById(R.id.g_group), 5);
|
||||
bindView(holder.findViewById(R.id.b_group), 10);
|
||||
holder.findViewById(R.id.apply).setOnClickListener(this);
|
||||
}
|
||||
|
||||
private void bindView(View view, final int index) {
|
||||
SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
|
||||
seekBar.setMax(1000);
|
||||
seekBar.setProgress((int) (1000 * mValues[index]));
|
||||
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
mValues[index] = progress / 1000f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startRevertTimer();
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
|
||||
DisplayController.toString(mValues));
|
||||
RevertWarning.show(ColorMatrixFragment.this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class RevertWarning extends DialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
|
||||
public static void show(ColorMatrixFragment fragment) {
|
||||
RevertWarning warning = new RevertWarning();
|
||||
warning.setTargetFragment(fragment, 0);
|
||||
warning.show(fragment.getFragmentManager(), "RevertWarning");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog alertDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.color_revert_title)
|
||||
.setMessage(R.string.color_revert_message)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.create();
|
||||
alertDialog.setCanceledOnTouchOutside(true);
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
((ColorMatrixFragment) getTargetFragment()).onRevert();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
((ColorMatrixFragment) getTargetFragment()).onApply();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.qs.QSTile;
|
||||
import com.android.systemui.statusbar.policy.DisplayController;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class ColorMatrixTile extends QSTile<QSTile.State> implements DisplayController.Listener {
|
||||
|
||||
public static final String COLOR_MATRIX_SPEC = "colors";
|
||||
|
||||
private final DisplayController mDisplayController;
|
||||
|
||||
private int mIndex;
|
||||
private String mCurrentValue;
|
||||
|
||||
private boolean mCustomEnabled;
|
||||
private String[] mValues;
|
||||
private CharSequence[] mValueTitles;
|
||||
|
||||
public ColorMatrixTile(Host host) {
|
||||
super(host);
|
||||
mDisplayController = host.getDisplayController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
mValues = DisplayController.getColorTransforms(mContext);
|
||||
mValueTitles = DisplayController.getColorTitles(mContext);
|
||||
mDisplayController.addListener(this);
|
||||
} else {
|
||||
mDisplayController.removeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public State newTileState() {
|
||||
return new State();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClick() {
|
||||
mIndex++;
|
||||
if (mIndex == DisplayController.AUTO_INDEX) {
|
||||
mDisplayController.setAuto(true);
|
||||
} else {
|
||||
mDisplayController.setAuto(false);
|
||||
if (!mDisplayController.isCustomEnabled()
|
||||
&& (mIndex == DisplayController.CUSTOM_INDEX)) {
|
||||
mIndex++;
|
||||
}
|
||||
if (mIndex == mValues.length - 1) {
|
||||
mIndex = 0;
|
||||
}
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, mValues[mIndex],
|
||||
ActivityManager.getCurrentUser());
|
||||
}
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUpdateState(State state, Object arg) {
|
||||
if (mDisplayController.isAuto()) {
|
||||
mIndex = DisplayController.AUTO_INDEX;
|
||||
} else if (mDisplayController.isCustomSet()) {
|
||||
mIndex = DisplayController.CUSTOM_INDEX;
|
||||
} else {
|
||||
mIndex = Objects.equals(mDisplayController.getCurrentMatrix(), mValues[1]) ? 1 : 0;
|
||||
}
|
||||
state.icon = ResourceIcon.get(R.drawable.ic_colorize);
|
||||
state.label = mValueTitles[mIndex];
|
||||
state.contentDescription = mValueTitles[mIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCurrentMatrixChanged() {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.QS_COLOR_MATRIX;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* Copyright (c) 2016, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.DropDownPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.QSTileHost;
|
||||
import com.android.systemui.statusbar.policy.NightModeController;
|
||||
import com.android.systemui.statusbar.policy.NightModeController.Listener;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
public class NightModeFragment extends PreferenceFragment implements Tunable,
|
||||
Listener, OnPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = "NightModeFragment";
|
||||
private static final CharSequence KEY_AUTO = "auto";
|
||||
private static final CharSequence KEY_DARK_THEME = "dark_theme";
|
||||
private static final CharSequence KEY_ADJUST_TINT = "adjust_tint";
|
||||
private static final CharSequence KEY_ADJUST_BRIGHTNESS = "adjust_brightness";
|
||||
|
||||
private Switch mSwitch;
|
||||
|
||||
private NightModeController mNightModeController;
|
||||
private SwitchPreference mAutoSwitch;
|
||||
private SwitchPreference mDarkTheme;
|
||||
private SwitchPreference mAdjustTint;
|
||||
private SwitchPreference mAdjustBrightness;
|
||||
private UiModeManager mUiModeManager;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mNightModeController = new NightModeController(getContext());
|
||||
mUiModeManager = getContext().getSystemService(UiModeManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final View view = LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.night_mode_settings, container, false);
|
||||
((ViewGroup) view).addView(super.onCreateView(inflater, container, savedInstanceState));
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
final Context context = getPreferenceManager().getContext();
|
||||
|
||||
addPreferencesFromResource(R.xml.night_mode);
|
||||
mAutoSwitch = (SwitchPreference) findPreference(KEY_AUTO);
|
||||
mAutoSwitch.setOnPreferenceChangeListener(this);
|
||||
mDarkTheme = (SwitchPreference) findPreference(KEY_DARK_THEME);
|
||||
mDarkTheme.setOnPreferenceChangeListener(this);
|
||||
mAdjustTint = (SwitchPreference) findPreference(KEY_ADJUST_TINT);
|
||||
mAdjustTint.setOnPreferenceChangeListener(this);
|
||||
mAdjustBrightness = (SwitchPreference) findPreference(KEY_ADJUST_BRIGHTNESS);
|
||||
mAdjustBrightness.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
View switchBar = view.findViewById(R.id.switch_bar);
|
||||
mSwitch = (Switch) switchBar.findViewById(android.R.id.switch_widget);
|
||||
mSwitch.setChecked(mNightModeController.isEnabled());
|
||||
switchBar.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
boolean newState = !mNightModeController.isEnabled();
|
||||
mNightModeController.setNightMode(newState);
|
||||
mSwitch.setChecked(newState);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mNightModeController.addListener(this);
|
||||
TunerService.get(getContext()).addTunable(this, Secure.BRIGHTNESS_USE_TWILIGHT,
|
||||
NightModeController.NIGHT_MODE_ADJUST_TINT);
|
||||
mDarkTheme.setChecked(mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_AUTO);
|
||||
calculateDisabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mNightModeController.removeListener(this);
|
||||
TunerService.get(getContext()).removeTunable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (mAutoSwitch == preference) {
|
||||
mNightModeController.setAuto((Boolean) newValue);
|
||||
} else if (mDarkTheme == preference) {
|
||||
mUiModeManager.setNightMode(((Boolean) newValue) ? UiModeManager.MODE_NIGHT_AUTO
|
||||
: UiModeManager.MODE_NIGHT_NO);
|
||||
postCalculateDisabled();
|
||||
} else if (mAdjustTint == preference) {
|
||||
mNightModeController.setAdjustTint((Boolean) newValue);
|
||||
postCalculateDisabled();
|
||||
} else if (mAdjustBrightness == preference) {
|
||||
TunerService.get(getContext()).setValue(Secure.BRIGHTNESS_USE_TWILIGHT,
|
||||
((Boolean) newValue) ? 1 : 0);
|
||||
postCalculateDisabled();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void postCalculateDisabled() {
|
||||
// Post this because its the easiest way to wait for all state to be calculated.
|
||||
getView().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
calculateDisabled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void calculateDisabled() {
|
||||
int enabledCount = (mDarkTheme.isChecked() ? 1 : 0)
|
||||
+ (mAdjustTint.isChecked() ? 1 : 0)
|
||||
+ (mAdjustBrightness.isChecked() ? 1 : 0);
|
||||
if (enabledCount == 1) {
|
||||
if (mDarkTheme.isChecked()) {
|
||||
mDarkTheme.setEnabled(false);
|
||||
} else if (mAdjustTint.isChecked()) {
|
||||
mAdjustTint.setEnabled(false);
|
||||
} else {
|
||||
mAdjustBrightness.setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
mDarkTheme.setEnabled(true);
|
||||
mAdjustTint.setEnabled(true);
|
||||
mAdjustBrightness.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (Secure.BRIGHTNESS_USE_TWILIGHT.equals(key)) {
|
||||
mAdjustBrightness.setChecked(newValue != null && Integer.parseInt(newValue) != 0);
|
||||
} else if (NightModeController.NIGHT_MODE_ADJUST_TINT.equals(key)) {
|
||||
// Default on.
|
||||
mAdjustTint.setChecked(newValue == null || Integer.parseInt(newValue) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNightModeChanged() {
|
||||
mSwitch.setChecked(mNightModeController.isEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTwilightAutoChanged() {
|
||||
mAutoSwitch.setChecked(mNightModeController.isAuto());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (c) 2016, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.tuner;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.qs.QSTile;
|
||||
import com.android.systemui.statusbar.policy.NightModeController;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class NightModeTile extends QSTile<QSTile.State> implements NightModeController.Listener {
|
||||
|
||||
public static final String NIGHT_MODE_SPEC = "night";
|
||||
|
||||
private final NightModeController mNightModeController;
|
||||
|
||||
private int mIndex;
|
||||
private String mCurrentValue;
|
||||
|
||||
private boolean mCustomEnabled;
|
||||
private String[] mValues;
|
||||
private CharSequence[] mValueTitles;
|
||||
|
||||
public NightModeTile(Host host) {
|
||||
super(host);
|
||||
mNightModeController = host.getNightModeController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
mNightModeController.addListener(this);
|
||||
refreshState();
|
||||
} else {
|
||||
mNightModeController.removeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public State newTileState() {
|
||||
return new State();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClick() {
|
||||
mNightModeController.setNightMode(!mNightModeController.isEnabled());
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUpdateState(State state, Object arg) {
|
||||
// TODO: Right now this is just a dropper, needs an actual night icon.
|
||||
boolean enabled = mNightModeController.isEnabled();
|
||||
state.icon = ResourceIcon.get(enabled ? R.drawable.ic_night_mode
|
||||
: R.drawable.ic_night_mode_disabled);
|
||||
state.label = mContext.getString(R.string.night_mode);
|
||||
state.contentDescription = mContext.getString(R.string.night_mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNightModeChanged() {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTwilightAutoChanged() {
|
||||
// Don't care.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.QS_COLOR_MATRIX;
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,6 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
|
||||
|
||||
public class TunerFragment extends PreferenceFragment {
|
||||
|
||||
private static final String TAG = "TunerFragment";
|
||||
@@ -51,10 +49,6 @@ public class TunerFragment extends PreferenceFragment {
|
||||
|
||||
private static final int MENU_REMOVE = Menu.FIRST + 1;
|
||||
|
||||
private final SettingObserver mSettingObserver = new SettingObserver();
|
||||
|
||||
private SwitchPreference mBatteryPct;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -72,7 +66,6 @@ public class TunerFragment extends PreferenceFragment {
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.tuner_prefs);
|
||||
|
||||
mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT);
|
||||
if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
|
||||
0) == 0) {
|
||||
if (getFragmentManager().findFragmentByTag(WARNING_TAG) == null) {
|
||||
@@ -85,9 +78,6 @@ public class TunerFragment extends PreferenceFragment {
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getActivity().setTitle(R.string.system_ui_tuner);
|
||||
updateBatteryPct();
|
||||
getContext().getContentResolver().registerContentObserver(
|
||||
System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
|
||||
|
||||
MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, true);
|
||||
}
|
||||
@@ -95,7 +85,6 @@ public class TunerFragment extends PreferenceFragment {
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
|
||||
|
||||
MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, false);
|
||||
}
|
||||
@@ -123,35 +112,6 @@ public class TunerFragment extends PreferenceFragment {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void updateBatteryPct() {
|
||||
mBatteryPct.setOnPreferenceChangeListener(null);
|
||||
mBatteryPct.setChecked(System.getInt(getContext().getContentResolver(),
|
||||
SHOW_PERCENT_SETTING, 0) != 0);
|
||||
mBatteryPct.setOnPreferenceChangeListener(mBatteryPctChange);
|
||||
}
|
||||
|
||||
private final class SettingObserver extends ContentObserver {
|
||||
public SettingObserver() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri, int userId) {
|
||||
super.onChange(selfChange, uri, userId);
|
||||
updateBatteryPct();
|
||||
}
|
||||
}
|
||||
|
||||
private final OnPreferenceChangeListener mBatteryPctChange = new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean v = (Boolean) newValue;
|
||||
MetricsLogger.action(getContext(), MetricsEvent.TUNER_BATTERY_PERCENTAGE, v);
|
||||
System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public static class TunerWarningFragment extends DialogFragment {
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
|
||||
@@ -23,7 +23,7 @@ public class TunerSwitch extends SwitchPreference implements Tunable {
|
||||
@Override
|
||||
public void onAttached() {
|
||||
super.onAttached();
|
||||
TunerService.get(getContext()).addTunable(this, getKey());
|
||||
TunerService.get(getContext()).addTunable(this, getKey().split(","));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,7 +39,9 @@ public class TunerSwitch extends SwitchPreference implements Tunable {
|
||||
|
||||
@Override
|
||||
protected boolean persistBoolean(boolean value) {
|
||||
Settings.Secure.putString(getContext().getContentResolver(), getKey(), value ? "1" : "0");
|
||||
for (String key : getKey().split(",")) {
|
||||
Settings.Secure.putString(getContext().getContentResolver(), key, value ? "1" : "0");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,22 +60,8 @@ class AutomaticBrightnessController {
|
||||
// non-zero, which in turn ensures that the total weight is non-zero.
|
||||
private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
|
||||
|
||||
// If true, enables the use of the current time as an auto-brightness adjustment.
|
||||
// The basic idea here is to expand the dynamic range of auto-brightness
|
||||
// when it is especially dark outside. The light sensor tends to perform
|
||||
// poorly at low light levels so we compensate for it by making an
|
||||
// assumption about the environment.
|
||||
private static final boolean USE_TWILIGHT_ADJUSTMENT =
|
||||
PowerManager.useTwilightAdjustmentFeature();
|
||||
|
||||
// Specifies the maximum magnitude of the time of day adjustment.
|
||||
private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
|
||||
|
||||
// The amount of time after or before sunrise over which to start adjusting
|
||||
// the gamma. We want the change to happen gradually so that it is below the
|
||||
// threshold of perceptibility and so that the adjustment has maximum effect
|
||||
// well after dusk.
|
||||
private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
|
||||
private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1f;
|
||||
|
||||
// Debounce for sampling user-initiated changes in display brightness to ensure
|
||||
// the user is satisfied with the result before storing the sample.
|
||||
@@ -193,6 +179,8 @@ class AutomaticBrightnessController {
|
||||
private int mBrightnessAdjustmentSampleOldBrightness;
|
||||
private float mBrightnessAdjustmentSampleOldGamma;
|
||||
|
||||
private boolean mUseTwilight;
|
||||
|
||||
public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
|
||||
SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
|
||||
int brightnessMin, int brightnessMax, float dozeScaleFactor,
|
||||
@@ -221,10 +209,6 @@ class AutomaticBrightnessController {
|
||||
if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
|
||||
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
|
||||
}
|
||||
|
||||
if (USE_TWILIGHT_ADJUSTMENT) {
|
||||
mTwilight.registerListener(mTwilightListener, mHandler);
|
||||
}
|
||||
}
|
||||
|
||||
public int getAutomaticScreenBrightness() {
|
||||
@@ -235,7 +219,7 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
|
||||
public void configure(boolean enable, float adjustment, boolean dozing,
|
||||
boolean userInitiatedChange) {
|
||||
boolean userInitiatedChange, boolean useTwilight) {
|
||||
// While dozing, the application processor may be suspended which will prevent us from
|
||||
// receiving new information from the light sensor. On some devices, we may be able to
|
||||
// switch to a wake-up light sensor instead but for now we will simply disable the sensor
|
||||
@@ -244,6 +228,7 @@ class AutomaticBrightnessController {
|
||||
mDozing = dozing;
|
||||
boolean changed = setLightSensorEnabled(enable && !dozing);
|
||||
changed |= setScreenAutoBrightnessAdjustment(adjustment);
|
||||
changed |= setUseTwilight(useTwilight);
|
||||
if (changed) {
|
||||
updateAutoBrightness(false /*sendUpdate*/);
|
||||
}
|
||||
@@ -252,6 +237,17 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setUseTwilight(boolean useTwilight) {
|
||||
if (mUseTwilight == useTwilight) return false;
|
||||
if (useTwilight) {
|
||||
mTwilight.registerListener(mTwilightListener, mHandler);
|
||||
} else {
|
||||
mTwilight.unregisterListener(mTwilightListener);
|
||||
}
|
||||
mUseTwilight = useTwilight;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("Automatic Brightness Controller Configuration:");
|
||||
@@ -484,18 +480,13 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
}
|
||||
|
||||
if (USE_TWILIGHT_ADJUSTMENT) {
|
||||
if (mUseTwilight) {
|
||||
TwilightState state = mTwilight.getCurrentState();
|
||||
if (state != null && state.isNight()) {
|
||||
final long now = System.currentTimeMillis();
|
||||
final float earlyGamma =
|
||||
getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
|
||||
final float lateGamma =
|
||||
getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
|
||||
gamma *= earlyGamma * lateGamma;
|
||||
gamma *= 1 + state.getAmount() * TWILIGHT_ADJUSTMENT_MAX_GAMMA;
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
|
||||
+ ", lateGamma=" + lateGamma);
|
||||
Slog.d(TAG, "updateAutoBrightness: twilight amount=" + state.getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -579,25 +570,6 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
}
|
||||
|
||||
private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
|
||||
if (lastSunset < 0 || nextSunrise < 0
|
||||
|| now < lastSunset || now > nextSunrise) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
|
||||
return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
|
||||
(float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
|
||||
}
|
||||
|
||||
if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
|
||||
return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
|
||||
(float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
|
||||
}
|
||||
|
||||
return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
|
||||
}
|
||||
|
||||
private final class AutomaticBrightnessHandler extends Handler {
|
||||
public AutomaticBrightnessHandler(Looper looper) {
|
||||
super(looper, null, true /*async*/);
|
||||
|
||||
@@ -615,7 +615,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
&& mPowerRequest.brightnessSetByUser;
|
||||
mAutomaticBrightnessController.configure(autoBrightnessEnabled,
|
||||
mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
|
||||
userInitiatedChange);
|
||||
userInitiatedChange, mPowerRequest.useTwilight);
|
||||
}
|
||||
|
||||
// Apply brightness boost.
|
||||
|
||||
@@ -49,6 +49,7 @@ import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.util.EventLog;
|
||||
import android.util.Slog;
|
||||
@@ -468,6 +469,9 @@ public final class PowerManagerService extends SystemService
|
||||
private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
|
||||
= new ArrayList<PowerManagerInternal.LowPowerModeListener>();
|
||||
|
||||
// True if brightness should be affected by twilight.
|
||||
private boolean mBrightnessUseTwilight;
|
||||
|
||||
private native void nativeInit();
|
||||
|
||||
private static native void nativeAcquireSuspendBlocker(String name);
|
||||
@@ -620,6 +624,9 @@ public final class PowerManagerService extends SystemService
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Settings.Secure.DOUBLE_TAP_TO_WAKE),
|
||||
false, mSettingsObserver, UserHandle.USER_ALL);
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
Secure.BRIGHTNESS_USE_TWILIGHT),
|
||||
false, mSettingsObserver, UserHandle.USER_ALL);
|
||||
// Go.
|
||||
readConfigurationLocked();
|
||||
updateSettingsLocked();
|
||||
@@ -726,6 +733,9 @@ public final class PowerManagerService extends SystemService
|
||||
Settings.System.SCREEN_BRIGHTNESS_MODE,
|
||||
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
|
||||
|
||||
mBrightnessUseTwilight = Settings.Secure.getIntForUser(resolver,
|
||||
Secure.BRIGHTNESS_USE_TWILIGHT, 0, UserHandle.USER_CURRENT) != 0;
|
||||
|
||||
final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
|
||||
Settings.Global.LOW_POWER_MODE, 0) != 0;
|
||||
final boolean autoLowPowerModeConfigured = Settings.Global.getInt(resolver,
|
||||
@@ -1997,6 +2007,7 @@ public final class PowerManagerService extends SystemService
|
||||
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
|
||||
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
|
||||
mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;
|
||||
mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
|
||||
|
||||
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
|
||||
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
|
||||
|
||||
@@ -20,5 +20,6 @@ import android.os.Handler;
|
||||
|
||||
public interface TwilightManager {
|
||||
void registerListener(TwilightListener listener, Handler handler);
|
||||
void unregisterListener(TwilightListener listener);
|
||||
TwilightState getCurrentState();
|
||||
}
|
||||
|
||||
@@ -19,12 +19,15 @@ package com.android.server.twilight;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.TwilightCalculator;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.ContentObserver;
|
||||
import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
@@ -33,6 +36,9 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.util.Slog;
|
||||
@@ -54,6 +60,26 @@ public final class TwilightService extends SystemService {
|
||||
static final String ACTION_UPDATE_TWILIGHT_STATE =
|
||||
"com.android.server.action.UPDATE_TWILIGHT_STATE";
|
||||
|
||||
// The amount of time after or before sunrise over which to start adjusting
|
||||
// twilight affected things. We want the change to happen gradually so that
|
||||
// it is below the threshold of perceptibility and so that the adjustment has
|
||||
// maximum effect well after dusk.
|
||||
private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
|
||||
|
||||
// Broadcast when twilight changes.
|
||||
public static final String ACTION_TWILIGHT_CHANGED = "android.intent.action.TWILIGHT_CHANGED";
|
||||
|
||||
public static final String EXTRA_IS_NIGHT = "isNight";
|
||||
public static final String EXTRA_AMOUNT = "amount";
|
||||
|
||||
// Amount of time the TwilightService will stay locked in an override state before switching
|
||||
// back to auto.
|
||||
private static final long RESET_TIME = DateUtils.HOUR_IN_MILLIS * 2;
|
||||
private static final String EXTRA_RESET_USER = "user";
|
||||
|
||||
private static final String ACTION_RESET_TWILIGHT_AUTO =
|
||||
"com.android.server.action.RESET_TWILIGHT_AUTO";
|
||||
|
||||
final Object mLock = new Object();
|
||||
|
||||
AlarmManager mAlarmManager;
|
||||
@@ -65,6 +91,10 @@ public final class TwilightService extends SystemService {
|
||||
|
||||
TwilightState mTwilightState;
|
||||
|
||||
private int mCurrentUser;
|
||||
private boolean mLocked;
|
||||
private boolean mBootCompleted;
|
||||
|
||||
public TwilightService(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -75,14 +105,93 @@ public final class TwilightService extends SystemService {
|
||||
mLocationManager = (LocationManager) getContext().getSystemService(
|
||||
Context.LOCATION_SERVICE);
|
||||
mLocationHandler = new LocationHandler();
|
||||
mCurrentUser = ActivityManager.getCurrentUser();
|
||||
|
||||
IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_USER_SWITCHED);
|
||||
filter.addAction(ACTION_UPDATE_TWILIGHT_STATE);
|
||||
getContext().registerReceiver(mUpdateLocationReceiver, filter);
|
||||
getContext().registerReceiver(mReceiver, filter);
|
||||
|
||||
publishLocalService(TwilightManager.class, mService);
|
||||
getContext().getContentResolver().registerContentObserver(
|
||||
Secure.getUriFor(Secure.TWILIGHT_MODE), false, mContentObserver, mCurrentUser);
|
||||
mContentObserver.onChange(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == PHASE_BOOT_COMPLETED) {
|
||||
mBootCompleted = true;
|
||||
sendBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
private void reregisterSettingObserver() {
|
||||
final ContentResolver contentResolver = getContext().getContentResolver();
|
||||
contentResolver.unregisterContentObserver(mContentObserver);
|
||||
contentResolver.registerContentObserver(Secure.getUriFor(Secure.TWILIGHT_MODE), false,
|
||||
mContentObserver, mCurrentUser);
|
||||
mContentObserver.onChange(true);
|
||||
}
|
||||
|
||||
private void setLockedState(TwilightState state) {
|
||||
synchronized (mLock) {
|
||||
// Make sure we aren't locked so we can set the state.
|
||||
mLocked = false;
|
||||
setTwilightState(state);
|
||||
// Make sure we leave the state locked, so it cant be changed.
|
||||
mLocked = true;
|
||||
// TODO: Don't bother updating state when locked.
|
||||
}
|
||||
}
|
||||
|
||||
private void setTwilightState(TwilightState state) {
|
||||
synchronized (mLock) {
|
||||
if (mLocked) {
|
||||
// State has been locked by secure setting, shouldn't be changed.
|
||||
return;
|
||||
}
|
||||
if (!Objects.equal(mTwilightState, state)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Twilight state changed: " + state);
|
||||
}
|
||||
|
||||
mTwilightState = state;
|
||||
|
||||
final int listenerLen = mListeners.size();
|
||||
for (int i = 0; i < listenerLen; i++) {
|
||||
mListeners.get(i).postUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
sendBroadcast();
|
||||
}
|
||||
|
||||
private void sendBroadcast() {
|
||||
synchronized (mLock) {
|
||||
if (mTwilightState == null) {
|
||||
return;
|
||||
}
|
||||
if (mBootCompleted) {
|
||||
Intent intent = new Intent(ACTION_TWILIGHT_CHANGED);
|
||||
intent.putExtra(EXTRA_IS_NIGHT, mTwilightState.isNight());
|
||||
intent.putExtra(EXTRA_AMOUNT, mTwilightState.getAmount());
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
||||
getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleReset() {
|
||||
long resetTime = System.currentTimeMillis() + RESET_TIME;
|
||||
Intent resetIntent = new Intent(ACTION_RESET_TWILIGHT_AUTO);
|
||||
resetIntent.putExtra(EXTRA_RESET_USER, mCurrentUser);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||
getContext(), 0, resetIntent, 0);
|
||||
mAlarmManager.cancel(pendingIntent);
|
||||
mAlarmManager.setExact(AlarmManager.RTC, resetTime, pendingIntent);
|
||||
}
|
||||
|
||||
private static class TwilightListenerRecord implements Runnable {
|
||||
@@ -133,24 +242,22 @@ public final class TwilightService extends SystemService {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void setTwilightState(TwilightState state) {
|
||||
synchronized (mLock) {
|
||||
if (!Objects.equal(mTwilightState, state)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Twilight state changed: " + state);
|
||||
@Override
|
||||
public void unregisterListener(TwilightListener listener) {
|
||||
synchronized (mLock) {
|
||||
for (int i = 0; i < mListeners.size(); i++) {
|
||||
if (mListeners.get(i).mListener == listener) {
|
||||
mListeners.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
mTwilightState = state;
|
||||
|
||||
final int listenerLen = mListeners.size();
|
||||
for (int i = 0; i < listenerLen; i++) {
|
||||
mListeners.get(i).postUpdate();
|
||||
if (mListeners.size() == 0) {
|
||||
mLocationHandler.disableLocationUpdates();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// The user has moved if the accuracy circles of the two locations don't overlap.
|
||||
private static boolean hasMoved(Location from, Location to) {
|
||||
@@ -183,6 +290,7 @@ public final class TwilightService extends SystemService {
|
||||
private static final int MSG_GET_NEW_LOCATION_UPDATE = 2;
|
||||
private static final int MSG_PROCESS_NEW_LOCATION = 3;
|
||||
private static final int MSG_DO_TWILIGHT_UPDATE = 4;
|
||||
private static final int MSG_DISABLE_LOCATION_UPDATES = 5;
|
||||
|
||||
private static final long LOCATION_UPDATE_MS = 24 * DateUtils.HOUR_IN_MILLIS;
|
||||
private static final long MIN_LOCATION_UPDATE_MS = 30 * DateUtils.MINUTE_IN_MILLIS;
|
||||
@@ -210,6 +318,10 @@ public final class TwilightService extends SystemService {
|
||||
sendEmptyMessage(MSG_ENABLE_LOCATION_UPDATES);
|
||||
}
|
||||
|
||||
public void disableLocationUpdates() {
|
||||
sendEmptyMessage(MSG_DISABLE_LOCATION_UPDATES);
|
||||
}
|
||||
|
||||
public void requestLocationUpdate() {
|
||||
sendEmptyMessage(MSG_GET_NEW_LOCATION_UPDATE);
|
||||
}
|
||||
@@ -311,6 +423,11 @@ public final class TwilightService extends SystemService {
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_DISABLE_LOCATION_UPDATES:
|
||||
mLocationManager.removeUpdates(mLocationListener);
|
||||
removeMessages(MSG_ENABLE_LOCATION_UPDATES);
|
||||
break;
|
||||
|
||||
case MSG_DO_TWILIGHT_UPDATE:
|
||||
updateTwilightState();
|
||||
break;
|
||||
@@ -368,11 +485,6 @@ public final class TwilightService extends SystemService {
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
// calculate yesterday's twilight
|
||||
mTwilightCalculator.calculateTwilight(now - DateUtils.DAY_IN_MILLIS,
|
||||
mLocation.getLatitude(), mLocation.getLongitude());
|
||||
final long yesterdaySunset = mTwilightCalculator.mSunset;
|
||||
|
||||
// calculate today's twilight
|
||||
mTwilightCalculator.calculateTwilight(now,
|
||||
mLocation.getLatitude(), mLocation.getLongitude());
|
||||
@@ -385,9 +497,19 @@ public final class TwilightService extends SystemService {
|
||||
mLocation.getLatitude(), mLocation.getLongitude());
|
||||
final long tomorrowSunrise = mTwilightCalculator.mSunrise;
|
||||
|
||||
float amount = 0;
|
||||
if (isNight) {
|
||||
if (todaySunrise == -1 || todaySunset == -1) {
|
||||
amount = 1;
|
||||
} else if (now > todaySunset) {
|
||||
amount = Math.min(1, (now - todaySunset) / (float) TWILIGHT_ADJUSTMENT_TIME);
|
||||
} else {
|
||||
amount = Math.max(0, 1
|
||||
- (todaySunrise - now) / (float) TWILIGHT_ADJUSTMENT_TIME);
|
||||
}
|
||||
}
|
||||
// set twilight state
|
||||
TwilightState state = new TwilightState(isNight, yesterdaySunset,
|
||||
todaySunrise, todaySunset, tomorrowSunrise);
|
||||
TwilightState state = new TwilightState(isNight, amount);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Updating twilight state: " + state);
|
||||
}
|
||||
@@ -402,12 +524,18 @@ public final class TwilightService extends SystemService {
|
||||
// add some extra time to be on the safe side.
|
||||
nextUpdate += DateUtils.MINUTE_IN_MILLIS;
|
||||
|
||||
if (now > todaySunset) {
|
||||
nextUpdate += tomorrowSunrise;
|
||||
} else if (now > todaySunrise) {
|
||||
nextUpdate += todaySunset;
|
||||
if (amount == 1 || amount == 0) {
|
||||
if (now > todaySunset) {
|
||||
nextUpdate += tomorrowSunrise;
|
||||
} else if (now > todaySunrise) {
|
||||
nextUpdate += todaySunset;
|
||||
} else {
|
||||
nextUpdate += todaySunrise;
|
||||
}
|
||||
} else {
|
||||
nextUpdate += todaySunrise;
|
||||
// This is the update rate while transitioning.
|
||||
// Leave at 10 min for now (one from above).
|
||||
nextUpdate += 9 * DateUtils.MINUTE_IN_MILLIS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,9 +551,37 @@ public final class TwilightService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mUpdateLocationReceiver = new BroadcastReceiver() {
|
||||
private final ContentObserver mContentObserver = new ContentObserver(new Handler()) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
super.onChange(selfChange);
|
||||
int value = Secure.getIntForUser(getContext().getContentResolver(),
|
||||
Secure.TWILIGHT_MODE, Secure.TWILIGHT_MODE_LOCKED_OFF, mCurrentUser);
|
||||
if (value == Secure.TWILIGHT_MODE_LOCKED_OFF) {
|
||||
setLockedState(new TwilightState(false, 0));
|
||||
} else if (value == Secure.TWILIGHT_MODE_LOCKED_ON) {
|
||||
setLockedState(new TwilightState(true, 1));
|
||||
} else if (value == Secure.TWILIGHT_MODE_AUTO_OVERRIDE_OFF) {
|
||||
setLockedState(new TwilightState(false, 0));
|
||||
scheduleReset();
|
||||
} else if (value == Secure.TWILIGHT_MODE_AUTO_OVERRIDE_ON) {
|
||||
setLockedState(new TwilightState(true, 1));
|
||||
scheduleReset();
|
||||
} else {
|
||||
mLocked = false;
|
||||
mLocationHandler.requestTwilightUpdate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
|
||||
mCurrentUser = ActivityManager.getCurrentUser();
|
||||
reregisterSettingObserver();
|
||||
return;
|
||||
}
|
||||
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())
|
||||
&& !intent.getBooleanExtra("state", false)) {
|
||||
// Airplane mode is now off!
|
||||
@@ -433,6 +589,12 @@ public final class TwilightService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ACTION_RESET_TWILIGHT_AUTO.equals(intent.getAction())) {
|
||||
int user = intent.getIntExtra(EXTRA_RESET_USER, 0);
|
||||
Settings.Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.TWILIGHT_MODE, Secure.TWILIGHT_MODE_AUTO, user);
|
||||
return;
|
||||
}
|
||||
// Time zone has changed or alarm expired.
|
||||
mLocationHandler.requestTwilightUpdate();
|
||||
}
|
||||
|
||||
@@ -25,20 +25,11 @@ import java.util.Date;
|
||||
*/
|
||||
public class TwilightState {
|
||||
private final boolean mIsNight;
|
||||
private final long mYesterdaySunset;
|
||||
private final long mTodaySunrise;
|
||||
private final long mTodaySunset;
|
||||
private final long mTomorrowSunrise;
|
||||
private final float mAmount;
|
||||
|
||||
TwilightState(boolean isNight,
|
||||
long yesterdaySunset,
|
||||
long todaySunrise, long todaySunset,
|
||||
long tomorrowSunrise) {
|
||||
TwilightState(boolean isNight, float amount) {
|
||||
mIsNight = isNight;
|
||||
mYesterdaySunset = yesterdaySunset;
|
||||
mTodaySunrise = todaySunrise;
|
||||
mTodaySunset = todaySunset;
|
||||
mTomorrowSunrise = tomorrowSunrise;
|
||||
mAmount = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,35 +40,11 @@ public class TwilightState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of yesterday's sunset in the System.currentTimeMillis() timebase,
|
||||
* or -1 if the sun never sets.
|
||||
* For twilight affects that change gradually over time, this is the amount they
|
||||
* should currently be in effect.
|
||||
*/
|
||||
public long getYesterdaySunset() {
|
||||
return mYesterdaySunset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of today's sunrise in the System.currentTimeMillis() timebase,
|
||||
* or -1 if the sun never rises.
|
||||
*/
|
||||
public long getTodaySunrise() {
|
||||
return mTodaySunrise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of today's sunset in the System.currentTimeMillis() timebase,
|
||||
* or -1 if the sun never sets.
|
||||
*/
|
||||
public long getTodaySunset() {
|
||||
return mTodaySunset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of tomorrow's sunrise in the System.currentTimeMillis() timebase,
|
||||
* or -1 if the sun never rises.
|
||||
*/
|
||||
public long getTomorrowSunrise() {
|
||||
return mTomorrowSunrise;
|
||||
public float getAmount() {
|
||||
return mAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,10 +55,7 @@ public class TwilightState {
|
||||
public boolean equals(TwilightState other) {
|
||||
return other != null
|
||||
&& mIsNight == other.mIsNight
|
||||
&& mYesterdaySunset == other.mYesterdaySunset
|
||||
&& mTodaySunrise == other.mTodaySunrise
|
||||
&& mTodaySunset == other.mTodaySunset
|
||||
&& mTomorrowSunrise == other.mTomorrowSunrise;
|
||||
&& mAmount == other.mAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,10 +67,7 @@ public class TwilightState {
|
||||
public String toString() {
|
||||
DateFormat f = DateFormat.getDateTimeInstance();
|
||||
return "{TwilightState: isNight=" + mIsNight
|
||||
+ ", mYesterdaySunset=" + f.format(new Date(mYesterdaySunset))
|
||||
+ ", mTodaySunrise=" + f.format(new Date(mTodaySunrise))
|
||||
+ ", mTodaySunset=" + f.format(new Date(mTodaySunset))
|
||||
+ ", mTomorrowSunrise=" + f.format(new Date(mTomorrowSunrise))
|
||||
+ ", mAmount=" + mAmount
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user