Merge changes Ie427a2d8,I213f1f76 into nyc-dev

* changes:
  SysUI Tuner: UI cleanup and grouping
  SysUI Tuner: Night mode v3
This commit is contained in:
Jason Monk
2016-02-19 18:50:04 +00:00
committed by Android (Google) Code Review
33 changed files with 1440 additions and 919 deletions

View File

@@ -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) {

View File

@@ -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.
*

View File

@@ -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 -->
<!-- ====================================================================== -->

View File

@@ -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.

View 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>

View File

@@ -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>

View File

@@ -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>

View 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>

View 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>

View File

@@ -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"

View File

@@ -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();

View File

@@ -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());

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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*/);

View File

@@ -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.

View File

@@ -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;

View File

@@ -20,5 +20,6 @@ import android.os.Handler;
public interface TwilightManager {
void registerListener(TwilightListener listener, Handler handler);
void unregisterListener(TwilightListener listener);
TwilightState getCurrentState();
}

View File

@@ -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();
}

View File

@@ -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
+ "}";
}
}