Create language and region settings page

1. Use flag to control the UI migration
2. Create language_and_region_settings.xml for new UI migration.

Bug: 379962955
Flag: com.android.settings.flags.regional_preferences_api_enabled
Test: check hsv and atest LanguagePreferenceControllerTest
Change-Id: If8d2303a2a3061231e69d1a45ad432c061da3545
This commit is contained in:
danielwbhuang
2024-12-12 20:56:13 +08:00
parent 626017d196
commit f70abd2680
11 changed files with 334 additions and 75 deletions

View File

@@ -4514,6 +4514,8 @@
<string name="language_settings">Languages&#160;&amp; input</string>
<!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings related to languages -->
<string name="languages_settings">Languages</string>
<!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings related to language and region-->
<string name="language_and_region_settings">Language &amp; region</string>
<!-- Title of setting on main settings screen. This item will take the user to the screen to tweak settings related to keyboards -->
<string name="keyboard_settings">Keyboard</string>
<!-- Text displayed when user has restriction DISALLOW_CONFIG_LOCALE [CHAR LIMIT=NONE]-->

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2024 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/language_and_region_settings"
android:key="language_and_region_settings">
<PreferenceCategory
android:key="languages_category"
android:title="@string/locale_picker_category_title">
<Preference
android:key="phone_language"
android:title="@string/system_language"
android:fragment="com.android.settings.localepicker.LocaleListEditor"
settings:controller="com.android.settings.language.PhoneLanguagePreferenceController" />
</PreferenceCategory>
<PreferenceCategory
android:key="more_language_settings_category"
android:title="@string/more_language_settings_category"
settings:controller="com.android.settings.language.MoreLanguagesSettingsCategoryController">
<Preference
android:key="apps_language_in_more_language_settings"
android:title="@string/app_locales_picker_menu_title"
android:summary="@string/app_locale_picker_summary"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
settings:controller="com.android.settings.applications.appinfo.NewAppsLocalePreferenceController">
<extra
android:name="classname"
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:key="regional_preferences_category"
android:title="@string/regional_preferences_category_title"
settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesCategoryController">
<Preference
android:key="temperature_preference"
android:title="@string/temperature_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.NewTemperatureUnitController"
settings:fragment="com.android.settings.regionalpreferences.TemperatureUnitFragment">
<extra
android:name="arg_key_regional_preference"
android:value="mu"/>
</Preference>
<Preference
android:key="key_measurement_system"
android:title="@string/measurement_system_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.MeasurementSystemController"
settings:fragment="com.android.settings.regionalpreferences.MeasurementSystemItemFragment">
<extra
android:name="arg_key_regional_preference"
android:value="ms"/>
</Preference>
<Preference
android:key="first_day_of_week_preference"
android:title="@string/first_day_of_week_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.NewFirstDayOfWeekController"
settings:fragment="com.android.settings.regionalpreferences.FirstDayOfWeekItemFragment">
<extra
android:name="arg_key_regional_preference"
android:value="fw"/>
</Preference>
<Preference
android:key="numbering_system_preference"
android:title="@string/numbers_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.NewNumberingSystemController"
settings:fragment="com.android.settings.regionalpreferences.NumberingPreferencesFragment">
<extra
android:name="arg_key_regional_preference"
android:value="arg_value_language_select"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:key="speech_category"
android:title="@string/speech_category_title">
<com.android.settings.widget.GearPreference
android:key="voice_input_settings"
android:title="@string/voice_input_settings_title"
android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
<Preference
android:key="on_device_recognition_settings"
android:title="@string/on_device_recognition_settings_title"
android:summary="@string/on_device_recognition_settings_summary"
settings:controller=
"com.android.settings.language.OnDeviceRecognitionPreferenceController" />
<Preference
android:key="tts_settings_summary"
android:title="@string/tts_settings_title"
android:fragment="com.android.settings.tts.TextToSpeechSettings"
settings:searchable="false"/>
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference
android:key="new_regional_pref_footer"
android:title="@string/title_regional_pref_footer"
android:selectable="false"
settings:searchable="false"
settings:controller="com.android.settings.regionalpreferences.NewRegionalFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -49,72 +49,6 @@
</PreferenceCategory>
<PreferenceCategory
android:key="more_language_settings_category"
android:title="@string/more_language_settings_category"
settings:controller="com.android.settings.language.MoreLanguagesSettingsCategoryController">
<Preference
android:key="apps_language_in_more_language_settings"
android:title="@string/app_locales_picker_menu_title"
android:summary="@string/app_locale_picker_summary"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
settings:controller="com.android.settings.applications.appinfo.NewAppsLocalePreferenceController">
<extra
android:name="classname"
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:key="regional_preferences_category"
android:title="@string/regional_preferences_category_title"
settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesCategoryController">
<Preference
android:key="temperature_preference"
android:title="@string/temperature_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.NewTemperatureUnitController"
settings:fragment="com.android.settings.regionalpreferences.TemperatureUnitFragment">
<extra
android:name="arg_key_regional_preference"
android:value="mu"/>
</Preference>
<Preference
android:key="key_measurement_system"
android:title="@string/measurement_system_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.MeasurementSystemController"
settings:fragment="com.android.settings.regionalpreferences.MeasurementSystemItemFragment">
<extra
android:name="arg_key_regional_preference"
android:value="ms"/>
</Preference>
<Preference
android:key="first_day_of_week_preference"
android:title="@string/first_day_of_week_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.NewFirstDayOfWeekController"
settings:fragment="com.android.settings.regionalpreferences.FirstDayOfWeekItemFragment">
<extra
android:name="arg_key_regional_preference"
android:value="fw"/>
</Preference>
<Preference
android:key="numbering_system_preference"
android:title="@string/numbers_preferences_title"
android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.NewNumberingSystemController"
settings:fragment="com.android.settings.regionalpreferences.NumberingPreferencesFragment">
<extra
android:name="arg_key_regional_preference"
android:value="arg_value_language_select"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:key="speech_category"
android:title="@string/speech_category_title">
@@ -136,11 +70,4 @@
android:fragment="com.android.settings.tts.TextToSpeechSettings"
settings:searchable="false"/>
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference
android:key="new_regional_pref_footer"
android:title="@string/title_regional_pref_footer"
android:selectable="false"
settings:searchable="false"
settings:controller="com.android.settings.regionalpreferences.NewRegionalFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -29,6 +29,15 @@
android:fragment="com.android.settings.language.LanguageSettings"
settings:controller="com.android.settings.language.LanguagePreferenceController"/>
<Preference
android:key="language_and_region_settings"
android:title="@string/language_and_region_settings"
android:summary="@string/languages_setting_summary"
android:icon="@drawable/ic_settings_languages"
android:order="-260"
android:fragment="com.android.settings.language.LanguageAndRegionSettings"
settings:controller="com.android.settings.language.LanguageAndRegionPreferenceController"/>
<Preference
android:key="Keyboard_settings"
android:title="@string/keyboard_settings"

