1 /* 2 * Copyright (C) 2019 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.tv.settings.device.display.daydream; 18 19 import static android.provider.Settings.Secure.ATTENTIVE_TIMEOUT; 20 import static android.provider.Settings.Secure.SLEEP_TIMEOUT; 21 22 import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected; 23 24 import android.app.tvsettings.TvSettingsEnums; 25 import android.os.Bundle; 26 import android.provider.Settings; 27 import android.text.format.DateUtils; 28 29 import androidx.annotation.Keep; 30 import androidx.preference.ListPreference; 31 import androidx.preference.Preference; 32 import androidx.preference.SwitchPreference; 33 34 import com.android.internal.logging.nano.MetricsProto; 35 import com.android.tv.settings.R; 36 import com.android.tv.settings.SettingsPreferenceFragment; 37 38 /** 39 * The energy saver screen in TV settings. 40 */ 41 @Keep 42 public class EnergySaverFragment extends SettingsPreferenceFragment implements 43 Preference.OnPreferenceChangeListener { 44 private static final String TAG = "EnergySaverFragment"; 45 private static final String KEY_SLEEP_TIME = "sleepTime"; 46 private static final String KEY_ALLOW_TURN_SCREEN_OFF = "allowTurnScreenOff"; 47 private static final int DEFAULT_SLEEP_TIME_MS = (int) (24 * DateUtils.HOUR_IN_MILLIS); 48 private SwitchPreference mAllowTurnScreenOffWithWakeLockPref; 49 private ListPreference mSleepTimePref; 50 51 @Override onCreatePreferences(Bundle bundle, String s)52 public void onCreatePreferences(Bundle bundle, String s) { 53 setPreferencesFromResource(R.xml.energy_saver, null); 54 mAllowTurnScreenOffWithWakeLockPref = findPreference(KEY_ALLOW_TURN_SCREEN_OFF); 55 mAllowTurnScreenOffWithWakeLockPref.setOnPreferenceChangeListener(this); 56 mAllowTurnScreenOffWithWakeLockPref.setVisible(showStandbyTimeout()); 57 updateAllowTurnScreenOffWithWakeLockPref(); 58 mSleepTimePref = findPreference(KEY_SLEEP_TIME); 59 if (allowTurnOffWithWakeLock()) { 60 int validatedAttentiveSleepTime = getValidatedTimeout(getAttentiveSleepTime()); 61 mSleepTimePref.setValue(String.valueOf(validatedAttentiveSleepTime)); 62 if (getAttentiveSleepTime() != validatedAttentiveSleepTime) { 63 setAttentiveSleepTime(validatedAttentiveSleepTime); 64 } 65 } else { 66 int validatedSleepTime = getValidatedTimeout(getSleepTime()); 67 mSleepTimePref.setValue(String.valueOf(validatedSleepTime)); 68 if (getSleepTime() != validatedSleepTime) { 69 setSleepTime(validatedSleepTime); 70 } 71 } 72 mSleepTimePref.setOnPreferenceChangeListener(this); 73 mSleepTimePref.setOnPreferenceClickListener( 74 preference -> { 75 logEntrySelected(TvSettingsEnums.SYSTEM_ENERGYSAVER_START_DELAY); 76 return false; 77 }); 78 } 79 showStandbyTimeout()80 private boolean showStandbyTimeout() { 81 return getResources().getBoolean(R.bool.config_show_standby_timeout); 82 } 83 allowTurnOffWithWakeLock()84 private boolean allowTurnOffWithWakeLock() { 85 return showStandbyTimeout() && mAllowTurnScreenOffWithWakeLockPref.isChecked(); 86 } 87 updateAllowTurnScreenOffWithWakeLockPref()88 private void updateAllowTurnScreenOffWithWakeLockPref() { 89 if (!mAllowTurnScreenOffWithWakeLockPref.isVisible()) { 90 return; 91 } 92 if (getSleepTime() == -1) { 93 mAllowTurnScreenOffWithWakeLockPref.setChecked(false); 94 mAllowTurnScreenOffWithWakeLockPref.setEnabled(false); 95 } else if (getAttentiveSleepTime() == -1) { 96 mAllowTurnScreenOffWithWakeLockPref.setChecked(false); 97 mAllowTurnScreenOffWithWakeLockPref.setEnabled(true); 98 } else { 99 mAllowTurnScreenOffWithWakeLockPref.setChecked(true); 100 mAllowTurnScreenOffWithWakeLockPref.setEnabled(true); 101 } 102 } 103 104 @Override getMetricsCategory()105 public int getMetricsCategory() { 106 return MetricsProto.MetricsEvent.DREAM; 107 } 108 109 @Override onPreferenceChange(Preference preference, Object newValue)110 public boolean onPreferenceChange(Preference preference, Object newValue) { 111 switch (preference.getKey()) { 112 case KEY_SLEEP_TIME: 113 final int newSleepTime = Integer.parseInt((String) newValue); 114 if (getSleepTimeEntryId(newSleepTime) != -1) { 115 logEntrySelected(getSleepTimeEntryId(newSleepTime)); 116 } 117 updateTimeOut(allowTurnOffWithWakeLock(), newSleepTime); 118 break; 119 case KEY_ALLOW_TURN_SCREEN_OFF: 120 updateTimeOut((boolean) newValue, Integer.parseInt(mSleepTimePref.getValue())); 121 break; 122 } 123 return true; 124 } 125 updateTimeOut(boolean allowTurnScreenOffWithWakeLock, int value)126 private void updateTimeOut(boolean allowTurnScreenOffWithWakeLock, int value) { 127 if (allowTurnScreenOffWithWakeLock) { 128 setSleepTime(value); 129 if (showStandbyTimeout()) { 130 setAttentiveSleepTime(value); 131 } 132 } else { 133 setSleepTime(value); 134 if (showStandbyTimeout()) { 135 setAttentiveSleepTime(-1); 136 } 137 } 138 updateAllowTurnScreenOffWithWakeLockPref(); 139 } 140 getSleepTime()141 private int getSleepTime() { 142 return Settings.Secure.getInt(getActivity().getContentResolver(), SLEEP_TIMEOUT, 143 DEFAULT_SLEEP_TIME_MS); 144 } 145 getAttentiveSleepTime()146 private int getAttentiveSleepTime() { 147 return Settings.Secure.getInt(getActivity().getContentResolver(), ATTENTIVE_TIMEOUT, 148 DEFAULT_SLEEP_TIME_MS); 149 } 150 setSleepTime(int ms)151 private void setSleepTime(int ms) { 152 Settings.Secure.putInt(getActivity().getContentResolver(), SLEEP_TIMEOUT, ms); 153 } 154 setAttentiveSleepTime(int ms)155 private void setAttentiveSleepTime(int ms) { 156 Settings.Secure.putInt(getActivity().getContentResolver(), ATTENTIVE_TIMEOUT, ms); 157 } 158 159 // The SLEEP_TIMEOUT and ATTENTIVE_TIMEOUT could be defined in overlay by OEMs. We validate the 160 // value to make sure that we select from the predefined options. If the value from overlay is 161 // not one of the predefined options, we round it to the closest predefined value, except -1. getValidatedTimeout(int purposedTimeout)162 private int getValidatedTimeout(int purposedTimeout) { 163 int validatedTimeout = DEFAULT_SLEEP_TIME_MS; 164 if (purposedTimeout < 0) { 165 return -1; 166 } 167 String[] optionsString = getResources().getStringArray(R.array.screen_off_timeout_values); 168 // Find the value from the predefined values that is closest to the proposed value except -1 169 int diff = Integer.MAX_VALUE; 170 for (String option : optionsString) { 171 if (Integer.parseInt(option) != -1) { 172 int currentDiff = Math.abs(purposedTimeout - Integer.parseInt(option)); 173 if (currentDiff < diff) { 174 diff = currentDiff; 175 validatedTimeout = Integer.parseInt(option); 176 } 177 } 178 } 179 return validatedTimeout; 180 } 181 182 // TODO(b/158783050): update logging for new options 4H, 8H, 24H. 183 // Map @array/screen_off_timeout_entries to defined log enum getSleepTimeEntryId(int sleepTimeValue)184 private int getSleepTimeEntryId(int sleepTimeValue) { 185 switch(sleepTimeValue) { 186 case -1: 187 return TvSettingsEnums.SYSTEM_ENERGYSAVER_START_DELAY_NEVER; 188 case 900000: 189 return TvSettingsEnums.SYSTEM_ENERGYSAVER_START_DELAY_15M; 190 case 1800000: 191 return TvSettingsEnums.SYSTEM_ENERGYSAVER_START_DELAY_30M; 192 case 3600000: 193 return TvSettingsEnums.SYSTEM_ENERGYSAVER_START_DELAY_1H; 194 case 43200000: 195 return TvSettingsEnums.SYSTEM_ENERGYSAVER_START_DELAY_12H; 196 default: 197 return -1; 198 } 199 } 200 201 @Override getPageId()202 protected int getPageId() { 203 return TvSettingsEnums.SYSTEM_ENERGYSAVER; 204 } 205 } 206