[Regional Pref] 1. Add metrics for user changes the Temperature unit 2.

Refactor to Settings design

Bug: 275003276
Bug: 264483854
Change-Id: Ib886ace45db8cfd7dd0f468d03a0aa0551f1f5c4
This commit is contained in:
Zoey Chen
2023-04-20 13:15:45 +00:00
parent 134bea1957
commit 5d2ce38d3a
8 changed files with 446 additions and 10 deletions

View File

@@ -27,7 +27,7 @@
android:title="@string/temperature_preferences_title" android:title="@string/temperature_preferences_title"
android:summary="@string/default_string_of_regional_preference" android:summary="@string/default_string_of_regional_preference"
settings:controller="com.android.settings.regionalpreferences.TemperatureUnitController" settings:controller="com.android.settings.regionalpreferences.TemperatureUnitController"
settings:fragment="com.android.settings.regionalpreferences.RegionalPreferencesFragment"> settings:fragment="com.android.settings.regionalpreferences.TemperatureUnitFragment">
<extra <extra
android:name="arg_key_regional_preference" android:name="arg_key_regional_preference"
android:value="mu" /> android:value="mu" />

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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/temperature_preferences_title">
<com.android.settingslib.widget.TopIntroPreference
android:title="@string/regional_preferences_option_page_sub_title"
android:persistent="false" />
<PreferenceCategory
android:key="temperature_unit_category"
android:title="@string/summary_placeholder"
android:layout="@layout/preference_category_no_label"
settings:controller="com.android.settings.regionalpreferences.TemperatureUnitCategoryController"/>
</PreferenceScreen>

View File

@@ -0,0 +1,103 @@
/**
* Copyright (C) 2023 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 android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.TickButtonPreference;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/** A base controller for handling all regional preferences controllers. */
public abstract class RegionalPreferenceListBasePreferenceController extends
BasePreferenceController {
private final MetricsFeatureProvider mMetricsFeatureProvider;
private PreferenceCategory mPreferenceCategory;
public RegionalPreferenceListBasePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceCategory = screen.findPreference(getPreferenceCategoryKey());
initPreferences();
}
private void initPreferences() {
if (mPreferenceCategory == null) {
return;
}
String[] unitValues = getUnitValues();
for (int i = 0; i < unitValues.length; i++) {
TickButtonPreference pref = new TickButtonPreference(mContext);
mPreferenceCategory.addPreference(pref);
final String item = unitValues[i];
pref.setTitle(getPreferenceTitle(item));
pref.setKey(item);
pref.setOnPreferenceClickListener(clickedPref -> {
setSelected(pref);
RegionalPreferencesDataUtils.savePreference(mContext, getExtensionTypes(), item);
mMetricsFeatureProvider.action(mContext, getMetricsActionKey(), item);
return true;
});
String value = RegionalPreferencesDataUtils.getDefaultUnicodeExtensionData(mContext,
getExtensionTypes());
pref.setSelected(!value.isEmpty() && item.equals(value));
}
}
private void setSelected(TickButtonPreference preference) {
for (int i = 0; i < mPreferenceCategory.getPreferenceCount(); i++) {
TickButtonPreference pref = (TickButtonPreference) mPreferenceCategory.getPreference(i);
if (pref.getKey().equals(preference.getKey())) {
pref.setSelected(true);
continue;
}
pref.setSelected(false);
}
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
protected abstract String getPreferenceTitle(String item);
protected abstract String getPreferenceCategoryKey();
protected abstract String getExtensionTypes();
protected abstract String[] getUnitValues();
protected abstract int getMetricsActionKey();
}

View File

