New time zone picker page
- Show current selected region and time zone in a 2 rows.
Defailed info of current selected time zone in footer
- Show option menu to switch to select UTC offset
- This picker will be changed to the default picker in a later CL
Bug: 73952488
Test: m RunSettingsRoboTests
Change-Id: Ia81bb022e1021369612f5bd60c2c1f4d08db2af8
(cherry picked from commit b7d588f341
)
This commit is contained in:
42
res/xml/time_zone_prefs.xml
Normal file
42
res/xml/time_zone_prefs.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:key="time_zone_settings_screen"
|
||||||
|
android:title="@string/date_time_set_timezone">
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="time_zone_region_preference_category">
|
||||||
|
<com.android.settingslib.RestrictedPreference
|
||||||
|
android:key="region"
|
||||||
|
android:title="@string/date_time_select_region"
|
||||||
|
android:summary="@string/summary_placeholder" />
|
||||||
|
<com.android.settingslib.RestrictedPreference
|
||||||
|
android:key="region_zone"
|
||||||
|
android:title="@string/date_time_select_zone"
|
||||||
|
android:summary="@string/summary_placeholder" />
|
||||||
|
<com.android.settingslib.widget.FooterPreference/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="time_zone_fixed_offset_preference_category">
|
||||||
|
<com.android.settingslib.RestrictedPreference
|
||||||
|
android:key="fixed_offset"
|
||||||
|
android:title="@string/date_time_select_fixed_offset_time_zones"
|
||||||
|
android:summary="@string/summary_placeholder"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
</PreferenceScreen>
|
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
public abstract class BaseTimeZonePreferenceController extends BasePreferenceController {
|
||||||
|
private OnPreferenceClickListener mOnClickListener;
|
||||||
|
|
||||||
|
protected BaseTimeZonePreferenceController(Context context, String preferenceKey) {
|
||||||
|
super(context, preferenceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAvailabilityStatus() {
|
||||||
|
return AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (mOnClickListener == null || !Objects.equal(getPreferenceKey(), preference.getKey())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOnClickListener.onClick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnClickListener(OnPreferenceClickListener listener) {
|
||||||
|
mOnClickListener = listener;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
public class FixedOffsetPreferenceController extends BaseTimeZonePreferenceController {
|
||||||
|
|
||||||
|
private static final String PREFERENCE_KEY = "fixed_offset";
|
||||||
|
|
||||||
|
private TimeZoneInfo mTimeZoneInfo;
|
||||||
|
|
||||||
|
public FixedOffsetPreferenceController(Context context) {
|
||||||
|
super(context, PREFERENCE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getSummary() {
|
||||||
|
// This is a Spannable object, which contains TTS span. It shouldn't be converted to String.
|
||||||
|
return mTimeZoneInfo == null ? "" : mTimeZoneInfo.getGmtOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZoneInfo(TimeZoneInfo timeZoneInfo) {
|
||||||
|
mTimeZoneInfo = timeZoneInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeZoneInfo getTimeZoneInfo() {
|
||||||
|
return mTimeZoneInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback when a preference is clicked in {@class TimeZoneSettings}
|
||||||
|
*/
|
||||||
|
public interface OnPreferenceClickListener {
|
||||||
|
void onClick();
|
||||||
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.icu.text.LocaleDisplayNames;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class RegionPreferenceController extends BaseTimeZonePreferenceController {
|
||||||
|
private static final String PREFERENCE_KEY = "region";
|
||||||
|
|
||||||
|
private final LocaleDisplayNames mLocaleDisplayNames;
|
||||||
|
private String mRegionId = "";
|
||||||
|
|
||||||
|
public RegionPreferenceController(Context context) {
|
||||||
|
super(context, PREFERENCE_KEY);
|
||||||
|
Locale locale = context.getResources().getConfiguration().getLocales().get(0);
|
||||||
|
mLocaleDisplayNames = LocaleDisplayNames.getInstance(locale);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getSummary() {
|
||||||
|
return mLocaleDisplayNames.regionDisplayName(mRegionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegionId(String regionId) {
|
||||||
|
mRegionId = regionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRegionId() {
|
||||||
|
return mRegionId;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
public class RegionZonePreferenceController extends BaseTimeZonePreferenceController {
|
||||||
|
private static final String PREFERENCE_KEY = "region_zone";
|
||||||
|
|
||||||
|
private TimeZoneInfo mTimeZoneInfo;
|
||||||
|
private boolean mIsClickable;
|
||||||
|
|
||||||
|
public RegionZonePreferenceController(Context context) {
|
||||||
|
super(context, PREFERENCE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAvailabilityStatus() {
|
||||||
|
return AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
super.updateState(preference);
|
||||||
|
preference.setEnabled(isClickable());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getSummary() {
|
||||||
|
return mTimeZoneInfo == null ? ""
|
||||||
|
: SpannableUtil.getResourcesText(mContext.getResources(),
|
||||||
|
R.string.zone_info_exemplar_location_and_offset,
|
||||||
|
mTimeZoneInfo.getExemplarLocation(), mTimeZoneInfo.getGmtOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZoneInfo(TimeZoneInfo timeZoneInfo) {
|
||||||
|
mTimeZoneInfo = timeZoneInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeZoneInfo getTimeZoneInfo() {
|
||||||
|
return mTimeZoneInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClickable(boolean clickable) {
|
||||||
|
mIsClickable = clickable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClickable() {
|
||||||
|
return mIsClickable;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.icu.impl.OlsonTimeZone;
|
||||||
|
import android.icu.text.DateFormat;
|
||||||
|
import android.icu.text.DisplayContext;
|
||||||
|
import android.icu.text.SimpleDateFormat;
|
||||||
|
import android.icu.util.Calendar;
|
||||||
|
import android.icu.util.TimeZone;
|
||||||
|
import android.icu.util.TimeZoneTransition;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settingslib.widget.FooterPreference;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class TimeZoneInfoPreferenceController extends BaseTimeZonePreferenceController {
|
||||||
|
private static final String PREFERENCE_KEY = FooterPreference.KEY_FOOTER;
|
||||||
|
|
||||||
|
private TimeZoneInfo mTimeZoneInfo;
|
||||||
|
private final DateFormat mDateFormat;
|
||||||
|
private final Date mDate;
|
||||||
|
|
||||||
|
public TimeZoneInfoPreferenceController(Context context) {
|
||||||
|
this(context, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
TimeZoneInfoPreferenceController(Context context, Date date) {
|
||||||
|
super(context, PREFERENCE_KEY);
|
||||||
|
mDateFormat = DateFormat.getDateInstance(SimpleDateFormat.LONG);
|
||||||
|
mDateFormat.setContext(DisplayContext.CAPITALIZATION_NONE);
|
||||||
|
mDate = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAvailabilityStatus() {
|
||||||
|
return AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
CharSequence formattedTimeZone = mTimeZoneInfo == null ? "" : formatInfo(mTimeZoneInfo);
|
||||||
|
preference.setTitle(formattedTimeZone);
|
||||||
|
preference.setVisible(mTimeZoneInfo != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZoneInfo(TimeZoneInfo timeZoneInfo) {
|
||||||
|
mTimeZoneInfo = timeZoneInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeZoneInfo getTimeZoneInfo() {
|
||||||
|
return mTimeZoneInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharSequence formatOffsetAndName(TimeZoneInfo item) {
|
||||||
|
String name = item.getGenericName();
|
||||||
|
if (name == null) {
|
||||||
|
if (item.getTimeZone().inDaylightTime(mDate)) {
|
||||||
|
name = item.getDaylightName();
|
||||||
|
} else {
|
||||||
|
name = item.getStandardName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
return item.getGmtOffset().toString();
|
||||||
|
} else {
|
||||||
|
return SpannableUtil.getResourcesText(mContext.getResources(),
|
||||||
|
R.string.zone_info_offset_and_name, item.getGmtOffset(),
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharSequence formatInfo(TimeZoneInfo item) {
|
||||||
|
final CharSequence offsetAndName = formatOffsetAndName(item);
|
||||||
|
final TimeZone timeZone = item.getTimeZone();
|
||||||
|
if (!timeZone.observesDaylightTime()) {
|
||||||
|
return mContext.getString(R.string.zone_info_footer_no_dst, offsetAndName);
|
||||||
|
}
|
||||||
|
|
||||||
|
final TimeZoneTransition nextDstTransition = findNextDstTransition(timeZone);
|
||||||
|
if (nextDstTransition == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final boolean toDst = nextDstTransition.getTo().getDSTSavings() != 0;
|
||||||
|
String timeType = toDst ? item.getDaylightName() : item.getStandardName();
|
||||||
|
if (timeType == null) {
|
||||||
|
// Fall back to generic "summer time" and "standard time" if the time zone has no
|
||||||
|
// specific names.
|
||||||
|
timeType = toDst ?
|
||||||
|
mContext.getString(R.string.zone_time_type_dst) :
|
||||||
|
mContext.getString(R.string.zone_time_type_standard);
|
||||||
|
|
||||||
|
}
|
||||||
|
final Calendar transitionTime = Calendar.getInstance(timeZone);
|
||||||
|
transitionTime.setTimeInMillis(nextDstTransition.getTime());
|
||||||
|
final String date = mDateFormat.format(transitionTime);
|
||||||
|
return SpannableUtil.getResourcesText(mContext.getResources(),
|
||||||
|
R.string.zone_info_footer, offsetAndName, timeType, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeZoneTransition findNextDstTransition(TimeZone timeZone) {
|
||||||
|
if (!(timeZone instanceof OlsonTimeZone)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final OlsonTimeZone olsonTimeZone = (OlsonTimeZone) timeZone;
|
||||||
|
TimeZoneTransition transition = olsonTimeZone.getNextTransition(
|
||||||
|
mDate.getTime(), /* inclusive */ false);
|
||||||
|
do {
|
||||||
|
if (transition.getTo().getDSTSavings() != transition.getFrom().getDSTSavings()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
transition = olsonTimeZone.getNextTransition(
|
||||||
|
transition.getTime(), /*inclusive */ false);
|
||||||
|
} while (transition != null);
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
372
src/com/android/settings/datetime/timezone/TimeZoneSettings.java
Normal file
372
src/com/android/settings/datetime/timezone/TimeZoneSettings.java
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.icu.util.TimeZone;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.SubSettingLauncher;
|
||||||
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
|
import com.android.settings.datetime.timezone.model.FilteredCountryTimeZones;
|
||||||
|
import com.android.settings.datetime.timezone.model.TimeZoneData;
|
||||||
|
import com.android.settings.datetime.timezone.model.TimeZoneDataLoader;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class displays a time zone picker either by regions or fixed offset time zones.
|
||||||
|
*/
|
||||||
|
public class TimeZoneSettings extends DashboardFragment {
|
||||||
|
|
||||||
|
private static final String TAG = "TimeZoneSettings";
|
||||||
|
|
||||||
|
private static final int MENU_BY_REGION = Menu.FIRST;
|
||||||
|
private static final int MENU_BY_OFFSET = Menu.FIRST + 1;
|
||||||
|
|
||||||
|
private static final int REQUEST_CODE_REGION_PICKER = 1;
|
||||||
|
private static final int REQUEST_CODE_ZONE_PICKER = 2;
|
||||||
|
private static final int REQUEST_CODE_FIXED_OFFSET_ZONE_PICKER = 3;
|
||||||
|
|
||||||
|
private static final String PREF_KEY_REGION = "time_zone_region";
|
||||||
|
private static final String PREF_KEY_REGION_CATEGORY = "time_zone_region_preference_category";
|
||||||
|
private static final String PREF_KEY_FIXED_OFFSET_CATEGORY =
|
||||||
|
"time_zone_fixed_offset_preference_category";
|
||||||
|
|
||||||
|
private Locale mLocale;
|
||||||
|
private boolean mSelectByRegion;
|
||||||
|
private TimeZoneData mTimeZoneData;
|
||||||
|
|
||||||
|
private String mSelectedTimeZoneId;
|
||||||
|
private TimeZoneInfo.Formatter mTimeZoneInfoFormatter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsProto.MetricsEvent.ZONE_PICKER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPreferenceScreenResId() {
|
||||||
|
return R.xml.time_zone_prefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getLogTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called during onAttach
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
@Override
|
||||||
|
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||||
|
mLocale = context.getResources().getConfiguration().getLocales().get(0);
|
||||||
|
mTimeZoneInfoFormatter = new TimeZoneInfo.Formatter(mLocale, new Date());
|
||||||
|
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||||
|
RegionPreferenceController regionPreferenceController =
|
||||||
|
new RegionPreferenceController(context);
|
||||||
|
regionPreferenceController.setOnClickListener(this::onRegionPreferenceClicked);
|
||||||
|
RegionZonePreferenceController regionZonePreferenceController =
|
||||||
|
new RegionZonePreferenceController(context);
|
||||||
|
regionZonePreferenceController.setOnClickListener(this::onRegionZonePreferenceClicked);
|
||||||
|
TimeZoneInfoPreferenceController timeZoneInfoPreferenceController =
|
||||||
|
new TimeZoneInfoPreferenceController(context);
|
||||||
|
FixedOffsetPreferenceController fixedOffsetPreferenceController =
|
||||||
|
new FixedOffsetPreferenceController(context);
|
||||||
|
fixedOffsetPreferenceController.setOnClickListener(this::onFixedOffsetPreferenceClicked);
|
||||||
|
|
||||||
|
controllers.add(regionPreferenceController);
|
||||||
|
controllers.add(regionZonePreferenceController);
|
||||||
|
controllers.add(timeZoneInfoPreferenceController);
|
||||||
|
controllers.add(fixedOffsetPreferenceController);
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle icicle) {
|
||||||
|
super.onCreate(icicle);
|
||||||
|
// Hide all interactive preferences
|
||||||
|
setPreferenceCategoryVisible((PreferenceCategory) findPreference(
|
||||||
|
PREF_KEY_REGION_CATEGORY), false);
|
||||||
|
setPreferenceCategoryVisible((PreferenceCategory) findPreference(
|
||||||
|
PREF_KEY_FIXED_OFFSET_CATEGORY), false);
|
||||||
|
|
||||||
|
// Start loading TimeZoneData
|
||||||
|
getLoaderManager().initLoader(0, null, new TimeZoneDataLoader.LoaderCreator(
|
||||||
|
getContext(), this::onTimeZoneDataReady));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (resultCode != Activity.RESULT_OK || data == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (requestCode) {
|
||||||
|
case REQUEST_CODE_REGION_PICKER:
|
||||||
|
case REQUEST_CODE_ZONE_PICKER: {
|
||||||
|
String regionId = data.getStringExtra(RegionSearchPicker.EXTRA_RESULT_REGION_ID);
|
||||||
|
String tzId = data.getStringExtra(RegionZonePicker.EXTRA_RESULT_TIME_ZONE_ID);
|
||||||
|
// Ignore the result if user didn't change the region or time zone.
|
||||||
|
if (!Objects.equals(regionId, use(RegionPreferenceController.class).getRegionId())
|
||||||
|
|| !Objects.equals(tzId, mSelectedTimeZoneId)) {
|
||||||
|
onRegionZoneChanged(regionId, tzId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case REQUEST_CODE_FIXED_OFFSET_ZONE_PICKER: {
|
||||||
|
String tzId = data.getStringExtra(FixedOffsetPicker.EXTRA_RESULT_TIME_ZONE_ID);
|
||||||
|
// Ignore the result if user didn't change the time zone.
|
||||||
|
if (tzId != null && !tzId.equals(mSelectedTimeZoneId)) {
|
||||||
|
onFixedOffsetZoneChanged(tzId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setTimeZoneData(TimeZoneData timeZoneData) {
|
||||||
|
mTimeZoneData = timeZoneData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onTimeZoneDataReady(TimeZoneData timeZoneData) {
|
||||||
|
if (mTimeZoneData == null && timeZoneData != null) {
|
||||||
|
mTimeZoneData = timeZoneData;
|
||||||
|
setupForCurrentTimeZone();
|
||||||
|
getActivity().invalidateOptionsMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRegionPreferenceClicked() {
|
||||||
|
startPickerFragment(RegionSearchPicker.class, new Bundle(), REQUEST_CODE_REGION_PICKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRegionZonePreferenceClicked() {
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putString(RegionZonePicker.EXTRA_REGION_ID,
|
||||||
|
use(RegionPreferenceController.class).getRegionId());
|
||||||
|
startPickerFragment(RegionZonePicker.class, args, REQUEST_CODE_ZONE_PICKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onFixedOffsetPreferenceClicked() {
|
||||||
|
startPickerFragment(FixedOffsetPicker.class, new Bundle(),
|
||||||
|
REQUEST_CODE_FIXED_OFFSET_ZONE_PICKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startPickerFragment(Class<? extends BaseTimeZonePicker> fragmentClass, Bundle args,
|
||||||
|
int resultRequestCode) {
|
||||||
|
new SubSettingLauncher(getContext())
|
||||||
|
.setDestination(fragmentClass.getCanonicalName())
|
||||||
|
.setArguments(args)
|
||||||
|
.setSourceMetricsCategory(getMetricsCategory())
|
||||||
|
.setResultListener(this, resultRequestCode)
|
||||||
|
.launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDisplayedRegion(String regionId) {
|
||||||
|
use(RegionPreferenceController.class).setRegionId(regionId);
|
||||||
|
updatePreferenceStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDisplayedTimeZoneInfo(String regionId, String tzId) {
|
||||||
|
final TimeZoneInfo tzInfo = tzId == null ? null : mTimeZoneInfoFormatter.format(tzId);
|
||||||
|
final FilteredCountryTimeZones countryTimeZones =
|
||||||
|
mTimeZoneData.lookupCountryTimeZones(regionId);
|
||||||
|
|
||||||
|
use(RegionZonePreferenceController.class).setTimeZoneInfo(tzInfo);
|
||||||
|
// Only clickable when the region has more than 1 time zones or no time zone is selected.
|
||||||
|
|
||||||
|
use(RegionZonePreferenceController.class).setClickable(tzInfo == null ||
|
||||||
|
(countryTimeZones != null && countryTimeZones.getTimeZoneIds().size() > 1));
|
||||||
|
use(TimeZoneInfoPreferenceController.class).setTimeZoneInfo(tzInfo);
|
||||||
|
|
||||||
|
updatePreferenceStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDisplayedFixedOffsetTimeZoneInfo(String tzId) {
|
||||||
|
if (isFixedOffset(tzId)) {
|
||||||
|
use(FixedOffsetPreferenceController.class).setTimeZoneInfo(
|
||||||
|
mTimeZoneInfoFormatter.format(tzId));
|
||||||
|
} else {
|
||||||
|
use(FixedOffsetPreferenceController.class).setTimeZoneInfo(null);
|
||||||
|
}
|
||||||
|
updatePreferenceStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRegionZoneChanged(String regionId, String tzId) {
|
||||||
|
FilteredCountryTimeZones countryTimeZones =
|
||||||
|
mTimeZoneData.lookupCountryTimeZones(regionId);
|
||||||
|
if (countryTimeZones == null || !countryTimeZones.getTimeZoneIds().contains(tzId)) {
|
||||||
|
Log.e(TAG, "Unknown time zone id is selected: " + tzId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSelectedTimeZoneId = tzId;
|
||||||
|
setDisplayedRegion(regionId);
|
||||||
|
setDisplayedTimeZoneInfo(regionId, mSelectedTimeZoneId);
|
||||||
|
saveTimeZone(regionId, mSelectedTimeZoneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onFixedOffsetZoneChanged(String tzId) {
|
||||||
|
mSelectedTimeZoneId = tzId;
|
||||||
|
setDisplayedFixedOffsetTimeZoneInfo(tzId);
|
||||||
|
saveTimeZone(null, mSelectedTimeZoneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveTimeZone(String regionId, String tzId) {
|
||||||
|
SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit();
|
||||||
|
if (regionId == null) {
|
||||||
|
editor.remove(PREF_KEY_REGION);
|
||||||
|
} else {
|
||||||
|
editor.putString(PREF_KEY_REGION, regionId);
|
||||||
|
}
|
||||||
|
editor.apply();
|
||||||
|
getActivity().getSystemService(AlarmManager.class).setTimeZone(tzId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
menu.add(0, MENU_BY_REGION, 0, R.string.zone_menu_by_region);
|
||||||
|
menu.add(0, MENU_BY_OFFSET, 0, R.string.zone_menu_by_offset);
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrepareOptionsMenu(Menu menu) {
|
||||||
|
// Do not show menu when data is not ready,
|
||||||
|
menu.findItem(MENU_BY_REGION).setVisible(mTimeZoneData != null && !mSelectByRegion);
|
||||||
|
menu.findItem(MENU_BY_OFFSET).setVisible(mTimeZoneData != null && mSelectByRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case MENU_BY_REGION:
|
||||||
|
setSelectByRegion(true);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case MENU_BY_OFFSET:
|
||||||
|
setSelectByRegion(false);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupForCurrentTimeZone() {
|
||||||
|
mSelectedTimeZoneId = TimeZone.getDefault().getID();
|
||||||
|
setSelectByRegion(!isFixedOffset(mSelectedTimeZoneId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFixedOffset(String tzId) {
|
||||||
|
return tzId.startsWith("Etc/GMT") || tzId.equals("Etc/UTC");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch the current view to select region or select fixed offset time zone.
|
||||||
|
* When showing the selected region, it guess the selected region from time zone id.
|
||||||
|
* See {@link #findRegionIdForTzId} for more info.
|
||||||
|
*/
|
||||||
|
private void setSelectByRegion(boolean selectByRegion) {
|
||||||
|
mSelectByRegion = selectByRegion;
|
||||||
|
setPreferenceCategoryVisible((PreferenceCategory) findPreference(
|
||||||
|
PREF_KEY_REGION_CATEGORY), selectByRegion);
|
||||||
|
setPreferenceCategoryVisible((PreferenceCategory) findPreference(
|
||||||
|
PREF_KEY_FIXED_OFFSET_CATEGORY), !selectByRegion);
|
||||||
|
final String localeRegionId = getLocaleRegionId();
|
||||||
|
final Set<String> allCountryIsoCodes = mTimeZoneData.getRegionIds();
|
||||||
|
|
||||||
|
String displayRegion = allCountryIsoCodes.contains(localeRegionId) ? localeRegionId : null;
|
||||||
|
setDisplayedRegion(displayRegion);
|
||||||
|
setDisplayedTimeZoneInfo(displayRegion, null);
|
||||||
|
|
||||||
|
if (!mSelectByRegion) {
|
||||||
|
setDisplayedFixedOffsetTimeZoneInfo(mSelectedTimeZoneId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String regionId = findRegionIdForTzId(mSelectedTimeZoneId);
|
||||||
|
if (regionId != null) {
|
||||||
|
setDisplayedRegion(regionId);
|
||||||
|
setDisplayedTimeZoneInfo(regionId, mSelectedTimeZoneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the a region associated with the specified time zone, based on the time zone data.
|
||||||
|
* If there are multiple regions associated with the given time zone, the priority will be given
|
||||||
|
* to the region the user last picked and the country in user's locale.
|
||||||
|
* @return null if no region associated with the time zone
|
||||||
|
*/
|
||||||
|
private String findRegionIdForTzId(String tzId) {
|
||||||
|
return findRegionIdForTzId(tzId,
|
||||||
|
getPreferenceManager().getSharedPreferences().getString(PREF_KEY_REGION, null),
|
||||||
|
getLocaleRegionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
String findRegionIdForTzId(String tzId, String sharePrefRegionId, String localeRegionId) {
|
||||||
|
final Set<String> matchedRegions = mTimeZoneData.lookupCountryCodesForZoneId(tzId);
|
||||||
|
if (matchedRegions.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (sharePrefRegionId != null && matchedRegions.contains(sharePrefRegionId)) {
|
||||||
|
return sharePrefRegionId;
|
||||||
|
}
|
||||||
|
if (localeRegionId != null && matchedRegions.contains(localeRegionId)) {
|
||||||
|
return localeRegionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchedRegions.toArray(new String[matchedRegions.size()])[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPreferenceCategoryVisible(PreferenceCategory category,
|
||||||
|
boolean isVisible) {
|
||||||
|
// Hiding category doesn't hide all the children preference. Set visibility of its children.
|
||||||
|
// Do not care grandchildren as time_zone_pref.xml has only 2 levels.
|
||||||
|
category.setVisible(isVisible);
|
||||||
|
for (int i = 0; i < category.getPreferenceCount(); i++) {
|
||||||
|
category.getPreference(i).setVisible(isVisible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLocaleRegionId() {
|
||||||
|
return mLocale.getCountry().toUpperCase(Locale.US);
|
||||||
|
}
|
||||||
|
}
|
@@ -24,3 +24,4 @@ com.android.settings.wifi.SavedAccessPointsWifiSettings
|
|||||||
com.android.settings.notification.ZenModeEventRuleSettings
|
com.android.settings.notification.ZenModeEventRuleSettings
|
||||||
com.android.settings.notification.ZenModeScheduleRuleSettings
|
com.android.settings.notification.ZenModeScheduleRuleSettings
|
||||||
com.android.settings.fuelgauge.RestrictedAppDetails
|
com.android.settings.fuelgauge.RestrictedAppDetails
|
||||||
|
com.android.settings.datetime.timezone.TimeZoneSettings
|
||||||
|
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class BaseTimeZonePreferenceControllerTest {
|
||||||
|
|
||||||
|
private Activity mActivity;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handlePreferenceTreeClick_correctKey_triggerOnClickListener() {
|
||||||
|
String prefKey = "key1";
|
||||||
|
TestClickListener clickListener = new TestClickListener();
|
||||||
|
TestPreference preference = new TestPreference(mActivity, prefKey);
|
||||||
|
TestPreferenceController controller = new TestPreferenceController(mActivity, prefKey);
|
||||||
|
controller.setOnClickListener(clickListener);
|
||||||
|
|
||||||
|
controller.handlePreferenceTreeClick(preference);
|
||||||
|
assertThat(clickListener.isClicked()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handlePreferenceTreeClick_wrongKey_triggerOnClickListener() {
|
||||||
|
String prefKey = "key1";
|
||||||
|
TestClickListener clickListener = new TestClickListener();
|
||||||
|
TestPreference preference = new TestPreference(mActivity, "wrong_key");
|
||||||
|
TestPreferenceController controller = new TestPreferenceController(mActivity, prefKey);
|
||||||
|
controller.setOnClickListener(clickListener);
|
||||||
|
|
||||||
|
controller.handlePreferenceTreeClick(preference);
|
||||||
|
assertThat(clickListener.isClicked()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestPreferenceController extends BaseTimeZonePreferenceController {
|
||||||
|
|
||||||
|
private final Preference mTestPreference;
|
||||||
|
|
||||||
|
public TestPreferenceController(Context context, String preferenceKey) {
|
||||||
|
super(context, preferenceKey);
|
||||||
|
mTestPreference = new Preference(context);
|
||||||
|
mTestPreference.setKey(preferenceKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestPreference extends Preference {
|
||||||
|
public TestPreference(Context context, String preferenceKey) {
|
||||||
|
super(context);
|
||||||
|
setKey(preferenceKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestClickListener implements OnPreferenceClickListener {
|
||||||
|
|
||||||
|
private boolean isClicked = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick() {
|
||||||
|
isClicked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClicked() {
|
||||||
|
return isClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.icu.util.TimeZone;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class FixedOffsetPreferenceControllerTest {
|
||||||
|
|
||||||
|
private Activity mActivity;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_matchTimeZoneSummary() {
|
||||||
|
TimeZoneInfo fixedOffsetZone = new TimeZoneInfo.Builder(
|
||||||
|
TimeZone.getFrozenTimeZone("Etc/GMT-8"))
|
||||||
|
.setExemplarLocation("Los Angeles")
|
||||||
|
.setGmtOffset("GMT-08:00")
|
||||||
|
.setItemId(0)
|
||||||
|
.build();
|
||||||
|
Preference preference = new Preference(mActivity);
|
||||||
|
FixedOffsetPreferenceController controller = new FixedOffsetPreferenceController(mActivity);
|
||||||
|
controller.setTimeZoneInfo(fixedOffsetZone);
|
||||||
|
controller.updateState(preference);
|
||||||
|
assertThat(preference.getSummary()).isEqualTo("GMT-08:00");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class RegionPreferenceControllerTest {
|
||||||
|
|
||||||
|
private Activity mActivity;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_matchCountryName() {
|
||||||
|
Preference preference = new Preference(mActivity);
|
||||||
|
RegionPreferenceController controller = new RegionPreferenceController(mActivity);
|
||||||
|
controller.setRegionId("US");
|
||||||
|
controller.updateState(preference);
|
||||||
|
assertThat(controller.getSummary()).isEqualTo("United States");
|
||||||
|
assertThat(preference.getSummary()).isEqualTo("United States");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.icu.util.TimeZone;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class RegionZonePreferenceControllerTest {
|
||||||
|
|
||||||
|
private Activity mActivity;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_matchTimeZoneName() {
|
||||||
|
TimeZoneInfo tzInfo = new TimeZoneInfo.Builder(
|
||||||
|
TimeZone.getFrozenTimeZone("America/Los_Angeles"))
|
||||||
|
.setGenericName("Pacific Time")
|
||||||
|
.setStandardName("Pacific Standard Time")
|
||||||
|
.setDaylightName("Pacific Daylight Time")
|
||||||
|
.setExemplarLocation("Los Angeles")
|
||||||
|
.setGmtOffset("GMT-08:00")
|
||||||
|
.setItemId(0)
|
||||||
|
.build();
|
||||||
|
Preference preference = new Preference(mActivity);
|
||||||
|
RegionZonePreferenceController controller = new RegionZonePreferenceController(mActivity);
|
||||||
|
controller.setTimeZoneInfo(tzInfo);
|
||||||
|
controller.setClickable(false);
|
||||||
|
controller.updateState(preference);
|
||||||
|
String expectedSummary = "Los Angeles (GMT-08:00)";
|
||||||
|
assertThat(controller.getSummary().toString()).isEqualTo(expectedSummary);
|
||||||
|
assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary);
|
||||||
|
assertThat(preference.isEnabled()).isFalse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class TimeZoneInfoPreferenceControllerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_matchExpectedFormattedText() {
|
||||||
|
Date now = new Date(0L); // 00:00 1/1/1970
|
||||||
|
Formatter formatter = new Formatter(Locale.US, now);
|
||||||
|
|
||||||
|
TimeZoneInfo timeZoneInfo = formatter.format("America/Los_Angeles");
|
||||||
|
TimeZoneInfoPreferenceController controller =
|
||||||
|
new TimeZoneInfoPreferenceController(RuntimeEnvironment.application, now);
|
||||||
|
controller.setTimeZoneInfo(timeZoneInfo);
|
||||||
|
Preference preference = spy(new Preference(RuntimeEnvironment.application));
|
||||||
|
controller.updateState(preference);
|
||||||
|
assertEquals("Uses Pacific Time (GMT-08:00). "
|
||||||
|
+ "Pacific Daylight Time starts on April 26, 1970.",
|
||||||
|
preference.getTitle().toString());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.datetime.timezone;
|
||||||
|
|
||||||
|
import com.android.settings.datetime.timezone.model.TimeZoneData;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(shadows = {
|
||||||
|
SettingsShadowResources.class,
|
||||||
|
SettingsShadowResources.SettingsShadowTheme.class,
|
||||||
|
})
|
||||||
|
public class TimeZoneSettingsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findRegionIdForTzId_matchExpectedCountry() {
|
||||||
|
String tzId = "Unknown/Secret_City";
|
||||||
|
TimeZoneData timeZoneData = mock(TimeZoneData.class);
|
||||||
|
when(timeZoneData.lookupCountryCodesForZoneId(tzId))
|
||||||
|
.thenReturn(new HashSet<>(Arrays.asList("US", "GB")));
|
||||||
|
|
||||||
|
TimeZoneSettings settings = new TimeZoneSettings();
|
||||||
|
settings.setTimeZoneData(timeZoneData);
|
||||||
|
assertThat(settings.findRegionIdForTzId(tzId, null, "")).matches("US|GB");
|
||||||
|
assertThat(settings.findRegionIdForTzId(tzId, "GB", "")).isEqualTo("GB");
|
||||||
|
assertThat(settings.findRegionIdForTzId(tzId, null, "GB")).isEqualTo("GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createPreferenceControllers_matchExpectedControllers() {
|
||||||
|
TimeZoneSettings settings = new TimeZoneSettings();
|
||||||
|
List<AbstractPreferenceController> controllers =
|
||||||
|
settings.createPreferenceControllers(RuntimeEnvironment.application);
|
||||||
|
assertThat(controllers).hasSize(4);
|
||||||
|
assertThat(controllers.get(0)).isInstanceOf(RegionPreferenceController.class);
|
||||||
|
assertThat(controllers.get(1)).isInstanceOf(RegionZonePreferenceController.class);
|
||||||
|
assertThat(controllers.get(2)).isInstanceOf(TimeZoneInfoPreferenceController.class);
|
||||||
|
assertThat(controllers.get(3)).isInstanceOf(FixedOffsetPreferenceController.class);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user