1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.display; 18 19 import android.app.Dialog; 20 import android.app.TimePickerDialog; 21 import android.content.Context; 22 import android.os.Bundle; 23 import android.support.v7.preference.DropDownPreference; 24 import android.support.v7.preference.Preference; 25 import android.support.v7.preference.TwoStatePreference; 26 import android.widget.TimePicker; 27 28 import com.android.internal.app.NightDisplayController; 29 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 30 import com.android.settings.R; 31 import com.android.settings.widget.SeekBarPreference; 32 import com.android.settings.SettingsPreferenceFragment; 33 34 import java.text.DateFormat; 35 import java.time.LocalTime; 36 import java.util.Calendar; 37 import java.util.TimeZone; 38 39 /** 40 * Settings screen for Night display. 41 */ 42 public class NightDisplaySettings extends SettingsPreferenceFragment 43 implements NightDisplayController.Callback, Preference.OnPreferenceChangeListener { 44 45 private static final String KEY_NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode"; 46 private static final String KEY_NIGHT_DISPLAY_START_TIME = "night_display_start_time"; 47 private static final String KEY_NIGHT_DISPLAY_END_TIME = "night_display_end_time"; 48 private static final String KEY_NIGHT_DISPLAY_ACTIVATED = "night_display_activated"; 49 private static final String KEY_NIGHT_DISPLAY_TEMPERATURE = "night_display_temperature"; 50 51 private static final int DIALOG_START_TIME = 0; 52 private static final int DIALOG_END_TIME = 1; 53 54 private NightDisplayController mController; 55 private DateFormat mTimeFormatter; 56 57 private DropDownPreference mAutoModePreference; 58 private Preference mStartTimePreference; 59 private Preference mEndTimePreference; 60 private TwoStatePreference mActivatedPreference; 61 private SeekBarPreference mTemperaturePreference; 62 63 @Override 64 public void onCreate(Bundle savedInstanceState) { 65 super.onCreate(savedInstanceState); 66 67 final Context context = getContext(); 68 mController = new NightDisplayController(context); 69 70 mTimeFormatter = android.text.format.DateFormat.getTimeFormat(context); 71 mTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); 72 73 mTemperaturePreference.setMax(convertTemperature(mController.getMinimumColorTemperature())); 74 mTemperaturePreference.setContinuousUpdates(true); 75 } 76 77 @Override 78 protected int getHelpResource() { 79 return R.string.help_url_night_display; 80 } 81 82 @Override 83 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 84 super.onCreatePreferences(savedInstanceState, rootKey); 85 86 // Load the preferences from xml. 87 addPreferencesFromResource(R.xml.night_display_settings); 88 mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.night_display_text); 89 mAutoModePreference = (DropDownPreference) findPreference(KEY_NIGHT_DISPLAY_AUTO_MODE); 90 mStartTimePreference = findPreference(KEY_NIGHT_DISPLAY_START_TIME); 91 mEndTimePreference = findPreference(KEY_NIGHT_DISPLAY_END_TIME); 92 mActivatedPreference = (TwoStatePreference) findPreference(KEY_NIGHT_DISPLAY_ACTIVATED); 93 mTemperaturePreference = (SeekBarPreference) findPreference(KEY_NIGHT_DISPLAY_TEMPERATURE); 94 95 mAutoModePreference.setEntries(new CharSequence[] { 96 getString(R.string.night_display_auto_mode_never), 97 getString(R.string.night_display_auto_mode_custom), 98 getString(R.string.night_display_auto_mode_twilight) 99 }); 100 mAutoModePreference.setEntryValues(new CharSequence[] { 101 String.valueOf(NightDisplayController.AUTO_MODE_DISABLED), 102 String.valueOf(NightDisplayController.AUTO_MODE_CUSTOM), 103 String.valueOf(NightDisplayController.AUTO_MODE_TWILIGHT) 104 }); 105 mAutoModePreference.setOnPreferenceChangeListener(this); 106 mActivatedPreference.setOnPreferenceChangeListener(this); 107 mTemperaturePreference.setOnPreferenceChangeListener(this); 108 } 109 110 @Override 111 public void onStart() { 112 super.onStart(); 113 114 // Listen for changes only while visible. 115 mController.setListener(this); 116 117 // Update the current state since it have changed while not visible. 118 onActivated(mController.isActivated()); 119 onAutoModeChanged(mController.getAutoMode()); 120 onCustomStartTimeChanged(mController.getCustomStartTime()); 121 onCustomEndTimeChanged(mController.getCustomEndTime()); 122 onColorTemperatureChanged(mController.getColorTemperature()); 123 onDisplayColorModeChanged(mController.getColorMode()); 124 } 125 126 @Override 127 public void onStop() { 128 super.onStop(); 129 130 // Stop listening for state changes. 131 mController.setListener(null); 132 } 133 134 @Override 135 public boolean onPreferenceTreeClick(Preference preference) { 136 if (preference == mStartTimePreference) { 137 showDialog(DIALOG_START_TIME); 138 return true; 139 } else if (preference == mEndTimePreference) { 140 showDialog(DIALOG_END_TIME); 141 return true; 142 } 143 return super.onPreferenceTreeClick(preference); 144 } 145 146 @Override 147 public Dialog onCreateDialog(final int dialogId) { 148 if (dialogId == DIALOG_START_TIME || dialogId == DIALOG_END_TIME) { 149 final LocalTime initialTime; 150 if (dialogId == DIALOG_START_TIME) { 151 initialTime = mController.getCustomStartTime(); 152 } else { 153 initialTime = mController.getCustomEndTime(); 154 } 155 156 final Context context = getContext(); 157 final boolean use24HourFormat = android.text.format.DateFormat.is24HourFormat(context); 158 return new TimePickerDialog(context, new TimePickerDialog.OnTimeSetListener() { 159 @Override 160 public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 161 final LocalTime time = LocalTime.of(hourOfDay, minute); 162 if (dialogId == DIALOG_START_TIME) { 163 mController.setCustomStartTime(time); 164 } else { 165 mController.setCustomEndTime(time); 166 } 167 } 168 }, initialTime.getHour(), initialTime.getMinute(), use24HourFormat); 169 } 170 return super.onCreateDialog(dialogId); 171 } 172 173 @Override 174 public int getDialogMetricsCategory(int dialogId) { 175 switch (dialogId) { 176 case DIALOG_START_TIME: 177 return MetricsEvent.DIALOG_NIGHT_DISPLAY_SET_START_TIME; 178 case DIALOG_END_TIME: 179 return MetricsEvent.DIALOG_NIGHT_DISPLAY_SET_END_TIME; 180 default: 181 return 0; 182 } 183 } 184 185 @Override 186 public void onActivated(boolean activated) { 187 mActivatedPreference.setChecked(activated); 188 mTemperaturePreference.setEnabled(activated); 189 } 190 191 @Override 192 public void onAutoModeChanged(int autoMode) { 193 mAutoModePreference.setValue(String.valueOf(autoMode)); 194 195 final boolean showCustomSchedule = autoMode == NightDisplayController.AUTO_MODE_CUSTOM; 196 mStartTimePreference.setVisible(showCustomSchedule); 197 mEndTimePreference.setVisible(showCustomSchedule); 198 } 199 200 @Override 201 public void onColorTemperatureChanged(int colorTemperature) { 202 mTemperaturePreference.setProgress(convertTemperature(colorTemperature)); 203 } 204 205 private String getFormattedTimeString(LocalTime localTime) { 206 final Calendar c = Calendar.getInstance(); 207 c.setTimeZone(mTimeFormatter.getTimeZone()); 208 c.set(Calendar.HOUR_OF_DAY, localTime.getHour()); 209 c.set(Calendar.MINUTE, localTime.getMinute()); 210 c.set(Calendar.SECOND, 0); 211 c.set(Calendar.MILLISECOND, 0); 212 return mTimeFormatter.format(c.getTime()); 213 } 214 215 /** 216 * Inverts and range-adjusts a raw value from the SeekBar (i.e. [0, maxTemp-minTemp]), or 217 * converts an inverted and range-adjusted value to the raw SeekBar value, depending on the 218 * adjustment status of the input. 219 */ 220 private int convertTemperature(int temperature) { 221 return mController.getMaximumColorTemperature() - temperature; 222 } 223 224 @Override 225 public void onCustomStartTimeChanged(LocalTime startTime) { 226 mStartTimePreference.setSummary(getFormattedTimeString(startTime)); 227 } 228 229 @Override 230 public void onCustomEndTimeChanged(LocalTime endTime) { 231 mEndTimePreference.setSummary(getFormattedTimeString(endTime)); 232 } 233 234 @Override 235 public boolean onPreferenceChange(Preference preference, Object newValue) { 236 if (preference == mAutoModePreference) { 237 return mController.setAutoMode(Integer.parseInt((String) newValue)); 238 } else if (preference == mActivatedPreference) { 239 return mController.setActivated((Boolean) newValue); 240 } else if (preference == mTemperaturePreference) { 241 return mController.setColorTemperature(convertTemperature((Integer) newValue)); 242 } 243 return false; 244 } 245 246 @Override 247 public int getMetricsCategory() { 248 return MetricsEvent.NIGHT_DISPLAY_SETTINGS; 249 } 250 } 251