[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]-->
|
<!-- 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>
|
<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] -->
|
<!-- 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,
|
<string name="dlg_remove_locales_title">{count, plural,
|
||||||
=1 {Remove selected language?}
|
=1 {Remove selected language?}
|
||||||
|
@@ -38,6 +38,15 @@
|
|||||||
android:name="classname"
|
android:name="classname"
|
||||||
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
|
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
|
||||||
</Preference>
|
</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>
|
||||||
|
|
||||||
<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