Add measurement system

1. add UX
2. add main functionality

Bug: 375979373
Flag: com.android.settings.flags.regional_preferences_api_enabled
Test: manual, atest
Change-Id: Ie0c82551ff4e9ab0c70fa5d3c32c62d1d7e26b87
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index febdb04..5de6222 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1425,6 +1425,14 @@
         <item>sat</item>
     </string-array>
 
+    <!-- A list for measurement system. [DO NOT TRANSLATE] -->
+    <string-array name="measurement_system">
+        <item>default</item>
+        <item>metric</item>
+        <item>ussystem</item>
+        <item>uksystem</item>
+    </string-array>
+
     <!-- Screen flash notification color when activating -->
     <array name="screen_flash_notification_preset_opacity_colors">
         <item>@color/screen_flash_preset_opacity_color_01</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2de7e88..78a22cd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -490,6 +490,8 @@
     <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 preferences</string>
+    <!-- The title of the  menu entry of Measurement system preference. [CHAR LIMIT=50]  -->
+    <string name="measurement_system_preferences_title">Measurement system</string>
     <!-- The summary of default string for each regional preference. [CHAR LIMIT=50] -->
     <string name="default_string_of_regional_preference">Use default</string>
     <!-- The title of Celsius for preference of temperature unit. [CHAR LIMIT=50] -->
@@ -516,6 +518,12 @@
     <string name="desc_regional_pref_footer_learn_more">Learn more about language preferences.</string>
     <!-- Support link for the regional preference page. [CHAR LIMIT=NONE]-->
     <string name="regional_pref_footer_learn_more_link" translatable="false">https://support.google.com/android?p=regional_preferences</string>
+    <!-- The title of metric for preference of measurement system. [CHAR LIMIT=50] -->
+    <string name="metric_measurement_system">Metric</string>
+    <!-- The title of imperial US for preference of measurement system. [CHAR LIMIT=50] -->
+    <string name="us_measurement_system">Imperial (US)</string>
+    <!-- The title of imperial UK for preference of measurement system. [CHAR LIMIT=50] -->
+    <string name="uk_measurement_system">Imperial (UK)</string>
 
     <!-- Category for the terms of address. [CHAR LIMIT=NONE]-->
     <string name="category_title_terms_of_address">Additional preferences</string>
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index f9f423e..44a195c 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -82,6 +82,17 @@
         </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"
diff --git a/res/xml/regional_preferences_measurement_system.xml b/res/xml/regional_preferences_measurement_system.xml
new file mode 100644
index 0000000..73ac03d
--- /dev/null
+++ b/res/xml/regional_preferences_measurement_system.xml
@@ -0,0 +1,34 @@
+<?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/measurement_system_preferences_title"
+    android:key="regional_preference_measurement_system">
+
+  <com.android.settingslib.widget.TopIntroPreference
+      android:key="measurement_system_intro"
+      android:title="@string/regional_preferences_option_page_sub_title"
+      android:persistent="false" />
+
+  <PreferenceCategory
+      android:key="measurement_system_item_category"
+      android:title="@string/summary_placeholder"
+      android:layout="@layout/preference_category_no_label"
+      settings:controller="com.android.settings.regionalpreferences.MeasurementSystemItemCategoryController"/>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/regionalpreferences/ExtensionTypes.java b/src/com/android/settings/regionalpreferences/ExtensionTypes.java
index b860d29..5a2057b 100644
--- a/src/com/android/settings/regionalpreferences/ExtensionTypes.java
+++ b/src/com/android/settings/regionalpreferences/ExtensionTypes.java
@@ -25,12 +25,14 @@
     public static final String FIRST_DAY_OF_WEEK = "fw";
     public static final String NUMBERING_SYSTEM = "nu";
     public static final String TEMPERATURE_UNIT = "mu";
+    public static final String MEASUREMENT_SYSTEM = "ms";
 
     @StringDef({
             FIRST_DAY_OF_WEEK,
             CALENDAR,
             TEMPERATURE_UNIT,
-            NUMBERING_SYSTEM
+            NUMBERING_SYSTEM,
+            MEASUREMENT_SYSTEM
     })
     public @interface Values {}
 }
