• 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.content.Context;
20 import android.icu.impl.OlsonTimeZone;
21 import android.icu.text.DateFormat;
22 import android.icu.text.DisplayContext;
23 import android.icu.text.SimpleDateFormat;
24 import android.icu.util.Calendar;
25 import android.icu.util.TimeZone;
26 import android.icu.util.TimeZoneTransition;
27 import android.support.annotation.VisibleForTesting;
28 import android.support.v7.preference.Preference;
29 
30 import com.android.settings.R;
31 import com.android.settingslib.widget.FooterPreference;
32 
33 import java.util.Date;
34 
35 public class TimeZoneInfoPreferenceController extends BaseTimeZonePreferenceController {
36 
37     private static final String PREFERENCE_KEY = FooterPreference.KEY_FOOTER;
38     @VisibleForTesting
39     Date mDate;
40     private TimeZoneInfo mTimeZoneInfo;
41     private final DateFormat mDateFormat;
42 
TimeZoneInfoPreferenceController(Context context)43     public TimeZoneInfoPreferenceController(Context context) {
44         super(context, PREFERENCE_KEY);
45         mDateFormat = DateFormat.getDateInstance(SimpleDateFormat.LONG);
46         mDateFormat.setContext(DisplayContext.CAPITALIZATION_NONE);
47         mDate = new Date();
48     }
49 
50     @Override
getAvailabilityStatus()51     public int getAvailabilityStatus() {
52         return AVAILABLE;
53     }
54 
55     @Override
updateState(Preference preference)56     public void updateState(Preference preference) {
57         CharSequence formattedTimeZone = mTimeZoneInfo == null ? "" : formatInfo(mTimeZoneInfo);
58         preference.setTitle(formattedTimeZone);
59         preference.setVisible(mTimeZoneInfo != null);
60     }
61 
setTimeZoneInfo(TimeZoneInfo timeZoneInfo)62     public void setTimeZoneInfo(TimeZoneInfo timeZoneInfo) {
63         mTimeZoneInfo = timeZoneInfo;
64     }
65 
getTimeZoneInfo()66     public TimeZoneInfo getTimeZoneInfo() {
67         return mTimeZoneInfo;
68     }
69 
formatOffsetAndName(TimeZoneInfo item)70     private CharSequence formatOffsetAndName(TimeZoneInfo item) {
71         String name = item.getGenericName();
72         if (name == null) {
73             if (item.getTimeZone().inDaylightTime(mDate)) {
74                 name = item.getDaylightName();
75             } else {
76                 name = item.getStandardName();
77             }
78         }
79         if (name == null) {
80             return item.getGmtOffset().toString();
81         } else {
82             return SpannableUtil.getResourcesText(mContext.getResources(),
83                     R.string.zone_info_offset_and_name, item.getGmtOffset(),
84                     name);
85         }
86     }
87 
formatInfo(TimeZoneInfo item)88     private CharSequence formatInfo(TimeZoneInfo item) {
89         final CharSequence offsetAndName = formatOffsetAndName(item);
90         final TimeZone timeZone = item.getTimeZone();
91         if (!timeZone.observesDaylightTime()) {
92             return mContext.getString(R.string.zone_info_footer_no_dst, offsetAndName);
93         }
94 
95         final TimeZoneTransition nextDstTransition = findNextDstTransition(timeZone);
96         if (nextDstTransition == null) {
97             return null;
98         }
99         final boolean toDst = nextDstTransition.getTo().getDSTSavings() != 0;
100         String timeType = toDst ? item.getDaylightName() : item.getStandardName();
101         if (timeType == null) {
102             // Fall back to generic "summer time" and "standard time" if the time zone has no
103             // specific names.
104             timeType = toDst ?
105                     mContext.getString(R.string.zone_time_type_dst) :
106                     mContext.getString(R.string.zone_time_type_standard);
107 
108         }
109         final Calendar transitionTime = Calendar.getInstance(timeZone);
110         transitionTime.setTimeInMillis(nextDstTransition.getTime());
111         final String date = mDateFormat.format(transitionTime);
112         return SpannableUtil.getResourcesText(mContext.getResources(),
113                 R.string.zone_info_footer, offsetAndName, timeType, date);
114     }
115 
findNextDstTransition(TimeZone timeZone)116     private TimeZoneTransition findNextDstTransition(TimeZone timeZone) {
117         if (!(timeZone instanceof OlsonTimeZone)) {
118             return null;
119         }
120         final OlsonTimeZone olsonTimeZone = (OlsonTimeZone) timeZone;
121         TimeZoneTransition transition = olsonTimeZone.getNextTransition(
122                 mDate.getTime(), /* inclusive */ false);
123         do {
124             if (transition.getTo().getDSTSavings() != transition.getFrom().getDSTSavings()) {
125                 break;
126             }
127             transition = olsonTimeZone.getNextTransition(
128                     transition.getTime(), /*inclusive */ false);
129         } while (transition != null);
130         return transition;
131     }
132 
133 }
134