• 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.Context;
21 import android.content.Intent;
22 import android.content.res.Resources;
23 import android.icu.text.DateFormat;
24 import android.icu.text.SimpleDateFormat;
25 import android.icu.util.Calendar;
26 import android.support.annotation.Nullable;
27 
28 import com.android.settings.R;
29 import com.android.settings.datetime.timezone.model.TimeZoneData;
30 
31 import java.util.ArrayList;
32 import java.util.Date;
33 import java.util.List;
34 import java.util.Locale;
35 
36 /**
37  * Render a list of {@class TimeZoneInfo} into the list view in {@class BaseTimeZonePicker}
38  */
39 public abstract class BaseTimeZoneInfoPicker extends BaseTimeZonePicker {
40     protected static final String TAG = "RegionZoneSearchPicker";
41     protected ZoneAdapter mAdapter;
42 
BaseTimeZoneInfoPicker(int titleResId, int searchHintResId, boolean searchEnabled, boolean defaultExpandSearch)43     protected BaseTimeZoneInfoPicker(int titleResId, int searchHintResId,
44             boolean searchEnabled, boolean defaultExpandSearch) {
45         super(titleResId, searchHintResId, searchEnabled, defaultExpandSearch);
46     }
47 
48     @Override
createAdapter(TimeZoneData timeZoneData)49     protected BaseTimeZoneAdapter createAdapter(TimeZoneData timeZoneData) {
50         mAdapter = new ZoneAdapter(getContext(), getAllTimeZoneInfos(timeZoneData),
51                 this::onListItemClick, getLocale(), getHeaderText());
52         return mAdapter;
53     }
54 
55     /**
56      * @return the text shown in the header, or null to show no header.
57      */
getHeaderText()58     protected @Nullable CharSequence getHeaderText() {
59         return null;
60     }
61 
onListItemClick(TimeZoneInfoItem item)62     private void onListItemClick(TimeZoneInfoItem item) {
63         final TimeZoneInfo timeZoneInfo = item.mTimeZoneInfo;
64         getActivity().setResult(Activity.RESULT_OK, prepareResultData(timeZoneInfo));
65         getActivity().finish();
66     }
67 
prepareResultData(TimeZoneInfo selectedTimeZoneInfo)68     protected Intent prepareResultData(TimeZoneInfo selectedTimeZoneInfo) {
69         return new Intent().putExtra(EXTRA_RESULT_TIME_ZONE_ID, selectedTimeZoneInfo.getId());
70     }
71 
getAllTimeZoneInfos(TimeZoneData timeZoneData)72     public abstract List<TimeZoneInfo> getAllTimeZoneInfos(TimeZoneData timeZoneData);
73 
74     protected static class ZoneAdapter extends BaseTimeZoneAdapter<TimeZoneInfoItem> {
75 
ZoneAdapter(Context context, List<TimeZoneInfo> timeZones, OnListItemClickListener<TimeZoneInfoItem> onListItemClickListener, Locale locale, CharSequence headerText)76         public ZoneAdapter(Context context, List<TimeZoneInfo> timeZones,
77                 OnListItemClickListener<TimeZoneInfoItem> onListItemClickListener, Locale locale,
78                 CharSequence headerText) {
79             super(createTimeZoneInfoItems(context, timeZones, locale),
80                     onListItemClickListener, locale,  true /* showItemSummary */,
81                     headerText /* headerText */);
82         }
83 
createTimeZoneInfoItems(Context context, List<TimeZoneInfo> timeZones, Locale locale)84         private static List<TimeZoneInfoItem> createTimeZoneInfoItems(Context context,
85                 List<TimeZoneInfo> timeZones, Locale locale) {
86             final DateFormat currentTimeFormat = new SimpleDateFormat(
87                     android.text.format.DateFormat.getTimeFormatString(context), locale);
88             final ArrayList<TimeZoneInfoItem> results = new ArrayList<>(timeZones.size());
89             final Resources resources = context.getResources();
90             long i = 0;
91             for (TimeZoneInfo timeZone : timeZones) {
92                 results.add(new TimeZoneInfoItem(i++, timeZone, resources, currentTimeFormat));
93             }
94             return results;
95         }
96     }
97 
98     private static class TimeZoneInfoItem implements BaseTimeZoneAdapter.AdapterItem {
99         private final long mItemId;
100         private final TimeZoneInfo mTimeZoneInfo;
101         private final Resources mResources;
102         private final DateFormat mTimeFormat;
103         private final String mTitle;
104         private final String[] mSearchKeys;
105 
TimeZoneInfoItem(long itemId, TimeZoneInfo timeZoneInfo, Resources resources, DateFormat timeFormat)106         private TimeZoneInfoItem(long itemId, TimeZoneInfo timeZoneInfo, Resources resources,
107                 DateFormat timeFormat) {
108             mItemId = itemId;
109             mTimeZoneInfo = timeZoneInfo;
110             mResources = resources;
111             mTimeFormat = timeFormat;
112             mTitle = createTitle(timeZoneInfo);
113             mSearchKeys = new String[] { mTitle };
114         }
115 
createTitle(TimeZoneInfo timeZoneInfo)116         private static String createTitle(TimeZoneInfo timeZoneInfo) {
117             String name = timeZoneInfo.getExemplarLocation();
118             if (name == null) {
119                 name = timeZoneInfo.getGenericName();
120             }
121             if (name == null && timeZoneInfo.getTimeZone().inDaylightTime(new Date())) {
122                 name = timeZoneInfo.getDaylightName();
123             }
124             if (name == null) {
125                 name = timeZoneInfo.getStandardName();
126             }
127             if (name == null) {
128                 name = String.valueOf(timeZoneInfo.getGmtOffset());
129             }
130             return name;
131         }
132 
133         @Override
getTitle()134         public CharSequence getTitle() {
135             return mTitle;
136         }
137 
138         @Override
getSummary()139         public CharSequence getSummary() {
140             String name = mTimeZoneInfo.getGenericName();
141             if (name == null) {
142                 if (mTimeZoneInfo.getTimeZone().inDaylightTime(new Date())) {
143                     name = mTimeZoneInfo.getDaylightName();
144                 } else {
145                     name = mTimeZoneInfo.getStandardName();
146                 }
147             }
148 
149             // Ignore name / GMT offset if the title shows the same information
150             if (name == null || name.equals(mTitle)) {
151                 CharSequence gmtOffset = mTimeZoneInfo.getGmtOffset();
152                 return gmtOffset == null || gmtOffset.toString().equals(mTitle) ? "" : gmtOffset;
153             } else {
154                 return SpannableUtil.getResourcesText(mResources,
155                         R.string.zone_info_offset_and_name, mTimeZoneInfo.getGmtOffset(), name);
156             }
157         }
158 
159         @Override
getIconText()160         public String getIconText() {
161             return null;
162         }
163 
164         @Override
getCurrentTime()165         public String getCurrentTime() {
166             return mTimeFormat.format(Calendar.getInstance(mTimeZoneInfo.getTimeZone()));
167         }
168 
169         @Override
getItemId()170         public long getItemId() {
171             return mItemId;
172         }
173 
174         @Override
getSearchKeys()175         public String[] getSearchKeys() {
176             return mSearchKeys;
177         }
178     }
179 }
180