diff --git a/src/com/android/settings/regionalpreferences/MeasurementSystemController.java b/src/com/android/settings/regionalpreferences/MeasurementSystemController.java
new file mode 100644
index 0000000..1b6daaf
--- /dev/null
+++ b/src/com/android/settings/regionalpreferences/MeasurementSystemController.java
@@ -0,0 +1,68 @@
+/**
+ * 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.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.flags.Flags;
+
+import java.util.Locale;
+
+/** A controller for the entry of measurement system page */
+public class MeasurementSystemController extends BasePreferenceController {
+    private static final String TAG = "MeasurementSystemController";
+    public MeasurementSystemController(@NonNull Context context, @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (Flags.regionalPreferencesApiEnabled()) {
+            return AVAILABLE;
+        }
+        return CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    @NonNull
+    public CharSequence getSummary() {
+        LocaleList localeList = LocaleList.getDefault();
+        Locale locale = localeList.get(0);
+        return getMeasurementSystem(locale);
+    }
+
+    private String getMeasurementSystem(Locale locale) {
+        String type = locale.getUnicodeLocaleType(
+                RegionalPreferencesDataUtils.EXTENSION_TYPE_MEASUREMENT_SYSTEM);
+        if (type != null) {
+            if (type.equals(RegionalPreferencesDataUtils.MEASUREMENT_SYSTEM_METRIC)) {
+                return mContext.getString(R.string.metric_measurement_system);
+            }
+            if (type.equals(RegionalPreferencesDataUtils.MEASUREMENT_SYSTEM_UK)) {
+                return mContext.getString(R.string.uk_measurement_system);
+            }
+            return mContext.getString(R.string.us_measurement_system);
+        } else {
+            return mContext.getString(R.string.default_string_of_regional_preference);
+        }
+    }
+}
diff --git a/src/com/android/settings/regionalpreferences/MeasurementSystemItemCategoryController.java b/src/com/android/settings/regionalpreferences/MeasurementSystemItemCategoryController.java
new file mode 100644
index 0000000..03b8817
--- /dev/null
+++ b/src/com/android/settings/regionalpreferences/MeasurementSystemItemCategoryController.java
@@ -0,0 +1,62 @@
+/**
+ * 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.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.widget.PreferenceCategoryController;
+
+/** Category preference controller for measurement system preferences. */
+public class MeasurementSystemItemCategoryController extends PreferenceCategoryController {
+
+    private static final String LOG_TAG = "MeasurementSystemItemCategoryController";
+    private static final String KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM =
+            "measurement_system_item_category";
+    private static final String KEY_PREFERENCE_MEASUREMENT_SYSTEM_ITEM =
+            "measurement_system_item_list";
+
+    public MeasurementSystemItemCategoryController(@NonNull Context context, @NonNull String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+        PreferenceCategory preferenceCategory =
+                screen.findPreference(KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM);
+        if (preferenceCategory == null) {
+            Log.d(LOG_TAG, "displayPreference(), Can not find the category.");
+            return;
+        }
+        preferenceCategory.setVisible(isAvailable());
+        MeasurementSystemItemListController measurementSystemItemListController =
+                new MeasurementSystemItemListController(
+                    mContext,
+                    KEY_PREFERENCE_MEASUREMENT_SYSTEM_ITEM);
+        measurementSystemItemListController.displayPreference(screen);
+    }
+}
diff --git a/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java b/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java
new file mode 100644
index 0000000..9f15cf4
--- /dev/null
+++ b/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java
@@ -0,0 +1,72 @@
+/**
+ * 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.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.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Main fragment to display measurement system. */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class MeasurementSystemItemFragment extends DashboardFragment {
+
+    private static final String LOG_TAG = "MeasurementSystemItemFragment";
+    private static final String KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM =
+            "measurement_system_item_category";
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.regional_preferences_measurement_system;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.MEASUREMENT_SYSTEM_PREFERENCE;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return LOG_TAG;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new MeasurementSystemItemCategoryController(context,
+                KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM));
+        return controllers;
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.regional_preferences_measurement_system) {
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    if (Flags.regionalPreferencesApiEnabled()) {
+                        return false;
+                    }
+                    return true;
+                }
+            };
+}
diff --git a/src/com/android/settings/regionalpreferences/MeasurementSystemItemListController.java b/src/com/android/settings/regionalpreferences/MeasurementSystemItemListController.java
new file mode 100644
index 0000000..061c4f8
--- /dev/null
+++ b/src/com/android/settings/regionalpreferences/MeasurementSystemItemListController.java
@@ -0,0 +1,69 @@
+/**
+ * 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.app.settings.SettingsEnums;
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.android.settings.R;
+
+/** A controller for handling all measurement system preferences. */
+public class MeasurementSystemItemListController extends
+        RegionalPreferenceListBasePreferenceController {
+
+    private static final String KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM =
+            "measurement_system_item_category";
+    private static final String KEY_PREFERENCE_MEASUREMENT_SYSTEM_ITEM =
+            "measurement_system_item_list";
+
+    public MeasurementSystemItemListController(@NonNull Context context, @NonNull String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected String getPreferenceTitle(String item) {
+        return RegionalPreferencesDataUtils.measurementSystemConverter(mContext, item);
+    }
+
+    @Override
+    protected String getPreferenceCategoryKey() {
+        return KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM;
+    }
+
+    @Override
+    @NonNull
+    public String getPreferenceKey() {
+        return KEY_PREFERENCE_MEASUREMENT_SYSTEM_ITEM;
+    }
+
+    @Override
+    protected String getExtensionTypes() {
+        return ExtensionTypes.MEASUREMENT_SYSTEM;
+    }
+
+    @Override
+    protected String[] getUnitValues() {
+        return mContext.getResources().getStringArray(R.array.measurement_system);
+    }
+
+    @Override
+    protected int getMetricsActionKey() {
+        return SettingsEnums.ACTION_SET_MEASUREMENT_SYSTEM;
+    }
+}
diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java b/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java
index dda0579..606307f 100644
--- a/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java
+++ b/src/com/android/settings/regionalpreferences/RegionalPreferenceListBasePreferenceController.java
@@ -65,8 +65,8 @@
                 RegionalPreferencesDataUtils.savePreference(mContext, getExtensionTypes(),
                         item.equals(RegionalPreferencesDataUtils.DEFAULT_VALUE)
                                 ? null : item);
-                String metrics =
-                        getMetricsActionKey() == SettingsEnums.ACTION_SET_FIRST_DAY_OF_WEEK ? ""
+                String metrics = shouldUseEmptyMetrics()
+                                ? ""
                                 : getPreferenceTitle(value) + " > " + getPreferenceTitle(item);
                 mMetricsFeatureProvider.action(mContext, getMetricsActionKey(), metrics);
             });
