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.SeekBarPreference; 32 import com.android.settings.SettingsPreferenceFragment; 33 34 import java.text.DateFormat; 35 import java.util.Calendar; 36 import java.util.TimeZone; 37 38 /** 39 * Settings screen for Night display. 40 */ 41 public class NightDisplaySettings extends SettingsPreferenceFragment 42 implements NightDisplayController.Callback, Preference.OnPreferenceChangeListener { 43 44 private static final String KEY_NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode"; 45 private static final String KEY_NIGHT_DISPLAY_START_TIME = "night_display_start_time"; 46 private static final String KEY_NIGHT_DISPLAY_END_TIME = "night_display_end_time"; 47 private static final String KEY_NIGHT_DISPLAY_ACTIVATED = "night_display_activated"; 48 private static final String KEY_NIGHT_DISPLAY_TEMPERATURE = "night_display_temperature"; 49 50 private static final int DIALOG_START_TIME = 0; 51 private static final int DIALOG_END_TIME = 1; 52 53 private NightDisplayController mController; 54 private DateFormat mTimeFormatter; 55 56 private DropDownPreference mAutoModePreference; 57 private Preference mStartTimePreference; 58 private Preference mEndTimePreference; 59 private TwoStatePreference mActivatedPreference; 60 private SeekBarPreference mTemperaturePreference; 61 62 @Override onCreate(Bundle savedInstanceState)63 public void onCreate(Bundle savedInstanceState) { 64 super.onCreate(savedInstanceState); 65 66 final Context context = getContext(); 67 mController = new NightDisplayController(context); 68 69 mTimeFormatter = android.text.format.DateFormat.getTimeFormat(context); 70 mTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); 71 72 mTemperaturePreference.setMax(convertTemperature(mController.getMinimumColorTemperature())); 73 mTemperaturePreference.setContinuousUpdates(true); 74 } 75 76 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)77 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 78 super.onCreatePreferences(savedInstanceState, rootKey); 79 80 // Load the preferences from xml. 81 addPreferencesFromResource(R.xml.night_display_settings); 82 mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.night_display_text); 83 mAutoModePreference = (DropDownPreference) findPreference(KEY_NIGHT_DISPLAY_AUTO_MODE); 84 mStartTimePreference = findPreference(KEY_NIGHT_DISPLAY_START_TIME); 85 mEndTimePreference = findPreference(KEY_NIGHT_DISPLAY_END_TIME); 86 mActivatedPreference = (TwoStatePreference) findPreference(KEY_NIGHT_DISPLAY_ACTIVATED); 87 mTemperaturePreference = (SeekBarPreference) findPreference(KEY_NIGHT_DISPLAY_TEMPERATURE); 88 89 mAutoModePreference.setEntries(new CharSequence[] { 90 getString(R.string.night_display_auto_mode_never), 91 getString(R.string.night_display_auto_mode_custom), 92 getString(R.string.night_display_auto_mode_twilight) 93 }); 94 mAutoModePreference.setEntryValues(new CharSequence[] { 95 String.valueOf(NightDisplayController.AUTO_MODE_DISABLED), 96 String.valueOf(NightDisplayController.AUTO_MODE_CUSTOM), 97 String.valueOf(NightDisplayController.AUTO_MODE_TWILIGHT) 98 }); 99 mAutoModePreference.setOnPreferenceChangeListener(this); 100 mActivatedPreference.setOnPreferenceChangeListener(this); 101 mTemperaturePreference.setOnPreferenceChangeListener(this); 102 } 103 104 @Override onStart()105 public void onStart() { 106 super.onStart(); 107 108 // Listen for changes only while visible. 109 mController.setListener(this); 110 111 // Update the current state since it have changed while not visible. 112 onActivated(mController.isActivated()); 113 onAutoModeChanged(mController.getAutoMode()); 114 onCustomStartTimeChanged(mController.getCustomStartTime()); 115 onCustomEndTimeChanged(mController.getCustomEndTime()); 116 onColorTemperatureChanged(mController.getColorTemperature()); 117 } 118 119 @Override onStop()120 public void onStop() { 121 super.onStop(); 122 123 // Stop listening for state changes. 124 mController.setListener(null); 125 } 126 127 @Override onPreferenceTreeClick(Preference preference)128 public boolean onPreferenceTreeClick(Preference preference) { 129 if (preference == mStartTimePreference) { 130 showDialog(DIALOG_START_TIME); 131 return true; 132 } else if (preference == mEndTimePreference) { 133 showDialog(DIALOG_END_TIME); 134 return true; 135 } 136 return super.onPreferenceTreeClick(preference); 137 } 138 139 @Override onCreateDialog(final int dialogId)140 public Dialog onCreateDialog(final int dialogId) { 141 if (dialogId == DIALOG_START_TIME || dialogId == DIALOG_END_TIME) { 142 final NightDisplayController.LocalTime initialTime; 143 if (dialogId == DIALOG_START_TIME) { 144 initialTime = mController.getCustomStartTime(); 145 } else { 146 initialTime = mController.getCustomEndTime(); 147 } 148 149 final Context context = getContext(); 150 final boolean use24HourFormat = android.text.format.DateFormat.is24HourFormat(context); 151 return new TimePickerDialog(context, new TimePickerDialog.OnTimeSetListener() { 152 @Override 153 public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 154 final NightDisplayController.LocalTime time = 155 new NightDisplayController.LocalTime(hourOfDay, minute); 156 if (dialogId == DIALOG_START_TIME) { 157 mController.setCustomStartTime(time); 158 } else { 159 mController.setCustomEndTime(time); 160 } 161 } 162 }, initialTime.hourOfDay, initialTime.minute, use24HourFormat); 163 } 164 return super.onCreateDialog(dialogId); 165 } 166 167 @Override 168 public int getDialogMetricsCategory(int dialogId) { 169 switch (dialogId) { 170 case DIALOG_START_TIME: 171 return MetricsEvent.DIALOG_NIGHT_DISPLAY_SET_START_TIME; 172 case DIALOG_END_TIME: 173 return MetricsEvent.DIALOG_NIGHT_DISPLAY_SET_END_TIME; 174 default: 175 return 0; 176 } 177 } 178 179 @Override 180 public void onActivated(boolean activated) { 181 mActivatedPreference.setChecked(activated); 182 mTemperaturePreference.setEnabled(activated); 183 } 184 185 @Override 186 public void onAutoModeChanged(int autoMode) { 187 mAutoModePreference.setValue(String.valueOf(autoMode)); 188 189 final boolean showCustomSchedule = autoMode == NightDisplayController.AUTO_MODE_CUSTOM; 190 mStartTimePreference.setVisible(showCustomSchedule); 191 mEndTimePreference.setVisible(showCustomSchedule); 192 } 193 194 @Override 195 public void onColorTemperatureChanged(int colorTemperature) { 196 mTemperaturePreference.setProgress(convertTemperature(colorTemperature)); 197 } 198 199 private String getFormattedTimeString(NightDisplayController.LocalTime localTime) { 200 final Calendar c = Calendar.getInstance(); 201 c.setTimeZone(mTimeFormatter.getTimeZone()); 202 c.set(Calendar.HOUR_OF_DAY, localTime.hourOfDay); 203 c.set(Calendar.MINUTE, localTime.minute); 204 c.set(Calendar.SECOND, 0); 205 c.set(Calendar.MILLISECOND, 0); 206 return mTimeFormatter.format(c.getTime()); 207 } 208 209 /** 210 * Inverts and range-adjusts a raw value from the SeekBar (i.e. [0, maxTemp-minTemp]), or 211 * converts an inverted and range-adjusted value to the raw SeekBar value, depending on the 212 * adjustment status of the input. 213 */ 214 private int convertTemperature(int temperature) { 215 return mController.getMaximumColorTemperature() - temperature; 216 } 217 218 @Override 219 public void onCustomStartTimeChanged(NightDisplayController.LocalTime startTime) { 220 mStartTimePreference.setSummary(getFormattedTimeString(startTime)); 221 } 222 223 @Override 224 public void onCustomEndTimeChanged(NightDisplayController.LocalTime endTime) { 225 mEndTimePreference.setSummary(getFormattedTimeString(endTime)); 226 } 227 228 @Override 229 public boolean onPreferenceChange(Preference preference, Object newValue) { 230 if (preference == mAutoModePreference) { 231 return mController.setAutoMode(Integer.parseInt((String) newValue)); 232 } else if (preference == mActivatedPreference) { 233 return mController.setActivated((Boolean) newValue); 234 } else if (preference == mTemperaturePreference) { 235 return mController.setColorTemperature(convertTemperature((Integer) newValue)); 236 } 237 return false; 238 } 239 240 @Override 241 public int getMetricsCategory() { 242 return MetricsEvent.NIGHT_DISPLAY_SETTINGS; 243 } 244 } 245