@@ -42,9 +42,6 @@ public class RegionalPreferencesFragment extends SettingsPreferenceFragment {
private String[] initializeUIdata(String type) { private String[] initializeUIdata(String type) {
switch(type) { switch(type) {
case ExtensionTypes.TEMPERATURE_UNIT:
mTitle = getPrefContext().getString(R.string.temperature_preferences_title);
return getPrefContext().getResources().getStringArray(R.array.temperature_units);
case ExtensionTypes.CALENDAR: case ExtensionTypes.CALENDAR:
mTitle = getPrefContext().getString(R.string.calendar_preferences_title); mTitle = getPrefContext().getString(R.string.calendar_preferences_title);
return getPrefContext().getResources().getStringArray(R.array.calendar_type); return getPrefContext().getResources().getStringArray(R.array.calendar_type);
@@ -102,9 +99,6 @@ public class RegionalPreferencesFragment extends SettingsPreferenceFragment {
if (mType.equals(ExtensionTypes.FIRST_DAY_OF_WEEK)) { if (mType.equals(ExtensionTypes.FIRST_DAY_OF_WEEK)) {
pref.setTitle(RegionalPreferencesDataUtils.dayConverter( pref.setTitle(RegionalPreferencesDataUtils.dayConverter(
getPrefContext(), item)); getPrefContext(), item));
} else if (mType.equals(ExtensionTypes.TEMPERATURE_UNIT)) {
pref.setTitle(RegionalPreferencesDataUtils.temperatureUnitsConverter(
getPrefContext(), item));
} else if (mType.equals(ExtensionTypes.CALENDAR)) { } else if (mType.equals(ExtensionTypes.CALENDAR)) {
pref.setTitle(RegionalPreferencesDataUtils.calendarConverter( pref.setTitle(RegionalPreferencesDataUtils.calendarConverter(
getPrefContext(), item)); getPrefContext(), item));
@@ -133,10 +127,8 @@ public class RegionalPreferencesFragment extends SettingsPreferenceFragment {
switch(mType) { switch(mType) {
case ExtensionTypes.CALENDAR: case ExtensionTypes.CALENDAR:
return SettingsEnums.CALENDAR_PREFERENCE; return SettingsEnums.CALENDAR_PREFERENCE;
case ExtensionTypes.FIRST_DAY_OF_WEEK:
return SettingsEnums.FIRST_DAY_OF_WEEK_PREFERENCE;
default: default:
return SettingsEnums.TEMPERATURE_PREFERENCE; return SettingsEnums.FIRST_DAY_OF_WEEK_PREFERENCE;
} }
} }

View File

@@ -0,0 +1,60 @@
/**
* Copyright (C) 2023 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.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.widget.PreferenceCategoryController;
/** Category preference controller for temperature preferences. */
public class TemperatureUnitCategoryController extends PreferenceCategoryController {
private static final String LOG_TAG = "TemperatureUnitCategoryController";
private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT =
"temperature_unit_category";
private static final String KEY_PREFERENCE_TEMPERATURE_UNIT = "temperature_unit_list";
private PreferenceCategory mPreferenceCategory;
private TemperatureUnitListController mTemperatureUnitListController;
public TemperatureUnitCategoryController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceCategory = screen.findPreference(KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT);
if (mPreferenceCategory == null) {
Log.d(LOG_TAG, "displayPreference(), Can not find the category.");
return;
}
mPreferenceCategory.setVisible(isAvailable());
mTemperatureUnitListController = new TemperatureUnitListController(mContext,
KEY_PREFERENCE_TEMPERATURE_UNIT);
mTemperatureUnitListController.displayPreference(screen);
}
}

View File

@@ -0,0 +1,64 @@
/**
* Copyright (C) 2023 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.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 temperature preferences. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class TemperatureUnitFragment extends DashboardFragment {
private static final String LOG_TAG = "TemperatureUnitFragment";
private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT =
"temperature_unit_category";
@Override
protected int getPreferenceScreenResId() {
return R.xml.regional_preferences_temperature;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.TEMPERATURE_PREFERENCE;
}
@Override
protected String getLogTag() {
return LOG_TAG;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new TemperatureUnitCategoryController(context,
KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT));
return controllers;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.regional_preferences_temperature);
}

View File

@@ -0,0 +1,64 @@
/**
* Copyright (C) 2023 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;
/** A controller for handling all temperature preferences. */
public class TemperatureUnitListController extends RegionalPreferenceListBasePreferenceController {
private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT =
"temperature_unit_category";
private static final String KEY_PREFERENCE_TEMPERATURE_UNIT = "temperature_unit_list";
public TemperatureUnitListController(Context context, String key) {
super(context, key);
}
@Override
protected String getPreferenceTitle(String item) {
return RegionalPreferencesDataUtils.temperatureUnitsConverter(mContext, item);
}
@Override
protected String getPreferenceCategoryKey() {
return KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT;
}
@Override
public String getPreferenceKey() {
return KEY_PREFERENCE_TEMPERATURE_UNIT;
}
@Override
protected String getExtensionTypes() {
return ExtensionTypes.TEMPERATURE_UNIT;
}
@Override
protected String[] getUnitValues() {
return mContext.getResources().getStringArray(R.array.temperature_units);
}
@Override
protected int getMetricsActionKey() {
return SettingsEnums.ACTION_SET_TEMPERATURE_UNIT;
}
}

View File

@@ -0,0 +1,121 @@
/**
* Copyright (C) 2023 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.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.os.LocaleList;
import android.os.Looper;
import android.provider.Settings;
import com.android.internal.app.LocalePicker;
import com.android.settings.widget.TickButtonPreference;
import androidx.preference.PreferenceManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import java.util.Locale;
@RunWith(AndroidJUnit4.class)
public class TemperatureUnitListControllerTest {
private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT =
"temperature_unit_category";
private static final String KEY_PREFERENCE_TEMPERATURE_UNIT = "temperature_unit_list";
private Context mContext;
private PreferenceManager mPreferenceManager;
private PreferenceCategory mPreferenceCategory;
private PreferenceScreen mPreferenceScreen;
private TemperatureUnitListController mController;
private LocaleList mCacheLocaleList;
private Locale mCacheLocale;
private String mCacheProviderContent = "";
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
if (Looper.myLooper() == null) {
Looper.prepare();
}
mPreferenceManager = new PreferenceManager(mContext);
mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
mPreferenceCategory = new PreferenceCategory(mContext);
mPreferenceCategory.setKey(KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT);
mPreferenceScreen.addPreference(mPreferenceCategory);
mController = new TemperatureUnitListController(mContext, KEY_PREFERENCE_TEMPERATURE_UNIT);
mController.displayPreference(mPreferenceScreen);
mCacheProviderContent = Settings.System.getString(
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
mCacheLocale = Locale.getDefault(Locale.Category.FORMAT);
mCacheLocaleList = LocaleList.getDefault();
}
@After
public void tearDown() throws Exception {
RegionalPreferenceTestUtils.setSettingsProviderContent(
mContext, mCacheProviderContent);
Locale.setDefault(mCacheLocale);
LocalePicker.updateLocales(mCacheLocaleList);
}
@Test
public void displayPreference_setSelectPreferredTemperatureUnitIsDefault() {
TickButtonPreference pref = (TickButtonPreference) mPreferenceCategory.getPreference(0);
pref.performClick();
String record = Settings.System.getString(
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
assertThat(pref.getKey()).isEqualTo("default");
assertThat(record).contains("default");
}
@Test
public void displayPreference_setSelectPreferredTemperatureUnitIsCelsius() {
TickButtonPreference pref = (TickButtonPreference) mPreferenceCategory.getPreference(1);
pref.performClick();
String record = Settings.System.getString(
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
assertThat(pref.getKey()).isEqualTo("celsius");
assertThat(record).contains("celsius");
}
@Test
public void displayPreference_setSelectPreferredTemperatureUnitIsFahrenhe() {
TickButtonPreference pref = (TickButtonPreference) mPreferenceCategory.getPreference(2);
pref.performClick();
String record = Settings.System.getString(
mContext.getContentResolver(), Settings.System.LOCALE_PREFERENCES);
assertThat(pref.getKey()).isEqualTo("fahrenhe");
assertThat(record).contains("fahrenhe");
}
}