[Regional Preference] Add each option entry
- Add a entry in langauge and input page - Add new page for the options of Temperature unit, calendar type, first day of week, and numbering system. Bug: b/246929960 Test: atest pass Test: Manual test pass Change-Id: I69377fe9cd6dcd7a27c933a8dc98483df3da7665
This commit is contained in:
@@ -354,6 +354,24 @@
|
||||
<!-- Description for introduction of the locale selection supported of app list [CHAR LIMIT=NONE]-->
|
||||
<string name="desc_app_locale_selection_supported">Only apps that support language selection are shown here.</string>
|
||||
|
||||
<!-- Regional Preferences begin -->
|
||||
<!-- The title of the menu entry of regional preferences. [CHAR LIMIT=50] -->
|
||||
<string name="regional_preferences_title">Regional preferences</string>
|
||||
<!-- The summary of the menu entry of regional preferences. [CHAR LIMIT=NONE] -->
|
||||
<string name="regional_preferences_summary">Set units and number preferences</string>
|
||||
<!-- The subtitle of main page of regional preferences. [CHAR LIMIT=NONE] -->
|
||||
<string name="regional_preferences_main_page_sub_title">Apps can use your regional preferences to personalize your experience</string>
|
||||
<!-- The title of menu entry of Temperature unit preference. [CHAR LIMIT=50] -->
|
||||
<string name="temperature_preferences_title">Temperature</string>
|
||||
<!-- The title of the menu entry of Calendar type preference. [CHAR LIMIT=50] -->
|
||||
<string name="calendar_preferences_title">Calendar</string>
|
||||
<!-- The title of the menu entry of First day of week preference. [CHAR LIMIT=50] -->
|
||||
<string name="first_day_of_week_preferences_title">First day of week</string>
|
||||
<!-- The title of the menu entry of Numbers system preference. [CHAR LIMIT=50] -->
|
||||
<string name="numbers_preferences_title">Numbers</string>
|
||||
<!-- The summary of default string for each regional preference. [CHAR LIMIT=50] -->
|
||||
<string name="default_string_of_regional_preference">[No preference]</string>
|
||||
|
||||
<!-- The title of the confirmation dialog shown when the user selects one / several languages and tries to remove them [CHAR LIMIT=60] -->
|
||||
<string name="dlg_remove_locales_title">{count, plural,
|
||||
=1 {Remove selected language?}
|
||||
|
@@ -38,6 +38,15 @@
|
||||
android:name="classname"
|
||||
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:key="regional_preferences"
|
||||
android:title="@string/regional_preferences_title"
|
||||
android:summary="@string/regional_preferences_summary"
|
||||
android:fragment="com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment"
|
||||
settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesController">
|
||||
</Preference>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
49
res/xml/regional_preference_main_page.xml
Normal file
49
res/xml/regional_preference_main_page.xml
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2022 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"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/regional_preferences_title">
|
||||
|
||||
<com.android.settingslib.widget.TopIntroPreference
|
||||
android:title="@string/regional_preferences_main_page_sub_title"
|
||||
android:persistent="false" />
|
||||
|
||||
<Preference
|
||||
android:key="key_temperature_unit"
|
||||
android:title="@string/temperature_preferences_title"
|
||||
android:summary="@string/default_string_of_regional_preference"
|
||||
settings:controller="com.android.settings.regionalpreferences.TemperatureUnitController"/>
|
||||
|
||||
<Preference
|
||||
android:key="key_calendar_type"
|
||||
android:title="@string/calendar_preferences_title"
|
||||
android:summary="@string/default_string_of_regional_preference"
|
||||
settings:controller="com.android.settings.regionalpreferences.CalendarTypeController"/>
|
||||
|
||||
<Preference
|
||||
android:key="key_first_day_of_week"
|
||||
android:title="@string/first_day_of_week_preferences_title"
|
||||
android:summary="@string/default_string_of_regional_preference"
|
||||
settings:controller="com.android.settings.regionalpreferences.FirstDayOfWeekController"/>
|
||||
|
||||
<Preference
|
||||
android:key="key_numbering_system"
|
||||
android:title="@string/numbers_preferences_title"
|
||||
android:summary="@string/default_string_of_regional_preference"
|
||||
settings:controller="com.android.settings.regionalpreferences.NumberingSystemController"/>
|
||||
|
||||
</PreferenceScreen>
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A controller for the entry of Calendar types' page
|
||||
*/
|
||||
public class CalendarTypeController extends BasePreferenceController {
|
||||
public CalendarTypeController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link AvailabilityStatus} for the Setting. This status is used to determine if the
|
||||
* Setting should be shown or disabled in Settings. Further, it can be used to produce
|
||||
* appropriate error / warning Slice in the case of unavailability.
|
||||
* </p>
|
||||
* The status is used for the convenience methods: {@link #isAvailable()}, {@link
|
||||
* #isSupported()}
|
||||
* </p>
|
||||
* The inherited class doesn't need to check work profile if android:forWork="true" is set in
|
||||
* preference xml.
|
||||
*/
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
String record = Settings.System.getString(
|
||||
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
String result = "";
|
||||
if (record != null) {
|
||||
result = LocalePreferences.getCalendarType(Locale.forLanguageTag(record), false);
|
||||
}
|
||||
|
||||
if (result.isEmpty()) {
|
||||
result = LocalePreferences.getCalendarType(false);
|
||||
}
|
||||
return result.isEmpty()
|
||||
? mContext.getString(R.string.default_string_of_regional_preference) : result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/** A controller for the entry of First Day of Week's page */
|
||||
public class FirstDayOfWeekController extends BasePreferenceController {
|
||||
public FirstDayOfWeekController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link AvailabilityStatus} for the Setting. This status is used to determine if the
|
||||
* Setting should be shown or disabled in Settings. Further, it can be used to produce
|
||||
* appropriate error / warning Slice in the case of unavailability.
|
||||
* </p>
|
||||
* The status is used for the convenience methods: {@link #isAvailable()}, {@link
|
||||
* #isSupported()}
|
||||
* </p>
|
||||
* The inherited class doesn't need to check work profile if android:forWork="true" is set in
|
||||
* preference xml.
|
||||
*/
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
String record = Settings.System.getString(
|
||||
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
String result = "";
|
||||
if (record != null) {
|
||||
result = LocalePreferences.getFirstDayOfWeek(Locale.forLanguageTag(record), false);
|
||||
}
|
||||
|
||||
if (result.isEmpty()) {
|
||||
result = LocalePreferences.getFirstDayOfWeek(false);
|
||||
}
|
||||
return result.isEmpty()
|
||||
? mContext.getString(R.string.default_string_of_regional_preference) : result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,604 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
import android.icu.number.LocalizedNumberFormatter;
|
||||
import android.icu.number.NumberFormatter;
|
||||
import android.icu.text.DateFormat;
|
||||
import android.icu.text.DateTimePatternGenerator;
|
||||
import android.icu.util.MeasureUnit;
|
||||
import android.os.Build.VERSION;
|
||||
|
||||
import androidx.annotation.DoNotInline;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.annotation.RestrictTo;
|
||||
import androidx.annotation.StringDef;
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Locale;
|
||||
import java.util.Locale.Category;
|
||||
|
||||
/**
|
||||
* TODO(b/263861083) This is a temp file and will replace it to Androidx version.
|
||||
* Provides friendly APIs to get the user's locale preferences. The data can refer to
|
||||
* external/cldr/common/main/en.xml.
|
||||
*/
|
||||
public final class LocalePreferences {
|
||||
private static final String TAG = LocalePreferences.class.getSimpleName();
|
||||
|
||||
/** APIs to get the user's preference of the hour cycle. */
|
||||
public static class HourCycle {
|
||||
private static final String U_EXTENSION_OF_HOUR_CYCLE = "hc";
|
||||
|
||||
/** 12 Hour System (0-11) */
|
||||
public static final String H11 = "h11";
|
||||
/** 12 Hour System (1-12) */
|
||||
public static final String H12 = "h12";
|
||||
/** 24 Hour System (0-23) */
|
||||
public static final String H23 = "h23";
|
||||
/** 24 Hour System (1-24) */
|
||||
public static final String H24 = "h24";
|
||||
/** Default hour cycle for the locale */
|
||||
public static final String DEFAULT = "";
|
||||
|
||||
/** @hide */
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
@StringDef({
|
||||
H11,
|
||||
H12,
|
||||
H23,
|
||||
H24,
|
||||
DEFAULT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface HourCycleTypes {
|
||||
}
|
||||
|
||||
private HourCycle() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the hour cycle which is from
|
||||
* {@link Locale#getDefault(Locale.Category)}. The returned result is resolved and
|
||||
* bases on the {@code Locale#getDefault(Locale.Category)}. E.g. "h23"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@HourCycle.HourCycleTypes
|
||||
public static String getHourCycle() {
|
||||
return getHourCycle(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hour cycle setting of the inputted {@link Locale}. The returned result is resolved
|
||||
* and bases on the inputted {@code Locale}.
|
||||
* E.g. "h23"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@HourCycle.HourCycleTypes
|
||||
public static String getHourCycle(@NonNull Locale locale) {
|
||||
return getHourCycle(locale, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the hour cycle which is from
|
||||
* {@link Locale#getDefault(Locale.Category)}. E.g. "h23"
|
||||
*
|
||||
* @param resolved If the {@code Locale#getDefault(Locale.Category)} contains hour cycle subtag,
|
||||
* this argument is ignored. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain hour cycle subtag
|
||||
* and the resolved argument is true, this function tries to find the default
|
||||
* hour cycle for the {@code Locale#getDefault(Locale.Category)}. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain hour cycle subtag
|
||||
* and the resolved argument is false, this function returns empty string
|
||||
* i.e. HourCycle.Default.
|
||||
* @return {@link HourCycle.HourCycleTypes} If the malformed hour cycle format was specified
|
||||
* in the hour cycle subtag, e.g. en-US-u-hc-h32, this function returns empty string
|
||||
* i.e. HourCycle.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@HourCycle.HourCycleTypes
|
||||
public static String getHourCycle(
|
||||
boolean resolved) {
|
||||
return getHourCycle(Api33Impl.getDefaultLocale(), resolved);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hour cycle setting of the inputted {@link Locale}. E.g. "en-US-u-hc-h23".
|
||||
*
|
||||
* @param locale The {@code Locale} to get the hour cycle.
|
||||
* @param resolved If the given {@code Locale} contains hour cycle subtag, this argument is
|
||||
* ignored. If the given {@code Locale} doesn't contain hour cycle subtag and
|
||||
* the resolved argument is true, this function tries to find the default
|
||||
* hour cycle for the given {@code Locale}. If the given {@code Locale} doesn't
|
||||
* contain hour cycle subtag and the resolved argument is false, this function
|
||||
* return empty string i.e. HourCycle.Default.
|
||||
* @return {@link HourCycle.HourCycleTypes} If the malformed hour cycle format was specified
|
||||
* in the hour cycle subtag, e.g. en-US-u-hc-h32, this function returns empty string
|
||||
* i.e. HourCycle.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@HourCycle.HourCycleTypes
|
||||
public static String getHourCycle(@NonNull Locale locale, boolean resolved) {
|
||||
if (!BuildCompat.isAtLeastT()) {
|
||||
throw new IllegalArgumentException("not a valid extension: " + VERSION.SDK_INT);
|
||||
}
|
||||
return Api33Impl.getHourCycle(locale, resolved);
|
||||
}
|
||||
|
||||
/** APIs to get the user's preference of Calendar. */
|
||||
public static class CalendarType {
|
||||
private static final String U_EXTENSION_OF_CALENDAR = "ca";
|
||||
/** Chinese Calendar */
|
||||
public static final String CHINESE = "chinese";
|
||||
/** Dangi Calendar (Korea Calendar) */
|
||||
public static final String DANGI = "dangi";
|
||||
/** Gregorian Calendar */
|
||||
public static final String GREGORIAN = "gregorian";
|
||||
/** Hebrew Calendar */
|
||||
public static final String HEBREW = "hebrew";
|
||||
/** Indian National Calendar */
|
||||
public static final String INDIAN = "indian";
|
||||
/** Islamic Calendar */
|
||||
public static final String ISLAMIC = "islamic";
|
||||
/** Islamic Calendar (tabular, civil epoch) */
|
||||
public static final String ISLAMIC_CIVIL = "islamic-civil";
|
||||
/** Islamic Calendar (Saudi Arabia, sighting) */
|
||||
public static final String ISLAMIC_RGSA = "islamic-rgsa";
|
||||
/** Islamic Calendar (tabular, astronomical epoch) */
|
||||
public static final String ISLAMIC_TBLA = "islamic-tbla";
|
||||
/** Islamic Calendar (Umm al-Qura) */
|
||||
public static final String ISLAMIC_UMALQURA = "islamic-umalqura";
|
||||
/** Persian Calendar */
|
||||
public static final String PERSIAN = "persian";
|
||||
/** Default calendar for the locale */
|
||||
public static final String DEFAULT = "";
|
||||
|
||||
/** @hide */
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
@StringDef({
|
||||
CHINESE,
|
||||
DANGI,
|
||||
GREGORIAN,
|
||||
HEBREW,
|
||||
INDIAN,
|
||||
ISLAMIC,
|
||||
ISLAMIC_CIVIL,
|
||||
ISLAMIC_RGSA,
|
||||
ISLAMIC_TBLA,
|
||||
ISLAMIC_UMALQURA,
|
||||
PERSIAN,
|
||||
DEFAULT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface CalendarTypes {
|
||||
}
|
||||
|
||||
private CalendarType() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the calendar type which is from {@link
|
||||
* Locale#getDefault(Locale.Category)}. The returned result is resolved and bases on
|
||||
* the {@code Locale#getDefault(Locale.Category)} settings. E.g. "chinese"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@CalendarType.CalendarTypes
|
||||
public static String getCalendarType() {
|
||||
return getCalendarType(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the calendar type of the inputted {@link Locale}. The returned result is resolved and
|
||||
* bases on the inputted {@link Locale} settings.
|
||||
* E.g. "chinese"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@CalendarType.CalendarTypes
|
||||
public static String getCalendarType(@NonNull Locale locale) {
|
||||
return getCalendarType(locale, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the calendar type which is from {@link
|
||||
* Locale#getDefault(Locale.Category)}. E.g. "chinese"
|
||||
*
|
||||
* @param resolved If the {@code Locale#getDefault(Locale.Category)} contains calendar type
|
||||
* subtag, this argument is ignored. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain calendar type
|
||||
* subtag and the resolved argument is true, this function tries to find
|
||||
* the default calendar type for the
|
||||
* {@code Locale#getDefault(Locale.Category)}. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain calendar type
|
||||
* subtag and the resolved argument is false, this function returns empty string
|
||||
* i.e. CalendarTypes.Default.
|
||||
* @return {@link CalendarType.CalendarTypes} If the malformed calendar type format was
|
||||
* specified in the calendar type subtag, e.g. en-US-u-ca-calendar, this function returns
|
||||
* empty string i.e. CalendarTypes.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@CalendarType.CalendarTypes
|
||||
public static String getCalendarType(boolean resolved) {
|
||||
return getCalendarType(Api33Impl.getDefaultLocale(), resolved);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the calendar type of the inputted {@link Locale}. E.g. "chinese"
|
||||
*
|
||||
* @param locale The {@link Locale} to get the calendar type.
|
||||
* @param resolved If the given {@code Locale} contains calendar type subtag, this argument is
|
||||
* ignored. If the given {@code Locale} doesn't contain calendar type subtag and
|
||||
* the resolved argument is true, this function tries to find the default
|
||||
* calendar type for the given {@code Locale}. If the given {@code Locale}
|
||||
* doesn't contain calendar type subtag and the resolved argument is false, this
|
||||
* function return empty string i.e. CalendarTypes.Default.
|
||||
* @return {@link CalendarType.CalendarTypes} If the malformed calendar type format was
|
||||
* specified in the calendar type subtag, e.g. en-US-u-ca-calendar, this function returns
|
||||
* empty string i.e. CalendarTypes.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@CalendarType.CalendarTypes
|
||||
public static String getCalendarType(@NonNull Locale locale, boolean resolved) {
|
||||
if (!BuildCompat.isAtLeastT()) {
|
||||
throw new IllegalArgumentException("not a valid extension: " + VERSION.SDK_INT);
|
||||
}
|
||||
return Api33Impl.getCalendarType(locale, resolved);
|
||||
}
|
||||
|
||||
/** APIs to get the user's preference of temperature unit. */
|
||||
public static class TemperatureUnit {
|
||||
private static final String U_EXTENSION_OF_TEMPERATURE_UNIT = "mu";
|
||||
/** Celsius */
|
||||
public static final String CELSIUS = "celsius";
|
||||
/** Fahrenheit */
|
||||
public static final String FAHRENHEIT = "fahrenheit";
|
||||
/** Kelvin */
|
||||
public static final String KELVIN = "kelvin";
|
||||
/** Default Temperature for the locale */
|
||||
public static final String DEFAULT = "";
|
||||
|
||||
/** @hide */
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
@StringDef({
|
||||
CELSIUS,
|
||||
FAHRENHEIT,
|
||||
KELVIN,
|
||||
DEFAULT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface TemperatureUnits {
|
||||
}
|
||||
|
||||
private TemperatureUnit() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the temperature unit which is from {@link
|
||||
* Locale#getDefault(Locale.Category)}. The returned result is resolved and bases on the
|
||||
* {@code Locale#getDefault(Locale.Category)} settings. E.g. "fahrenheit"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@TemperatureUnit.TemperatureUnits
|
||||
public static String getTemperatureUnit() {
|
||||
return getTemperatureUnit(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temperature unit of the inputted {@link Locale}. The returned result is resolved
|
||||
* and bases on the inputted {@code Locale} settings. E.g. "fahrenheit"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@TemperatureUnit.TemperatureUnits
|
||||
public static String getTemperatureUnit(
|
||||
@NonNull Locale locale) {
|
||||
return getTemperatureUnit(locale, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the temperature unit which is from {@link
|
||||
* Locale#getDefault(Locale.Category)}. E.g. "fahrenheit"
|
||||
*
|
||||
* @param resolved If the {@code Locale#getDefault(Locale.Category)} contains temperature unit
|
||||
* subtag, this argument is ignored. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain temperature unit
|
||||
* subtag and the resolved argument is true, this function tries to find
|
||||
* the default temperature unit for the
|
||||
* {@code Locale#getDefault(Locale.Category)}. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain temperature unit
|
||||
* subtag and the resolved argument is false, this function returns empty string
|
||||
* i.e. TemperatureUnits.Default.
|
||||
* @return {@link TemperatureUnit.TemperatureUnits} If the malformed temperature unit format was
|
||||
* specified in the temperature unit subtag, e.g. en-US-u-mu-temperature, this function returns
|
||||
* empty string i.e. TemperatureUnits.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@TemperatureUnit.TemperatureUnits
|
||||
public static String getTemperatureUnit(boolean resolved) {
|
||||
return getTemperatureUnit(Api33Impl.getDefaultLocale(), resolved);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temperature unit of the inputted {@link Locale}. E.g. "fahrenheit"
|
||||
*
|
||||
* @param locale The {@link Locale} to get the temperature unit.
|
||||
* @param resolved If the given {@code Locale} contains temperature unit subtag, this argument
|
||||
* is ignored. If the given {@code Locale} doesn't contain temperature unit
|
||||
* subtag and the resolved argument is true, this function tries to find
|
||||
* the default temperature unit for the given {@code Locale}. If the given
|
||||
* {@code Locale} doesn't contain temperature unit subtag and the resolved
|
||||
* argument is false, this function return empty string
|
||||
* i.e. TemperatureUnits.Default.
|
||||
* @return {@link TemperatureUnit.TemperatureUnits} If the malformed temperature unit format was
|
||||
* specified in the temperature unit subtag, e.g. en-US-u-mu-temperature, this function returns
|
||||
* empty string i.e. TemperatureUnits.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@TemperatureUnit.TemperatureUnits
|
||||
public static String getTemperatureUnit(@NonNull Locale locale, boolean resolved) {
|
||||
if (!BuildCompat.isAtLeastT()) {
|
||||
throw new IllegalArgumentException("not a valid extension: " + VERSION.SDK_INT);
|
||||
}
|
||||
return Api33Impl.getTemperatureUnit(locale, resolved);
|
||||
}
|
||||
|
||||
/** APIs to get the user's preference of the first day of week. */
|
||||
public static class FirstDayOfWeek {
|
||||
private static final String U_EXTENSION_OF_FIRST_DAY_OF_WEEK = "fw";
|
||||
/** Sunday */
|
||||
public static final String SUNDAY = "sun";
|
||||
/** Monday */
|
||||
public static final String MONDAY = "mon";
|
||||
/** Tuesday */
|
||||
public static final String TUESDAY = "tue";
|
||||
/** Wednesday */
|
||||
public static final String WEDNESDAY = "wed";
|
||||
/** Thursday */
|
||||
public static final String THURSDAY = "thu";
|
||||
/** Friday */
|
||||
public static final String FRIDAY = "fri";
|
||||
/** Saturday */
|
||||
public static final String SATURDAY = "sat";
|
||||
/** Default first day of week for the locale */
|
||||
public static final String DEFAULT = "";
|
||||
|
||||
/** @hide */
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
@StringDef({
|
||||
SUNDAY,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
DEFAULT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Days {
|
||||
}
|
||||
|
||||
private FirstDayOfWeek() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the first day of week which is from
|
||||
* {@link Locale#getDefault(Locale.Category)}. The returned result is resolved and bases on the
|
||||
* {@code Locale#getDefault(Locale.Category)} settings. E.g. "sun"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@FirstDayOfWeek.Days
|
||||
public static String getFirstDayOfWeek() {
|
||||
return getFirstDayOfWeek(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first day of week of the inputted {@link Locale}. The returned result is resolved
|
||||
* and bases on the inputted {@code Locale} settings.
|
||||
* E.g. "sun"
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
public static @FirstDayOfWeek.Days String getFirstDayOfWeek(@NonNull Locale locale) {
|
||||
return getFirstDayOfWeek(locale, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user's preference of the first day of week which is from {@link
|
||||
* Locale#getDefault(Locale.Category)}. E.g. "sun"
|
||||
*
|
||||
* @param resolved If the {@code Locale#getDefault(Locale.Category)} contains first day of week
|
||||
* subtag, this argument is ignored. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain first day of week
|
||||
* subtag and the resolved argument is true, this function tries to find
|
||||
* the default first day of week for the
|
||||
* {@code Locale#getDefault(Locale.Category)}. If the
|
||||
* {@code Locale#getDefault(Locale.Category)} doesn't contain first day of week
|
||||
* subtag and the resolved argument is false, this function returns empty string
|
||||
* i.e. Days.Default.
|
||||
* @return {@link FirstDayOfWeek.Days} If the malformed first day of week format was specified
|
||||
* in the first day of week subtag, e.g. en-US-u-fw-days, this function returns empty string
|
||||
* i.e. Days.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@FirstDayOfWeek.Days
|
||||
public static String getFirstDayOfWeek(boolean resolved) {
|
||||
return getFirstDayOfWeek(Api33Impl.getDefaultLocale(), resolved);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first day of week of the inputted {@link Locale}. E.g. "sun"
|
||||
*
|
||||
* @param locale The {@link Locale} to get the first day of week.
|
||||
* @param resolved If the given {@code Locale} contains first day of week subtag, this argument
|
||||
* is ignored. If the given {@code Locale} doesn't contain first day of week
|
||||
* subtag and the resolved argument is true, this function tries to find
|
||||
* the default first day of week for the given {@code Locale}. If the given
|
||||
* {@code Locale} doesn't contain first day of week subtag and the resolved
|
||||
* argument is false, this function return empty string i.e. Days.Default.
|
||||
* @return {@link FirstDayOfWeek.Days} If the malformed first day of week format was
|
||||
* specified in the first day of week subtag, e.g. en-US-u-fw-days, this function returns
|
||||
* empty string i.e. Days.Default.
|
||||
*/
|
||||
@NonNull
|
||||
@OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
|
||||
@FirstDayOfWeek.Days
|
||||
public static String getFirstDayOfWeek(
|
||||
@NonNull Locale locale, boolean resolved) {
|
||||
if (!BuildCompat.isAtLeastT()) {
|
||||
throw new IllegalArgumentException("not a valid extension: " + VERSION.SDK_INT);
|
||||
}
|
||||
|
||||
return Api33Impl.getFirstDayOfWeek(locale, resolved);
|
||||
}
|
||||
|
||||
private static class Api33Impl {
|
||||
@DoNotInline
|
||||
@HourCycle.HourCycleTypes
|
||||
static String getHourCycle(@NonNull Locale locale,
|
||||
boolean resolved) {
|
||||
String hc = locale.getUnicodeLocaleType(HourCycle.U_EXTENSION_OF_HOUR_CYCLE);
|
||||
if (hc != null) {
|
||||
return hc;
|
||||
}
|
||||
if (!resolved) {
|
||||
return HourCycle.DEFAULT;
|
||||
}
|
||||
|
||||
return getHourCycleType(
|
||||
DateTimePatternGenerator.getInstance(locale).getDefaultHourCycle());
|
||||
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
@CalendarType.CalendarTypes
|
||||
static String getCalendarType(@NonNull Locale locale, boolean resolved) {
|
||||
String ca = locale.getUnicodeLocaleType(CalendarType.U_EXTENSION_OF_CALENDAR);
|
||||
if (ca != null) {
|
||||
return ca;
|
||||
}
|
||||
if (!resolved) {
|
||||
return CalendarType.DEFAULT;
|
||||
}
|
||||
|
||||
return android.icu.util.Calendar.getInstance(locale).getType();
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
@TemperatureUnit.TemperatureUnits
|
||||
static String getTemperatureUnit(@NonNull Locale locale, boolean resolved) {
|
||||
String mu =
|
||||
locale.getUnicodeLocaleType(TemperatureUnit.U_EXTENSION_OF_TEMPERATURE_UNIT);
|
||||
if (mu != null) {
|
||||
if (mu.contains("fahrenhe")) {
|
||||
mu = TemperatureUnit.FAHRENHEIT;
|
||||
}
|
||||
return mu;
|
||||
}
|
||||
if (!resolved) {
|
||||
return TemperatureUnit.DEFAULT;
|
||||
}
|
||||
|
||||
return getResolvedTemperatureUnit(locale);
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
@FirstDayOfWeek.Days
|
||||
static String getFirstDayOfWeek(@NonNull Locale locale, boolean resolved) {
|
||||
String mu =
|
||||
locale.getUnicodeLocaleType(FirstDayOfWeek.U_EXTENSION_OF_FIRST_DAY_OF_WEEK);
|
||||
if (mu != null) {
|
||||
return mu;
|
||||
}
|
||||
if (!resolved) {
|
||||
return FirstDayOfWeek.DEFAULT;
|
||||
}
|
||||
// TODO(b/262294472) Use {@code android.icu.util.Calendar} instead of
|
||||
// {@code java.util.Calendar}.
|
||||
return getStringOfFirstDayOfWeek(
|
||||
java.util.Calendar.getInstance(locale).getFirstDayOfWeek());
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
static Locale getDefaultLocale() {
|
||||
return Locale.getDefault(Category.FORMAT);
|
||||
}
|
||||
|
||||
private static String getStringOfFirstDayOfWeek(int fw) {
|
||||
String[] arrDays = {
|
||||
FirstDayOfWeek.SUNDAY,
|
||||
FirstDayOfWeek.MONDAY,
|
||||
FirstDayOfWeek.TUESDAY,
|
||||
FirstDayOfWeek.WEDNESDAY,
|
||||
FirstDayOfWeek.THURSDAY,
|
||||
FirstDayOfWeek.FRIDAY,
|
||||
FirstDayOfWeek.SATURDAY};
|
||||
|
||||
return fw >= 1 && fw <= 7 ? arrDays[fw - 1] : FirstDayOfWeek.DEFAULT;
|
||||
}
|
||||
|
||||
@HourCycle.HourCycleTypes
|
||||
private static String getHourCycleType(
|
||||
DateFormat.HourCycle hourCycle) {
|
||||
switch (hourCycle) {
|
||||
case HOUR_CYCLE_11:
|
||||
return HourCycle.H11;
|
||||
case HOUR_CYCLE_12:
|
||||
return HourCycle.H12;
|
||||
case HOUR_CYCLE_23:
|
||||
return HourCycle.H23;
|
||||
case HOUR_CYCLE_24:
|
||||
return HourCycle.H24;
|
||||
default:
|
||||
return HourCycle.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
@TemperatureUnit.TemperatureUnits
|
||||
private static String getResolvedTemperatureUnit(@NonNull Locale locale) {
|
||||
LocalizedNumberFormatter nf = NumberFormatter.with()
|
||||
.usage("temperature")
|
||||
.unit(MeasureUnit.CELSIUS)
|
||||
.locale(locale);
|
||||
return nf.format(1).getOutputUnit().getIdentifier();
|
||||
}
|
||||
|
||||
private Api33Impl() {
|
||||
}
|
||||
}
|
||||
|
||||
private LocalePreferences() {
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.icu.text.NumberingSystem;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/** A controller for the entry of Numbering System's page */
|
||||
public class NumberingSystemController extends BasePreferenceController {
|
||||
private static final String UNICODE_EXTENSION_NUMBERING_SYSTEM = "nu";
|
||||
|
||||
public NumberingSystemController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link AvailabilityStatus} for the Setting. This status is used to determine if the
|
||||
* Setting should be shown or disabled in Settings. Further, it can be used to produce
|
||||
* appropriate error / warning Slice in the case of unavailability.
|
||||
* </p>
|
||||
* The status is used for the convenience methods: {@link #isAvailable()}, {@link
|
||||
* #isSupported()}
|
||||
* </p>
|
||||
* The inherited class doesn't need to check work profile if android:forWork="true" is set in
|
||||
* preference xml.
|
||||
*/
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
String record = Settings.System.getString(
|
||||
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
String result = "";
|
||||
if (!TextUtils.isEmpty(record)) {
|
||||
result = Locale.forLanguageTag(record)
|
||||
.getUnicodeLocaleType(UNICODE_EXTENSION_NUMBERING_SYSTEM);
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(result)) {
|
||||
result = Locale.getDefault(Locale.Category.FORMAT)
|
||||
.getUnicodeLocaleType(UNICODE_EXTENSION_NUMBERING_SYSTEM);
|
||||
if (TextUtils.isEmpty(result)) {
|
||||
return mContext.getString(R.string.default_string_of_regional_preference);
|
||||
}
|
||||
}
|
||||
|
||||
Locale locale = new Locale.Builder()
|
||||
.setUnicodeLocaleKeyword(UNICODE_EXTENSION_NUMBERING_SYSTEM, result)
|
||||
.build();
|
||||
return NumberingSystem.getInstance(locale).getName();
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
/** A controller for the entry of Regional preferences */
|
||||
public class RegionalPreferencesController extends BasePreferenceController {
|
||||
// This is a feature flag and will be removed after feature completed.
|
||||
static final String FEATURE_PROPERTY = "i18n-feature-locale-preference";
|
||||
public RegionalPreferencesController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link AvailabilityStatus} for the Setting. This status is used to determine if the
|
||||
* Setting should be shown or disabled in Settings. Further, it can be used to produce
|
||||
* appropriate error / warning Slice in the case of unavailability.
|
||||
* </p>
|
||||
* The status is used for the convenience methods: {@link #isAvailable()}, {@link
|
||||
* #isSupported()}
|
||||
* </p>
|
||||
* The inherited class doesn't need to check work profile if android:forWork="true" is set in
|
||||
* preference xml.
|
||||
*/
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return SystemProperties.getBoolean(FEATURE_PROPERTY, false)
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
/** Provides entries of each regional preferences */
|
||||
@SearchIndexable
|
||||
public class RegionalPreferencesEntriesFragment extends DashboardFragment {
|
||||
private static final String TAG = RegionalPreferencesEntriesFragment.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
getActivity().setTitle(R.string.regional_preferences_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.REGIONAL_PREFERENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.regional_preference_main_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tag string for logging.
|
||||
*/
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.regional_preference_main_page);
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/** A controller for the entry of Temperature units' page */
|
||||
public class TemperatureUnitController extends BasePreferenceController {
|
||||
public TemperatureUnitController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link AvailabilityStatus} for the Setting. This status is used to determine if the
|
||||
* Setting should be shown or disabled in Settings. Further, it can be used to produce
|
||||
* appropriate error / warning Slice in the case of unavailability.
|
||||
* </p>
|
||||
* The status is used for the convenience methods: {@link #isAvailable()}, {@link
|
||||
* #isSupported()}
|
||||
* </p>
|
||||
* The inherited class doesn't need to check work profile if android:forWork="true" is set in
|
||||
* preference xml.
|
||||
*/
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
String record = Settings.System.getString(
|
||||
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
String result = "";
|
||||
if (record != null) {
|
||||
result = LocalePreferences.getTemperatureUnit(Locale.forLanguageTag(record), false);
|
||||
}
|
||||
|
||||
if (result.isEmpty()) {
|
||||
result = LocalePreferences.getTemperatureUnit(false);
|
||||
}
|
||||
return result.isEmpty()
|
||||
? mContext.getString(R.string.default_string_of_regional_preference) : result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class CalendarTypeControllerTest {
|
||||
private Context mApplicationContext;
|
||||
private CalendarTypeController mController;
|
||||
private String mCacheProviderContent = "";
|
||||
private Locale mCacheLocale;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mApplicationContext = ApplicationProvider.getApplicationContext();
|
||||
mController = new CalendarTypeController(mApplicationContext, "key");
|
||||
mCacheProviderContent = Settings.System.getString(
|
||||
mApplicationContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
mCacheLocale = Locale.getDefault(Locale.Category.FORMAT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, mCacheProviderContent);
|
||||
Locale.setDefault(mCacheLocale);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasProviderValue_resultIsChinese() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, "und-u-ca-chinese");
|
||||
|
||||
CharSequence type = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.CalendarType.CHINESE, type.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasProviderValue_resultIsDangi() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, "und-u-ca-dangi");
|
||||
|
||||
CharSequence type = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.CalendarType.DANGI, type.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noProviderValueButHasDefaultLocaleWithSubtag_resultIsSat() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "");
|
||||
Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese"));
|
||||
|
||||
CharSequence type = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.CalendarType.CHINESE, type.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noProviderValueAndDefaultLocaleWithoutSubtag_resultIsEmpty() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "");
|
||||
Locale.setDefault(Locale.forLanguageTag("en-US"));
|
||||
|
||||
CharSequence type = mController.getSummary();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(
|
||||
mApplicationContext, "default_string_of_regional_preference"), type.toString());
|
||||
}
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class FirstDayOfWeekControllerTest {
|
||||
private Context mApplicationContext;
|
||||
private FirstDayOfWeekController mController;
|
||||
private String mCacheProviderContent = "";
|
||||
private Locale mCacheLocale;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mApplicationContext = ApplicationProvider.getApplicationContext();
|
||||
mController = new FirstDayOfWeekController(mApplicationContext, "key");
|
||||
mCacheProviderContent = Settings.System.getString(
|
||||
mApplicationContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
mCacheLocale = Locale.getDefault(Locale.Category.FORMAT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, mCacheProviderContent);
|
||||
Locale.setDefault(mCacheLocale);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasProviderValue_resultIsWed() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "und-u-fw-wed");
|
||||
|
||||
CharSequence day = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.FirstDayOfWeek.WEDNESDAY, day.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasProviderValue_resultIsSat() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "und-u-fw-sat");
|
||||
|
||||
CharSequence day = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.FirstDayOfWeek.SATURDAY, day.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noProviderValueButHasDefaultLocaleWithSubtag_resultIsSat() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "");
|
||||
Locale.setDefault(Locale.forLanguageTag("en-US-u-fw-sat"));
|
||||
|
||||
CharSequence day = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.FirstDayOfWeek.SATURDAY, day.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noProviderValueAndDefaultLocaleWithoutSubtag_resultIsEmpty() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "");
|
||||
Locale.setDefault(Locale.forLanguageTag("en-US"));
|
||||
|
||||
CharSequence day = mController.getSummary();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(
|
||||
mApplicationContext, "default_string_of_regional_preference"), day.toString());
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
/** Utils for each regional preference unit test. */
|
||||
public final class RegionalPreferenceUtils {
|
||||
/** Set language tag to Settings Provider */
|
||||
public static void setSettingsProviderContent(Context context, String languageTag) {
|
||||
Settings.System.putString(context.getContentResolver(),
|
||||
Settings.System.LOCALE_PREFERENCES, languageTag);
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.app.UiAutomation;
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RegionalPreferencesControllerTest {
|
||||
private boolean mCacheProperty = false;
|
||||
private Context mApplicationContext;
|
||||
private RegionalPreferencesController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mApplicationContext = ApplicationProvider.getApplicationContext();
|
||||
mCacheProperty =
|
||||
SystemProperties.getBoolean(RegionalPreferencesController.FEATURE_PROPERTY, false);
|
||||
mController = new RegionalPreferencesController(mApplicationContext, "key");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
setProp(mCacheProperty);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_systemPropertyIstrue_available() throws Exception {
|
||||
setProp(true);
|
||||
|
||||
int result = mController.getAvailabilityStatus();
|
||||
|
||||
assertEquals(AVAILABLE, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_systemPropertyIstrue_unavailable() throws Exception {
|
||||
setProp(false);
|
||||
|
||||
int result = mController.getAvailabilityStatus();
|
||||
|
||||
assertEquals(CONDITIONALLY_UNAVAILABLE, result);
|
||||
}
|
||||
|
||||
private static void setProp(boolean isEnabled) throws Exception {
|
||||
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
|
||||
uiAutomation.executeShellCommand(
|
||||
"setprop " + RegionalPreferencesController.FEATURE_PROPERTY + " " + isEnabled);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Thread.sleep(500);
|
||||
if (SystemProperties.getBoolean(
|
||||
RegionalPreferencesController.FEATURE_PROPERTY, false) == isEnabled) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RegionalPreferencesEntriesFragmentTest {
|
||||
private RegionalPreferencesEntriesFragment mFragment;
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setUp() throws Exception {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
mFragment = new RegionalPreferencesEntriesFragment();
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getMetricsCategory_returnRegionalPreference() {
|
||||
assertEquals(SettingsEnums.REGIONAL_PREFERENCE, mFragment.getMetricsCategory());
|
||||
}
|
||||
}
|
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.regionalpreferences;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class TemperatureUnitControllerTest {
|
||||
private Context mApplicationContext;
|
||||
private TemperatureUnitController mController;
|
||||
private String mCacheProviderContent = "";
|
||||
private Locale mCacheLocale;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mApplicationContext = ApplicationProvider.getApplicationContext();
|
||||
mController = new TemperatureUnitController(mApplicationContext, "key");
|
||||
mCacheProviderContent = Settings.System.getString(
|
||||
mApplicationContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
|
||||
mCacheLocale = Locale.getDefault(Locale.Category.FORMAT);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, mCacheProviderContent);
|
||||
Locale.setDefault(mCacheLocale);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasProviderValue_resultIsCelsius() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, "und-u-mu-celsius");
|
||||
|
||||
CharSequence unit = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.TemperatureUnit.CELSIUS, unit.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_hasProviderValue_resultIsFahrenheit() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(
|
||||
mApplicationContext, "und-u-mu-fahrenhe");
|
||||
|
||||
CharSequence unit = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.TemperatureUnit.FAHRENHEIT, unit.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noProviderValueButHasDefaultLocaleWithSubtag_resultIsFahrenheit() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "");
|
||||
Locale.setDefault(Locale.forLanguageTag("en-US-u-mu-fahrenhe"));
|
||||
|
||||
CharSequence unit = mController.getSummary();
|
||||
|
||||
assertEquals(LocalePreferences.TemperatureUnit.FAHRENHEIT, unit.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_noProviderValueAndDefaultLocaleWithoutSubtag_resultIsEmpty() {
|
||||
RegionalPreferenceUtils.setSettingsProviderContent(mApplicationContext, "");
|
||||
Locale.setDefault(Locale.forLanguageTag("en-US"));
|
||||
|
||||
CharSequence unit = mController.getSummary();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(
|
||||
mApplicationContext, "default_string_of_regional_preference"), unit.toString());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user