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