diff --git a/res/values/strings.xml b/res/values/strings.xml index d9594b3ffdb..170e4b63afa 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -480,6 +480,8 @@ Let apps know your regional preferences so they can personalize your experience. Apps will use your regional preferences where possible. + + Regional preferences Temperature diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml index 7618399db97..fb79346b3b8 100644 --- a/res/xml/language_settings.xml +++ b/res/xml/language_settings.xml @@ -48,6 +48,45 @@ + + + + + + + + + + + + + + + @@ -69,4 +108,11 @@ android:fragment="com.android.settings.tts.TextToSpeechSettings" settings:searchable="false"/> + + diff --git a/src/com/android/settings/regionalpreferences/NewFirstDayOfWeekController.java b/src/com/android/settings/regionalpreferences/NewFirstDayOfWeekController.java new file mode 100644 index 00000000000..bbe4dd682b5 --- /dev/null +++ b/src/com/android/settings/regionalpreferences/NewFirstDayOfWeekController.java @@ -0,0 +1,74 @@ +/* + * 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.regionalpreferences; + +import android.content.Context; +import android.provider.Settings; + +import androidx.annotation.NonNull; +import androidx.core.text.util.LocalePreferences; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.flags.Flags; + +import java.util.Locale; + +/** A controller for the entry of First Day of Week's page */ +public class NewFirstDayOfWeekController extends BasePreferenceController { + + public NewFirstDayOfWeekController(@NonNull Context context, @NonNull 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. + *

+ * The status is used for the convenience methods: {@link #isAvailable()}, {@link + * #isSupported()} + *

+ * The inherited class doesn't need to check work profile if android:forWork="true" is set in + * preference xml. + */ + @Override + public int getAvailabilityStatus() { + if (Flags.regionalPreferencesApiEnabled()) { + return AVAILABLE; + } + return CONDITIONALLY_UNAVAILABLE; + } + + @Override + @NonNull + 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) + : RegionalPreferencesDataUtils.dayConverter(mContext, result); + } +} diff --git a/src/com/android/settings/regionalpreferences/NewNumberingSystemController.java b/src/com/android/settings/regionalpreferences/NewNumberingSystemController.java new file mode 100644 index 00000000000..ccdb13ffa0f --- /dev/null +++ b/src/com/android/settings/regionalpreferences/NewNumberingSystemController.java @@ -0,0 +1,89 @@ +/* + * 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.regionalpreferences; + +import android.content.Context; +import android.os.LocaleList; + +import androidx.annotation.NonNull; + +import com.android.internal.app.LocaleStore; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.flags.Flags; +import com.android.settings.localepicker.LocaleFeatureProviderImpl; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +/** A controller for the entry of Numbering System's page */ +public class NewNumberingSystemController extends BasePreferenceController { + private static final String TAG = NewNumberingSystemController.class.getSimpleName(); + + private LocaleList mLocaleList; + public NewNumberingSystemController(@NonNull Context context, @NonNull String preferenceKey) { + super(context, preferenceKey); + // Initialize the supported languages to LocaleInfos + LocaleStore.fillCache(context); + mLocaleList = getNumberingSystemLocale(); + } + + /** + * @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. + *

+ * The status is used for the convenience methods: {@link #isAvailable()}, {@link + * #isSupported()} + *

+ * The inherited class doesn't need to check work profile if android:forWork="true" is set in + * preference xml. + */ + @Override + public int getAvailabilityStatus() { + if (Flags.regionalPreferencesApiEnabled()) { + return mLocaleList.isEmpty() ? CONDITIONALLY_UNAVAILABLE : AVAILABLE; + } + return CONDITIONALLY_UNAVAILABLE; + } + + private static LocaleList getNumberingSystemLocale() { + LocaleList localeList = LocaleList.getDefault(); + Set localesHasNumberingSystems = new HashSet<>(); + for (int i = 0; i < localeList.size(); i++) { + Locale locale = localeList.get(i); + LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(locale); + if (localeInfo.hasNumberingSystems()) { + localesHasNumberingSystems.add(locale); + } + } + return convertToLocaleList(localesHasNumberingSystems); + } + + private static LocaleList convertToLocaleList(Set locales) { + if (locales.isEmpty()) { + return LocaleList.getEmptyLocaleList(); + } + return new LocaleList(locales.stream().toArray(Locale[]::new)); + } + + @Override + @NonNull + public CharSequence getSummary() { + return new LocaleFeatureProviderImpl().getLocaleNames(getNumberingSystemLocale()); + } +} diff --git a/src/com/android/settings/regionalpreferences/NewRegionalFooterPreferenceController.java b/src/com/android/settings/regionalpreferences/NewRegionalFooterPreferenceController.java new file mode 100644 index 00000000000..6888833b8c8 --- /dev/null +++ b/src/com/android/settings/regionalpreferences/NewRegionalFooterPreferenceController.java @@ -0,0 +1,79 @@ +/** + * 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.regionalpreferences; + +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.flags.Flags; +import com.android.settingslib.HelpUtils; +import com.android.settingslib.widget.FooterPreference; + +/** + * Preference controller for regional preference footer. + */ +public class NewRegionalFooterPreferenceController extends BasePreferenceController { + + private static final String TAG = "NewRegionalFooterPreferenceController"; + + public NewRegionalFooterPreferenceController(@NonNull Context context, @NonNull String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + if (Flags.regionalPreferencesApiEnabled()) { + return AVAILABLE_UNSEARCHABLE; + } + return CONDITIONALLY_UNAVAILABLE; + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + FooterPreference footerPreference = screen.findPreference(getPreferenceKey()); + setupFooterPreference(footerPreference); + } + + @VisibleForTesting + void setupFooterPreference(FooterPreference footerPreference) { + if (footerPreference != null) { + footerPreference.setLearnMoreAction(v -> openLocaleLearnMoreLink()); + footerPreference.setLearnMoreText(mContext.getString( + R.string.desc_regional_pref_footer_learn_more)); + } + } + + private void openLocaleLearnMoreLink() { + Intent intent = HelpUtils.getHelpIntent( + mContext, + mContext.getString(R.string.regional_pref_footer_learn_more_link), + mContext.getClass().getName()); + if (intent != null) { + mContext.startActivity(intent); + } else { + Log.w(TAG, "HelpIntent is null"); + } + } +} diff --git a/src/com/android/settings/regionalpreferences/NewTemperatureUnitController.java b/src/com/android/settings/regionalpreferences/NewTemperatureUnitController.java new file mode 100644 index 00000000000..2910dc58f61 --- /dev/null +++ b/src/com/android/settings/regionalpreferences/NewTemperatureUnitController.java @@ -0,0 +1,75 @@ +/* + * 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.regionalpreferences; + +import android.content.Context; +import android.provider.Settings; + +import androidx.annotation.NonNull; +import androidx.core.text.util.LocalePreferences; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.flags.Flags; + +import java.util.Locale; + +/** A controller for the entry of Temperature units' page */ +public class NewTemperatureUnitController extends BasePreferenceController { + private static final String TAG = NewTemperatureUnitController.class.getSimpleName(); + public NewTemperatureUnitController(@NonNull Context context, @NonNull 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. + *

+ * The status is used for the convenience methods: {@link #isAvailable()}, {@link + * #isSupported()} + *

+ * The inherited class doesn't need to check work profile if android:forWork="true" is set in + * preference xml. + */ + @Override + public int getAvailabilityStatus() { + if (Flags.regionalPreferencesApiEnabled()) { + return AVAILABLE; + } + return CONDITIONALLY_UNAVAILABLE; + } + + @Override + @NonNull + 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) + : RegionalPreferencesDataUtils.temperatureUnitsConverter(mContext, result); + } +} diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferencesCategoryController.java b/src/com/android/settings/regionalpreferences/RegionalPreferencesCategoryController.java new file mode 100644 index 00000000000..ad524a4ed3c --- /dev/null +++ b/src/com/android/settings/regionalpreferences/RegionalPreferencesCategoryController.java @@ -0,0 +1,38 @@ +/* + * 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.regionalpreferences; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.android.settings.flags.Flags; +import com.android.settings.widget.PreferenceCategoryController; + +public class RegionalPreferencesCategoryController extends PreferenceCategoryController { + public RegionalPreferencesCategoryController(@NonNull Context context, @NonNull String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + if (Flags.regionalPreferencesApiEnabled()) { + return AVAILABLE; + } + return CONDITIONALLY_UNAVAILABLE; + } +} diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferencesController.java b/src/com/android/settings/regionalpreferences/RegionalPreferencesController.java index 5e5fc9d2175..f194659c00b 100644 --- a/src/com/android/settings/regionalpreferences/RegionalPreferencesController.java +++ b/src/com/android/settings/regionalpreferences/RegionalPreferencesController.java @@ -20,6 +20,7 @@ import android.content.Context; import android.os.SystemProperties; import com.android.settings.core.BasePreferenceController; +import com.android.settings.flags.Flags; /** A controller for the entry of Regional preferences */ public class RegionalPreferencesController extends BasePreferenceController { @@ -42,6 +43,9 @@ public class RegionalPreferencesController extends BasePreferenceController { */ @Override public int getAvailabilityStatus() { + if (Flags.regionalPreferencesApiEnabled()) { + return CONDITIONALLY_UNAVAILABLE; + } return SystemProperties.getBoolean(FEATURE_PROPERTY, true) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferencesEntriesFragment.java b/src/com/android/settings/regionalpreferences/RegionalPreferencesEntriesFragment.java index 848febcf2d2..8b1e749ef79 100644 --- a/src/com/android/settings/regionalpreferences/RegionalPreferencesEntriesFragment.java +++ b/src/com/android/settings/regionalpreferences/RegionalPreferencesEntriesFragment.java @@ -17,9 +17,11 @@ package com.android.settings.regionalpreferences; import android.app.settings.SettingsEnums; +import android.content.Context; 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.settingslib.search.SearchIndexable; @@ -55,5 +57,13 @@ public class RegionalPreferencesEntriesFragment extends DashboardFragment { } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.regional_preference_main_page); + new BaseSearchIndexProvider(R.xml.regional_preference_main_page) { + @Override + protected boolean isPageSearchEnabled(Context context) { + if (Flags.regionalPreferencesApiEnabled()) { + return false; + } + return true; + } + }; } diff --git a/tests/unit/src/com/android/settings/regionalpreferences/FirstDayOfWeekControllerTest.java b/tests/unit/src/com/android/settings/regionalpreferences/FirstDayOfWeekControllerTest.java index 062aef8393a..cd813453425 100644 --- a/tests/unit/src/com/android/settings/regionalpreferences/FirstDayOfWeekControllerTest.java +++ b/tests/unit/src/com/android/settings/regionalpreferences/FirstDayOfWeekControllerTest.java @@ -19,14 +19,18 @@ package com.android.settings.regionalpreferences; import static org.junit.Assert.assertEquals; import android.content.Context; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.flags.Flags; import com.android.settings.testutils.ResourcesUtils; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.util.Locale; @@ -37,6 +41,8 @@ public class FirstDayOfWeekControllerTest { private String mCacheProviderContent = ""; private Locale mCacheLocale; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Before public void setUp() throws Exception { mApplicationContext = ApplicationProvider.getApplicationContext(); @@ -54,6 +60,7 @@ public class FirstDayOfWeekControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_hasProviderValue_resultIsWed() { RegionalPreferenceTestUtils.setSettingsProviderContent(mApplicationContext, "und-u-fw-wed"); @@ -64,6 +71,7 @@ public class FirstDayOfWeekControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_hasProviderValue_resultIsSat() { RegionalPreferenceTestUtils.setSettingsProviderContent(mApplicationContext, "und-u-fw-sat"); @@ -74,6 +82,7 @@ public class FirstDayOfWeekControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_noProviderValueButHasDefaultLocaleWithSubtag_resultIsSat() { RegionalPreferenceTestUtils.setSettingsProviderContent(mApplicationContext, ""); Locale.setDefault(Locale.forLanguageTag("en-US-u-fw-sat")); @@ -85,6 +94,7 @@ public class FirstDayOfWeekControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_noProviderValueAndDefaultLocaleWithoutSubtag_resultIsdefault() { RegionalPreferenceTestUtils.setSettingsProviderContent(mApplicationContext, ""); Locale.setDefault(Locale.forLanguageTag("en-US")); diff --git a/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemControllerTest.java b/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemControllerTest.java index 6a95bb95826..cba30936c23 100644 --- a/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemControllerTest.java +++ b/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemControllerTest.java @@ -23,22 +23,30 @@ import static org.junit.Assert.assertEquals; import android.content.Context; import android.os.LocaleList; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.flags.Flags; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; public class NumberingSystemControllerTest { private Context mApplicationContext; private NumberingSystemController mController; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Before public void setUp() throws Exception { mApplicationContext = ApplicationProvider.getApplicationContext(); } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getAvailabilityStatus_noLocale_unavailable() { LocaleList.setDefault(LocaleList.forLanguageTags("en-US,zh-Hant-TW")); mController = new NumberingSystemController(mApplicationContext, "key"); @@ -49,6 +57,7 @@ public class NumberingSystemControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getAvailabilityStatus_hasLocaleWithNumberingSystems_available() { // ar-JO has different numbering system. LocaleList.setDefault(LocaleList.forLanguageTags("en-US,zh-Hant-TW,ar-JO")); diff --git a/tests/unit/src/com/android/settings/regionalpreferences/TemperatureUnitControllerTest.java b/tests/unit/src/com/android/settings/regionalpreferences/TemperatureUnitControllerTest.java index aa652cab1f4..561e788533d 100644 --- a/tests/unit/src/com/android/settings/regionalpreferences/TemperatureUnitControllerTest.java +++ b/tests/unit/src/com/android/settings/regionalpreferences/TemperatureUnitControllerTest.java @@ -19,14 +19,18 @@ package com.android.settings.regionalpreferences; import static org.junit.Assert.assertEquals; import android.content.Context; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.flags.Flags; import com.android.settings.testutils.ResourcesUtils; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.util.Locale; @@ -37,6 +41,8 @@ public class TemperatureUnitControllerTest { private String mCacheProviderContent = ""; private Locale mCacheLocale; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Before public void setUp() throws Exception { mApplicationContext = ApplicationProvider.getApplicationContext(); @@ -54,6 +60,7 @@ public class TemperatureUnitControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_hasProviderValue_resultIsCelsius() { RegionalPreferenceTestUtils.setSettingsProviderContent( mApplicationContext, "und-u-mu-celsius"); @@ -65,6 +72,7 @@ public class TemperatureUnitControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_hasProviderValue_resultIsFahrenheit() { RegionalPreferenceTestUtils.setSettingsProviderContent( mApplicationContext, "und-u-mu-fahrenhe"); @@ -76,6 +84,7 @@ public class TemperatureUnitControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_noProviderValueButHasDefaultLocaleWithSubtag_resultIsFahrenheit() { RegionalPreferenceTestUtils.setSettingsProviderContent(mApplicationContext, ""); Locale.setDefault(Locale.forLanguageTag("en-US-u-mu-fahrenhe")); @@ -87,6 +96,7 @@ public class TemperatureUnitControllerTest { } @Test + @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED) public void getSummary_noProviderValueAndDefaultLocaleWithoutSubtag_resultIsDefault() { RegionalPreferenceTestUtils.setSettingsProviderContent(mApplicationContext, ""); Locale.setDefault(Locale.forLanguageTag("en-US"));