View File

@@ -22,9 +22,12 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.Initializer;
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
import com.android.settingslib.applications.DefaultAppInfo;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -43,7 +46,8 @@ public class DefaultVoiceInputPreferenceController extends DefaultAppPreferenceC
private Preference mPreference;
private Context mContext;
public DefaultVoiceInputPreferenceController(Context context, Lifecycle lifecycle) {
public DefaultVoiceInputPreferenceController(
@NonNull Context context, @Nullable Lifecycle lifecycle) {
super(context);
mContext = context;
mHelper = new VoiceInputHelper(context);
@@ -65,6 +69,7 @@ public class DefaultVoiceInputPreferenceController extends DefaultAppPreferenceC
}
@Override
@Initializer
public void displayPreference(PreferenceScreen screen) {
mScreen = screen;
mPreference = screen.findPreference(getPreferenceKey());

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2024 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.language;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.flags.Flags;
/**
* This is a display controller for new language activity entry.
* TODO(b/379962955): When new layout is on board, all old layouts should be removed.
*/
public class LanguageAndRegionPreferenceController extends BasePreferenceController {
public LanguageAndRegionPreferenceController(@NonNull Context context, @NonNull String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
if (!Flags.regionalPreferencesApiEnabled()) {
return CONDITIONALLY_UNAVAILABLE;
}
// TODO: Add setComponentEnabledSetting after LanguageAndRegionSettingsActivity is created.
return AVAILABLE;
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2024 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.language;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.flags.Flags;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
@SearchIndexable
public class LanguageAndRegionSettings extends DashboardFragment {
private static final String KEY_SPEECH_CATEGORY = "speech_category";
private static final String KEY_ON_DEVICE_RECOGNITION = "on_device_recognition_settings";
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
private static final String TAG = "LanguageAndRegionSettings";
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_LANGUAGES_CATEGORY;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
public void onResume() {
super.onResume();
// Hack to update action bar title. It's necessary to refresh title because this page user
// can change locale from here and fragment won't relaunch. Once language changes, title
// must display in the new language.
final Activity activity = getActivity();
if (activity == null) {
return;
}
activity.setTitle(R.string.languages_settings);
}
@Override
public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
return LanguageSettingScreen.KEY;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.language_and_region_settings;
}
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(
@NonNull Context context, @Nullable Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
new DefaultVoiceInputPreferenceController(context, lifecycle);
final TtsPreferenceController ttsPreferenceController =
new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
final OnDeviceRecognitionPreferenceController onDeviceRecognitionPreferenceController =
new OnDeviceRecognitionPreferenceController(context, KEY_ON_DEVICE_RECOGNITION);
controllers.add(defaultVoiceInputPreferenceController);
controllers.add(ttsPreferenceController);
List<AbstractPreferenceController> speechCategoryChildren = new ArrayList<>(
List.of(defaultVoiceInputPreferenceController, ttsPreferenceController));
if (onDeviceRecognitionPreferenceController.isAvailable()) {
controllers.add(onDeviceRecognitionPreferenceController);
speechCategoryChildren.add(onDeviceRecognitionPreferenceController);
}
controllers.add(new PreferenceCategoryController(context, KEY_SPEECH_CATEGORY)
.setChildren(speechCategoryChildren));
return controllers;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.language_and_region_settings) {
@Override
@NonNull
public List<AbstractPreferenceController> createPreferenceControllers(
@NonNull Context context) {
return buildPreferenceControllers(context, null);
}
@Override
protected boolean isPageSearchEnabled(Context context) {
if (Flags.regionalPreferencesApiEnabled()) {
return true;
}
return false;
}
};
}

View File

@@ -22,6 +22,7 @@ import android.content.pm.PackageManager;
import com.android.settings.Settings;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.flags.Flags;
/**
* This is a display controller for new language activity entry.
@@ -34,6 +35,10 @@ public class LanguagePreferenceController extends BasePreferenceController {
@Override
public int getAvailabilityStatus() {
if (Flags.regionalPreferencesApiEnabled()) {
setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, false);
return CONDITIONALLY_UNAVAILABLE;
}
setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, true);
return AVAILABLE;
}

View File

@@ -25,6 +25,7 @@ import androidx.annotation.Nullable;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.flags.Flags;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -116,6 +117,9 @@ public class LanguageSettings extends DashboardFragment {
}
@Override
protected boolean isPageSearchEnabled(Context context) {
if (Flags.regionalPreferencesApiEnabled()) {
return false;
}
return true;
}
};

View File

@@ -63,7 +63,7 @@ public class MeasurementSystemItemFragment extends DashboardFragment {
new BaseSearchIndexProvider(R.xml.regional_preferences_measurement_system) {
@Override
protected boolean isPageSearchEnabled(Context context) {
if (Flags.regionalPreferencesApiEnabled()) {
if (!Flags.regionalPreferencesApiEnabled()) {
return false;
}
return true;

View File

@@ -21,18 +21,24 @@ import static org.junit.Assert.assertTrue;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.Settings;
import com.android.settings.flags.Flags;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class LanguagePreferenceControllerTest {
private Context mContext;
private LanguagePreferenceController mController;
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Before
public void setup() {
mContext = ApplicationProvider.getApplicationContext();
@@ -40,6 +46,7 @@ public class LanguagePreferenceControllerTest {
}
@Test
@DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED)
public void getAvailabilityStatus_featureFlagOff_LanguageSettingsActivitydisabled() {
mController.getAvailabilityStatus();