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