1 /* 2 * Copyright (C) 2015 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.system; 18 19 import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected; 20 import static com.android.tv.settings.util.InstrumentationUtils.logToggleInteracted; 21 22 import android.app.Activity; 23 import android.app.tvsettings.TvSettingsEnums; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.os.Bundle; 29 import android.os.SystemProperties; 30 import android.os.UserManager; 31 import android.provider.Settings; 32 import android.text.TextUtils; 33 import android.text.format.DateFormat; 34 35 import androidx.annotation.Keep; 36 import androidx.preference.ListPreference; 37 import androidx.preference.Preference; 38 import androidx.preference.SwitchPreference; 39 40 import com.android.settingslib.datetime.ZoneGetter; 41 import com.android.tv.settings.R; 42 import com.android.tv.settings.RestrictedPreferenceAdapter; 43 import com.android.tv.settings.SettingsPreferenceFragment; 44 45 import java.util.Calendar; 46 import java.util.Date; 47 48 /** 49 * The date and time screen in TV settings. 50 */ 51 @Keep 52 public class DateTimeFragment extends SettingsPreferenceFragment implements 53 Preference.OnPreferenceChangeListener { 54 55 private static final String KEY_AUTO_DATE_TIME = "auto_date_time"; 56 private static final String KEY_SET_DATE = "set_date"; 57 private static final String KEY_SET_TIME = "set_time"; 58 private static final String KEY_SET_TIME_ZONE = "set_time_zone"; 59 private static final String KEY_USE_24_HOUR = "use_24_hour"; 60 61 private static final String AUTO_DATE_TIME_NTP = "network"; 62 private static final String AUTO_DATE_TIME_TS = "transport_stream"; 63 private static final String AUTO_DATE_TIME_OFF = "off"; 64 65 private static final String HOURS_12 = "12"; 66 private static final String HOURS_24 = "24"; 67 68 // private TvInputManager mTvInputManager; 69 private final Calendar mDummyDate = Calendar.getInstance(); 70 71 private RestrictedPreferenceAdapter<Preference> mDatePref; 72 private RestrictedPreferenceAdapter<Preference> mTimePref; 73 private RestrictedPreferenceAdapter<Preference> mTimeZone; 74 private Preference mTime24Pref; 75 76 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 77 @Override 78 public void onReceive(Context context, Intent intent) { 79 final Activity activity = getActivity(); 80 if (activity != null) { 81 updateTimeAndDateDisplay(activity); 82 } 83 } 84 }; 85 newInstance()86 public static DateTimeFragment newInstance() { 87 return new DateTimeFragment(); 88 } 89 90 @Override onCreate(Bundle savedInstanceState)91 public void onCreate(Bundle savedInstanceState) { 92 // mTvInputManager = 93 // (TvInputManager) getActivity().getSystemService(Context.TV_INPUT_SERVICE); 94 super.onCreate(savedInstanceState); 95 } 96 97 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)98 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 99 setPreferencesFromResource(R.xml.date_time, null); 100 101 final boolean isRestricted = SecurityFragment.isRestrictedProfileInEffect(getContext()); 102 103 Preference datePref = findPreference(KEY_SET_DATE); 104 datePref.setVisible(!isRestricted); 105 106 Preference timePref = findPreference(KEY_SET_TIME); 107 timePref.setVisible(!isRestricted); 108 109 final boolean tsTimeCapable = SystemProperties.getBoolean("ro.config.ts.date.time", false); 110 final ListPreference autoDateTimePref = 111 (ListPreference) findPreference(KEY_AUTO_DATE_TIME); 112 autoDateTimePref.setValue(getAutoDateTimeState()); 113 autoDateTimePref.setOnPreferenceChangeListener(this); 114 if (tsTimeCapable) { 115 autoDateTimePref.setEntries(R.array.auto_date_time_ts_entries); 116 autoDateTimePref.setEntryValues(R.array.auto_date_time_ts_entry_values); 117 } 118 autoDateTimePref.setVisible(!isRestricted); 119 120 Preference timeZonePref = findPreference(KEY_SET_TIME_ZONE); 121 timeZonePref.setVisible(!isRestricted); 122 123 mTime24Pref = findPreference(KEY_USE_24_HOUR); 124 mTime24Pref.setOnPreferenceChangeListener(this); 125 126 final String userRestriction = UserManager.DISALLOW_CONFIG_DATE_TIME; 127 mDatePref = RestrictedPreferenceAdapter.adapt(datePref, userRestriction); 128 mTimePref = RestrictedPreferenceAdapter.adapt(timePref, userRestriction); 129 mTimeZone = RestrictedPreferenceAdapter.adapt(timeZonePref, userRestriction); 130 RestrictedPreferenceAdapter.adapt(autoDateTimePref, userRestriction); 131 } 132 133 @Override onResume()134 public void onResume() { 135 super.onResume(); 136 137 ((SwitchPreference)mTime24Pref).setChecked(is24Hour()); 138 139 // Register for time ticks and other reasons for time change 140 IntentFilter filter = new IntentFilter(); 141 filter.addAction(Intent.ACTION_TIME_TICK); 142 filter.addAction(Intent.ACTION_TIME_CHANGED); 143 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 144 getActivity().registerReceiver(mIntentReceiver, filter, null, null); 145 146 updateTimeAndDateDisplay(getActivity()); 147 updateTimeDateEnable(); 148 } 149 150 @Override onPause()151 public void onPause() { 152 super.onPause(); 153 getActivity().unregisterReceiver(mIntentReceiver); 154 } 155 updateTimeAndDateDisplay(Context context)156 private void updateTimeAndDateDisplay(Context context) { 157 final Calendar now = Calendar.getInstance(); 158 mDummyDate.setTimeZone(now.getTimeZone()); 159 // We use December 31st because it's unambiguous when demonstrating the date format. 160 // We use 13:00 so we can demonstrate the 12/24 hour options. 161 mDummyDate.set(now.get(Calendar.YEAR), 11, 31, 13, 0, 0); 162 Date dummyDate = mDummyDate.getTime(); 163 164 mDatePref.updatePreference(pref -> 165 pref.setSummary(DateFormat.getLongDateFormat(context).format(now.getTime()))); 166 mTimePref.updatePreference(pref -> 167 pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime()))); 168 mTimeZone.updatePreference(pref -> 169 pref.setSummary(ZoneGetter.getTimeZoneOffsetAndName(getActivity(), 170 now.getTimeZone(), now.getTime()))); 171 172 mTime24Pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(dummyDate)); 173 } 174 updateTimeDateEnable()175 private void updateTimeDateEnable() { 176 final boolean enable = TextUtils.equals(getAutoDateTimeState(), AUTO_DATE_TIME_OFF); 177 178 mDatePref.updatePreference(pref -> pref.setEnabled(enable)); 179 mTimePref.updatePreference(pref -> pref.setEnabled(enable)); 180 } 181 182 @Override onPreferenceChange(Preference preference, Object newValue)183 public boolean onPreferenceChange(Preference preference, Object newValue) { 184 if (TextUtils.equals(preference.getKey(), KEY_AUTO_DATE_TIME)) { 185 String value = (String) newValue; 186 if (TextUtils.equals(value, AUTO_DATE_TIME_NTP)) { 187 logEntrySelected(TvSettingsEnums.SYSTEM_DATE_TIME_AUTOMATIC_USE_NETWORK_TIME); 188 setAutoDateTime(true); 189 } else if (TextUtils.equals(value, AUTO_DATE_TIME_TS)) { 190 throw new IllegalStateException("TS date is not yet implemented"); 191 // mTvInputManager.syncTimefromBroadcast(true); 192 // setAutoDateTime(false); 193 } else if (TextUtils.equals(value, AUTO_DATE_TIME_OFF)) { 194 logEntrySelected(TvSettingsEnums.SYSTEM_DATE_TIME_AUTOMATIC_OFF); 195 setAutoDateTime(false); 196 } else { 197 throw new IllegalArgumentException("Unknown auto time value " + value); 198 } 199 updateTimeDateEnable(); 200 } else if (TextUtils.equals(preference.getKey(), KEY_USE_24_HOUR)) { 201 final boolean use24Hour = (Boolean) newValue; 202 logToggleInteracted(TvSettingsEnums.SYSTEM_DATE_TIME_USE_24_HOUR_FORMAT, use24Hour); 203 set24Hour(use24Hour); 204 timeUpdated(use24Hour); 205 } 206 return true; 207 } 208 209 @Override onPreferenceTreeClick(Preference preference)210 public boolean onPreferenceTreeClick(Preference preference) { 211 switch (preference.getKey()) { 212 case KEY_SET_DATE: 213 logEntrySelected(TvSettingsEnums.SYSTEM_DATE_TIME_SET_DATE); 214 break; 215 case KEY_SET_TIME: 216 logEntrySelected(TvSettingsEnums.SYSTEM_DATE_TIME_SET_TIME); 217 break; 218 } 219 return super.onPreferenceTreeClick(preference); 220 } 221 222 /* Get & Set values from the system settings */ 223 is24Hour()224 private boolean is24Hour() { 225 return DateFormat.is24HourFormat(getActivity()); 226 } 227 timeUpdated(boolean use24Hour)228 private void timeUpdated(boolean use24Hour) { 229 Intent timeChanged = new Intent(Intent.ACTION_TIME_CHANGED); 230 int timeFormatPreference = 231 use24Hour ? Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR 232 : Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR; 233 timeChanged.putExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, timeFormatPreference); 234 getContext().sendBroadcast(timeChanged); 235 } 236 set24Hour(boolean use24Hour)237 private void set24Hour(boolean use24Hour) { 238 Settings.System.putString(getContext().getContentResolver(), 239 Settings.System.TIME_12_24, 240 use24Hour ? HOURS_24 : HOURS_12); 241 } 242 setAutoDateTime(boolean on)243 private void setAutoDateTime(boolean on) { 244 Settings.Global.putInt(getContext().getContentResolver(), 245 Settings.Global.AUTO_TIME, on ? 1 : 0); 246 } 247 getAutoDateTimeState()248 private String getAutoDateTimeState() { 249 // if(mTvInputManager.isUseBroadcastDateTime()) { 250 // return AUTO_DATE_TIME_TS; 251 // } 252 253 int value = Settings.Global.getInt(getContext().getContentResolver(), 254 Settings.Global.AUTO_TIME, 0); 255 if(value > 0) { 256 return AUTO_DATE_TIME_NTP; 257 } 258 259 return AUTO_DATE_TIME_OFF; 260 } 261 262 @Override getPageId()263 protected int getPageId() { 264 return TvSettingsEnums.SYSTEM_DATE_TIME; 265 } 266 } 267