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.app.timezonedetector.ManualTimeZoneSuggestion;
21 import android.app.timezonedetector.TimeZoneDetector;
22 import android.app.tvsettings.TvSettingsEnums;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.os.Bundle;
28 import android.text.TextUtils;
29 
30 import androidx.annotation.Keep;
31 import androidx.preference.CheckBoxPreference;
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceScreen;
34 
35 import com.android.settingslib.datetime.ZoneGetter;
36 import com.android.tv.settings.R;
37 import com.android.tv.settings.SettingsPreferenceFragment;
38 import com.android.tv.twopanelsettings.TwoPanelSettingsFragment;
39 
40 import java.util.ArrayList;
41 import java.util.Comparator;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.TimeZone;
45 
46 @Keep
47 public class TimeZoneFragment extends SettingsPreferenceFragment {
48 
49     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
50         @Override
51         public void onReceive(Context context, Intent intent) {
52             final Activity activity = getActivity();
53             if (activity != null) {
54                 updateZones();
55             }
56         }
57     };
58 
59     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)60     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
61         final Context themedContext = getPreferenceManager().getContext();
62         final PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(
63                 themedContext);
64         screen.setTitle(R.string.system_set_time_zone);
65         setPreferenceScreen(screen);
66 
67         final List<Map<String, Object>> zoneList = ZoneGetter.getZonesList(getActivity());
68         final List<ZonePreference> zonePrefs = new ArrayList<>(zoneList.size());
69         for (final Map<String, Object> zone : zoneList) {
70             zonePrefs.add(new ZonePreference(themedContext, zone));
71         }
72         zonePrefs.sort(new ZonePrefComparator());
73         for (final Preference zonePref : zonePrefs) {
74             screen.addPreference(zonePref);
75         }
76     }
77 
78     @Override
onResume()79     public void onResume() {
80         super.onResume();
81         // Register for zone changes
82         IntentFilter filter = new IntentFilter();
83         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
84         getActivity().registerReceiver(mIntentReceiver, filter, null, null);
85         updateZones();
86     }
87 
88     @Override
onPause()89     public void onPause() {
90         super.onPause();
91         getActivity().unregisterReceiver(mIntentReceiver);
92     }
93 
94     @Override
onPreferenceTreeClick(Preference preference)95     public boolean onPreferenceTreeClick(Preference preference) {
96         if (preference instanceof ZonePreference) {
97             // Update the system timezone value
98             final TimeZoneDetector timeZoneDetector =
99                     getActivity().getSystemService(TimeZoneDetector.class);
100             ManualTimeZoneSuggestion suggestion = TimeZoneDetector.createManualTimeZoneSuggestion(
101                     preference.getKey(), "Settings: Set time zone");
102             timeZoneDetector.suggestManualTimeZone(suggestion);
103             if (getParentFragment() instanceof TwoPanelSettingsFragment) {
104                 ((TwoPanelSettingsFragment) getParentFragment()).navigateBack();
105             } else if (!getFragmentManager().popBackStackImmediate()) {
106                 getActivity().finish();
107             }
108         }
109         return super.onPreferenceTreeClick(preference);
110     }
111 
updateZones()112     private void updateZones() {
113         final String id = TimeZone.getDefault().getID();
114         final PreferenceScreen screen = getPreferenceScreen();
115         final int count = screen.getPreferenceCount();
116         for (int i = 0; i < count; i++) {
117             final Preference pref = screen.getPreference(i);
118             if (!(pref instanceof ZonePreference)) {
119                 continue;
120             }
121             final ZonePreference zonePref = (ZonePreference) pref;
122             zonePref.setChecked(TextUtils.equals(zonePref.getKey(), id));
123         }
124     }
125 
126     private static class ZonePreference extends CheckBoxPreference {
127         Integer offset;
128 
ZonePreference(Context context, Map<? extends String, ?> zone)129         public ZonePreference(Context context, Map<? extends String, ?> zone) {
130             super(context);
131             setWidgetLayoutResource(R.layout.radio_preference_widget);
132             setKey((String) zone.get(ZoneGetter.KEY_ID));
133             setPersistent(false);
134             setTitle((String) zone.get(ZoneGetter.KEY_DISPLAYNAME));
135             setSummary((String) zone.get(ZoneGetter.KEY_GMT));
136             offset = (Integer) zone.get(ZoneGetter.KEY_OFFSET);
137         }
138     }
139 
140     private static class ZonePrefComparator implements Comparator<ZonePreference> {
compare(ZonePreference zone1, ZonePreference zone2)141         public int compare(ZonePreference zone1, ZonePreference zone2) {
142             final int firstResult = zone1.offset.compareTo(zone2.offset);
143             if (firstResult != 0) {
144                 return firstResult;
145             }
146             return zone1.getTitle().toString().compareTo(zone2.getTitle().toString());
147         }
148     }
149 
150     @Override
getPageId()151     protected int getPageId() {
152         return TvSettingsEnums.SYSTEM_DATE_TIME_SET_TIME_ZONE;
153     }
154 }
155