@@ -79,6 +79,14 @@
         return AVAILABLE;
     }
 
+    private boolean shouldUseEmptyMetrics() {
+        if (getMetricsActionKey() == SettingsEnums.ACTION_SET_FIRST_DAY_OF_WEEK
+                || getMetricsActionKey() == SettingsEnums.ACTION_SET_MEASUREMENT_SYSTEM) {
+            return true;
+        }
+        return false;
+    }
+
     protected abstract String getPreferenceTitle(String item);
 
     protected abstract String getPreferenceCategoryKey();
diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferencesDataUtils.java b/src/com/android/settings/regionalpreferences/RegionalPreferencesDataUtils.java
index d1ae40b..669bcdd 100644
--- a/src/com/android/settings/regionalpreferences/RegionalPreferencesDataUtils.java
+++ b/src/com/android/settings/regionalpreferences/RegionalPreferencesDataUtils.java
@@ -17,6 +17,7 @@
 package com.android.settings.regionalpreferences;
 
 import android.content.Context;
+import android.icu.util.LocaleData;
 import android.icu.util.ULocale;
 import android.os.LocaleList;
 import android.provider.Settings;
@@ -32,6 +33,10 @@
 /** Provides utils for regional preferences. */
 public class RegionalPreferencesDataUtils {
     static final String DEFAULT_VALUE = "default";
+    static final String EXTENSION_TYPE_MEASUREMENT_SYSTEM = "ms";
+    static final String MEASUREMENT_SYSTEM_METRIC = "metric";
+    static final String MEASUREMENT_SYSTEM_UK = "uksystem";
+    static final String MEASUREMENT_SYSTEM_US = "ussystem";
 
     static String getDefaultUnicodeExtensionData(Context contxt, String type) {
         // 1. Check cache data in Settings provider.
@@ -118,4 +123,30 @@
                 return context.getString(R.string.default_string_of_regional_preference);
         }
     }
+
+    static String measurementSystemConverter(Context context, String unit) {
+        switch (unit) {
+            case MEASUREMENT_SYSTEM_METRIC:
+                return context.getString(R.string.metric_measurement_system);
+            case MEASUREMENT_SYSTEM_UK:
+                return context.getString(R.string.uk_measurement_system);
+            case MEASUREMENT_SYSTEM_US:
+                return context.getString(R.string.us_measurement_system);
+            default:
+                return context.getString(R.string.default_string_of_regional_preference);
+        }
+    }
+
+    static String getDefaultMeasurementSystem() {
+        LocaleList localeList = LocaleList.getDefault();
+        Locale locale = localeList.get(0);
+        ULocale uLocale = ULocale.forLocale(locale);
+        if (LocaleData.getMeasurementSystem(uLocale) == LocaleData.MeasurementSystem.SI) {
+            return RegionalPreferencesDataUtils.MEASUREMENT_SYSTEM_METRIC;
+        }
+        if (LocaleData.getMeasurementSystem(uLocale) == LocaleData.MeasurementSystem.UK) {
+            return RegionalPreferencesDataUtils.MEASUREMENT_SYSTEM_UK;
+        }
+        return RegionalPreferencesDataUtils.MEASUREMENT_SYSTEM_US;
+    }
 }