• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.settings.datetime.timezone;
18 
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.icu.text.Collator;
22 import android.icu.text.LocaleDisplayNames;
23 import android.os.Bundle;
24 import android.support.annotation.VisibleForTesting;
25 import android.util.Log;
26 
27 import com.android.internal.logging.nano.MetricsProto;
28 import com.android.settings.R;
29 import com.android.settings.core.SubSettingLauncher;
30 import com.android.settings.datetime.timezone.BaseTimeZoneAdapter.AdapterItem;
31 import com.android.settings.datetime.timezone.model.FilteredCountryTimeZones;
32 import com.android.settings.datetime.timezone.model.TimeZoneData;
33 
34 import java.util.ArrayList;
35 import java.util.Comparator;
36 import java.util.List;
37 import java.util.Set;
38 import java.util.TreeSet;
39 
40 /**
41  * Render a list of regions into a list view.
42  */
43 public class RegionSearchPicker extends BaseTimeZonePicker {
44     private static final int REQUEST_CODE_ZONE_PICKER = 1;
45     private static final String TAG = "RegionSearchPicker";
46 
47     private BaseTimeZoneAdapter<RegionItem> mAdapter;
48     private TimeZoneData mTimeZoneData;
49 
RegionSearchPicker()50     public RegionSearchPicker() {
51         super(R.string.date_time_select_region, R.string.date_time_search_region, true, true);
52     }
53 
54     @Override
getMetricsCategory()55     public int getMetricsCategory() {
56         return MetricsProto.MetricsEvent.SETTINGS_ZONE_PICKER_REGION;
57     }
58 
59     @Override
createAdapter(TimeZoneData timeZoneData)60     protected BaseTimeZoneAdapter createAdapter(TimeZoneData timeZoneData) {
61         mTimeZoneData = timeZoneData;
62         mAdapter = new BaseTimeZoneAdapter<>(createAdapterItem(timeZoneData.getRegionIds()),
63                 this::onListItemClick, getLocale(), false /* showItemSummary */,
64                     null /* headerText */);
65         return mAdapter;
66     }
67 
onListItemClick(RegionItem item)68     private void onListItemClick(RegionItem item) {
69         final String regionId = item.getId();
70         final FilteredCountryTimeZones countryTimeZones = mTimeZoneData.lookupCountryTimeZones(
71                 regionId);
72         final Activity activity = getActivity();
73         if (countryTimeZones == null || countryTimeZones.getTimeZoneIds().isEmpty()) {
74             Log.e(TAG, "Region has no time zones: " + regionId);
75             activity.setResult(Activity.RESULT_CANCELED);
76             activity.finish();
77             return;
78         }
79 
80         List<String> timeZoneIds = countryTimeZones.getTimeZoneIds();
81         // Choose the time zone associated the region if there is only one time zone in that region
82         if (timeZoneIds.size() == 1) {
83             final Intent resultData = new Intent()
84                     .putExtra(EXTRA_RESULT_REGION_ID, regionId)
85                     .putExtra(EXTRA_RESULT_TIME_ZONE_ID, timeZoneIds.get(0));
86             getActivity().setResult(Activity.RESULT_OK, resultData);
87             getActivity().finish();
88         } else {
89             // Launch the zone picker and let the user choose a time zone from the list of
90             // time zones associated with the region.
91             final Bundle args = new Bundle();
92             args.putString(RegionZonePicker.EXTRA_REGION_ID, regionId);
93             new SubSettingLauncher(getContext())
94                     .setDestination(RegionZonePicker.class.getCanonicalName())
95                     .setArguments(args)
96                     .setSourceMetricsCategory(getMetricsCategory())
97                     .setResultListener(this, REQUEST_CODE_ZONE_PICKER)
98                     .launch();
99         }
100     }
101 
102     @Override
onActivityResult(int requestCode, int resultCode, Intent data)103     public void onActivityResult(int requestCode, int resultCode, Intent data) {
104         if (requestCode == REQUEST_CODE_ZONE_PICKER) {
105             if (resultCode == Activity.RESULT_OK) {
106                 getActivity().setResult(Activity.RESULT_OK, data);
107             }
108             getActivity().finish();
109         }
110     }
111 
createAdapterItem(Set<String> regionIds)112     private List<RegionItem> createAdapterItem(Set<String> regionIds) {
113         final Collator collator = Collator.getInstance(getLocale());
114         final TreeSet<RegionItem> items = new TreeSet<>(new RegionInfoComparator(collator));
115         final LocaleDisplayNames localeDisplayNames = LocaleDisplayNames.getInstance(getLocale());
116         long i = 0;
117         for (String regionId : regionIds) {
118             String name = localeDisplayNames.regionDisplayName(regionId);
119             items.add(new RegionItem(i++, regionId, name));
120         }
121         return new ArrayList<>(items);
122     }
123 
124     @VisibleForTesting
125     static class RegionItem implements AdapterItem {
126 
127         private final String mId;
128         private final String mName;
129         private final long mItemId;
130         private final String[] mSearchKeys;
131 
RegionItem(long itemId, String id, String name)132         RegionItem(long itemId, String id, String name) {
133             mId = id;
134             mName = name;
135             mItemId = itemId;
136             // Allow to search with ISO_3166-1 alpha-2 code. It's handy for english users in some
137             // countries, e.g. US for United States. It's not best search keys for users, but
138             // ICU doesn't have the data for the alias names of a region.
139             mSearchKeys = new String[] {mId, mName};
140         }
141 
getId()142         public String getId() {
143             return mId;
144         }
145 
146         @Override
getTitle()147         public CharSequence getTitle() {
148             return mName;
149         }
150 
151         @Override
getSummary()152         public CharSequence getSummary() {
153             return null;
154         }
155 
156         @Override
getIconText()157         public String getIconText() {
158             return null;
159         }
160 
161         @Override
getCurrentTime()162         public String getCurrentTime() {
163             return null;
164         }
165 
166         @Override
getItemId()167         public long getItemId() {
168             return mItemId;
169         }
170 
171         @Override
getSearchKeys()172         public String[] getSearchKeys() {
173             return mSearchKeys;
174         }
175     }
176 
177     private static class RegionInfoComparator implements Comparator<RegionItem> {
178         private final Collator mCollator;
179 
RegionInfoComparator(Collator collator)180         RegionInfoComparator(Collator collator) {
181             mCollator = collator;
182         }
183 
184         @Override
compare(RegionItem r1, RegionItem r2)185         public int compare(RegionItem r1, RegionItem r2) {
186             return mCollator.compare(r1.getTitle(), r2.getTitle());
187         }
188     }
189 }
190