diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 26e7e12e3d6..a673920282f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1117,6 +1117,54 @@ android:value="true"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Swap left and right buttons Use the left mouse button as your right + + Cursor acceleration + + Faster movements with your mouse will move the cursor farther Mouse keys for %s @@ -4865,6 +4869,10 @@ Speech + + Speech + + Control speech recognition and output Pointer speed diff --git a/res/xml/language_and_region_settings.xml b/res/xml/language_and_region_settings.xml index 1d59532d3e2..7c342c6f244 100644 --- a/res/xml/language_and_region_settings.xml +++ b/res/xml/language_and_region_settings.xml @@ -44,6 +44,13 @@ android:name="classname" android:value="com.android.settings.applications.appinfo.AppLocaleDetails" /> + + + + settings:fragment="com.android.settings.regionalpreferences.NumberingSystemLocaleListFragment"> - - - - - - - - + + diff --git a/res/xml/speech_settings.xml b/res/xml/speech_settings.xml new file mode 100644 index 00000000000..08aef3f638d --- /dev/null +++ b/res/xml/speech_settings.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index aa52a2ad152..e373ccccd1d 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -100,9 +100,12 @@ public class Settings extends SettingsActivity { public static class LocalePickerActivity extends SettingsActivity { /* empty */ } public static class LanguageSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for the regional preferences settings. */ + public static class RegionSettingsActivity extends SettingsActivity { /* empty */ } public static class RegionalPreferencesActivity extends SettingsActivity { /* empty */ } public static class TemperatureUnitSettingsActivity extends SettingsActivity { /* empty */ } public static class FirstDayOfWeekSettingsActivity extends SettingsActivity { /* empty */ } + public static class MeasurementSystemSettingsActivity extends SettingsActivity { /* empty */ } + public static class NumberingSystemSettingsActivity extends SettingsActivity { /* empty */ } public static class KeyboardSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for the navigation mode settings. */ public static class NavigationModeSettingsActivity extends SettingsActivity { /* empty */ } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index c81d504b223..6097b0682da 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -315,6 +315,12 @@ public class SettingsActivity extends SettingsBaseActivity if (mMainSwitch != null) { mMainSwitch.setMetricsCategory(lookupMetricsCategory()); mMainSwitch.setTranslationZ(findViewById(R.id.main_content).getTranslationZ() + 1); + if (SettingsThemeHelper.isExpressiveTheme(this)) { + final int paddingHorizontal = getResources().getDimensionPixelSize( + com.android.settingslib.widget.theme + .R.dimen.settingslib_expressive_space_small1); + mMainSwitch.setPadding(paddingHorizontal, 0, paddingHorizontal, 0); + } } getSupportFragmentManager().addOnBackStackChangedListener(this); diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index eeecdd54844..bc2ab68764c 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -183,6 +183,9 @@ import com.android.settings.privatespace.delete.PrivateSpaceDeleteFragment; import com.android.settings.privatespace.delete.PrivateSpaceDeletionProgressFragment; import com.android.settings.privatespace.onelock.PrivateSpaceBiometricSettings; import com.android.settings.regionalpreferences.FirstDayOfWeekItemFragment; +import com.android.settings.regionalpreferences.MeasurementSystemItemFragment; +import com.android.settings.regionalpreferences.NumberingSystemLocaleListFragment; +import com.android.settings.regionalpreferences.RegionPickerFragment; import com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment; import com.android.settings.regionalpreferences.TemperatureUnitFragment; import com.android.settings.safetycenter.MoreSecurityPrivacyFragment; @@ -396,9 +399,12 @@ public class SettingsGateway { ColorAndMotionFragment.class.getName(), ColorContrastFragment.class.getName(), LongBackgroundTasksDetails.class.getName(), + RegionPickerFragment.class.getName(), RegionalPreferencesEntriesFragment.class.getName(), TemperatureUnitFragment.class.getName(), FirstDayOfWeekItemFragment.class.getName(), + MeasurementSystemItemFragment.class.getName(), + NumberingSystemLocaleListFragment.class.getName(), BatteryInfoFragment.class.getName(), UserAspectRatioDetails.class.getName(), ScreenTimeoutSettings.class.getName(), diff --git a/src/com/android/settings/deviceinfo/storage/StorageUtils.java b/src/com/android/settings/deviceinfo/storage/StorageUtils.java index 5c4a4b40f2a..5bf66a69a4a 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageUtils.java +++ b/src/com/android/settings/deviceinfo/storage/StorageUtils.java @@ -28,12 +28,15 @@ import android.os.storage.DiskInfo; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; +import android.text.SpannableString; import android.text.TextUtils; import android.text.format.Formatter; +import android.text.style.TtsSpan; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; @@ -122,11 +125,22 @@ public class StorageUtils { } /** Returns size label of changing units. (e.g., 1kB, 2MB, 3GB) */ - public static String getStorageSizeLabel(Context context, long bytes) { + public static @Nullable CharSequence getStorageSizeLabel(@NonNull Context context, long bytes) { final Formatter.BytesResult result = Formatter.formatBytes(context.getResources(), bytes, Formatter.FLAG_SHORTER); - return TextUtils.expandTemplate(context.getText(R.string.storage_size_large), + String storageSize = TextUtils.expandTemplate(context.getText(R.string.storage_size_large), result.value, result.units).toString(); + + // If storage size is less than 1KB, use TtsSpan to add additional metadata for + // text-to-speech engines. + if (bytes < 1024) { + TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(bytes).setUnit("byte").build(); + SpannableString phraseSpannable = new SpannableString(storageSize); + phraseSpannable.setSpan(ttsSpan, 0, phraseSpannable.length(), 0); + return phraseSpannable; + } + + return storageSize; } /** An AsyncTask to unmount a specified volume. */ diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt index ce1c1be743e..ed9b525b443 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt @@ -15,6 +15,7 @@ */ package com.android.settings.fuelgauge.batterysaver +import android.Manifest import android.content.Context import android.os.PowerManager import com.android.settings.R @@ -22,6 +23,7 @@ import com.android.settings.fuelgauge.BatterySaverReceiver import com.android.settings.fuelgauge.BatterySaverReceiver.BatterySaverListener import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.NoOpKeyedObservable +import com.android.settingslib.datastore.Permissions import com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_SETTINGS import com.android.settingslib.fuelgauge.BatterySaverUtils import com.android.settingslib.fuelgauge.BatteryStatus @@ -43,6 +45,11 @@ class BatterySaverPreference : override fun storage(context: Context) = BatterySaverStore(context) + override fun getReadPermissions(context: Context) = Permissions.EMPTY + + override fun getWritePermissions(context: Context) = + Permissions.anyOf(Manifest.permission.DEVICE_POWER, Manifest.permission.POWER_SAVER) + override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = ReadWritePermit.ALLOW diff --git a/src/com/android/settings/inputmethod/MousePointerAccelerationPreferenceController.java b/src/com/android/settings/inputmethod/MousePointerAccelerationPreferenceController.java new file mode 100644 index 00000000000..030f2538d0b --- /dev/null +++ b/src/com/android/settings/inputmethod/MousePointerAccelerationPreferenceController.java @@ -0,0 +1,57 @@ +/* + * Copyright 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.inputmethod; + +import android.content.Context; +import android.hardware.input.InputSettings; + +import androidx.annotation.NonNull; + +import com.android.settings.R; +import com.android.settings.core.TogglePreferenceController; + +public class MousePointerAccelerationPreferenceController extends TogglePreferenceController { + + public MousePointerAccelerationPreferenceController( + @NonNull Context context, @NonNull String key) { + super(context, key); + } + + @Override + public boolean isChecked() { + return InputSettings.isMousePointerAccelerationEnabled(mContext); + } + + @Override + public boolean setChecked(boolean isChecked) { + InputSettings.setMouseAccelerationEnabled(mContext, isChecked); + return true; + } + + @Override + public int getAvailabilityStatus() { + if (!InputSettings.isPointerAccelerationFeatureFlagEnabled()) { + return UNSUPPORTED_ON_DEVICE; + } + return AVAILABLE; + } + + @Override + public int getSliceHighlightMenuRes() { + return R.string.menu_key_system; + } +} diff --git a/src/com/android/settings/language/SpeechSettings.java b/src/com/android/settings/language/SpeechSettings.java new file mode 100644 index 00000000000..4032e3cd015 --- /dev/null +++ b/src/com/android/settings/language/SpeechSettings.java @@ -0,0 +1,106 @@ +/* + * 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 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 java.util.ArrayList; +import java.util.List; + +public class SpeechSettings extends DashboardFragment { + + private static final String TAG = "SpeechSettings"; + 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"; + + @Override + protected int getPreferenceScreenResId() { + return R.xml.speech_settings; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + public int getMetricsCategory() { + return 0; + } + + protected List createPreferenceControllers(Context context) { + return buildPreferenceControllers(context, getSettingsLifecycle()); + } + + private static List buildPreferenceControllers( + @NonNull Context context, @Nullable Lifecycle lifecycle) { + final List 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 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 createPreferenceControllers( + @NonNull Context context) { + return buildPreferenceControllers(context, null); + } + + @Override + protected boolean isPageSearchEnabled(Context context) { + if (Flags.regionalPreferencesApiEnabled()) { + return true; + } + return false; + } + }; +} diff --git a/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java b/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java index 1c5015fe7b0..8a9840f9f87 100644 --- a/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java +++ b/src/com/android/settings/regionalpreferences/NumberingPreferencesFragment.java @@ -32,8 +32,14 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -/** Provides options of numbering system to each language. */ -public class NumberingPreferencesFragment extends DashboardFragment { +/** + * Provides options of numbering system to each language. + * + * @deprecated Use {@link NumberingSystemLocaleListFragment} instead. + */ +@Deprecated +public class NumberingPreferencesFragment extends DashboardFragment { + /** Initializes variables. */ @VisibleForTesting String initTitle() { diff --git a/src/com/android/settings/regionalpreferences/NumberingSystemFormatSelectionFragment.java b/src/com/android/settings/regionalpreferences/NumberingSystemFormatSelectionFragment.java new file mode 100644 index 00000000000..bbe14b6a4ad --- /dev/null +++ b/src/com/android/settings/regionalpreferences/NumberingSystemFormatSelectionFragment.java @@ -0,0 +1,82 @@ +/* + * 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 android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.android.internal.app.LocaleHelper; +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** Provides options of numbering system to each language. */ +public class NumberingSystemFormatSelectionFragment extends DashboardFragment { + + @Override + public void onCreate(@NonNull Bundle icicle) { + super.onCreate(icicle); + getActivity().setTitle(initTitle()); + } + + /** + * Get a list of {@link AbstractPreferenceController} for this fragment. + */ + @Override + protected List createPreferenceControllers(Context context) { + NumberingSystemItemController controller = + new NumberingSystemItemController(context, getArguments()); + controller.setParentFragment(this); + List listControllers = new ArrayList<>(); + listControllers.add(controller); + return listControllers; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.regional_preference_numbering_system_page; + } + + @Override + protected String getLogTag() { + return NumberingSystemFormatSelectionFragment.class.getSimpleName(); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.NUMBERING_SYSTEM_NUMBER_FORMAT_SELECTION_PREFERENCE; + } + + private String initTitle() { + String selectedLanguage = getArguments().getString( + NumberingSystemItemController.KEY_SELECTED_LANGUAGE, ""); + if (selectedLanguage.isEmpty()) { + Log.w(getLogTag(), "No selected language."); + return ""; + } + Locale locale = Locale.forLanguageTag(selectedLanguage); + return LocaleHelper.getDisplayName(locale.stripExtensions(), locale, true); + } +} diff --git a/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java b/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java index 9f0c4041ebf..fe0a088f8bf 100644 --- a/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java +++ b/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java @@ -34,6 +34,7 @@ import com.android.internal.app.LocaleStore; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.flags.Flags; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.widget.SelectorWithWidgetPreference; @@ -158,10 +159,15 @@ public class NumberingSystemItemController extends BasePreferenceController { extra.putString(RegionalPreferencesEntriesFragment.ARG_KEY_REGIONAL_PREFERENCE, ARG_VALUE_NUMBERING_SYSTEM_SELECT); extra.putString(KEY_SELECTED_LANGUAGE, selectedLanguage); + + String destinationFragment = NumberingPreferencesFragment.class.getName(); + if (Flags.regionalPreferencesApiEnabled()) { + destinationFragment = NumberingSystemFormatSelectionFragment.class.getName(); + } new SubSettingLauncher(preference.getContext()) - .setDestination(NumberingPreferencesFragment.class.getName()) + .setDestination(destinationFragment) .setSourceMetricsCategory( - SettingsEnums.NUMBERING_SYSTEM_LANGUAGE_SELECTION_PREFERENCE) + SettingsEnums.NUMBERING_SYSTEM_LANGUAGE_SELECTION_PREFERENCE) .setArguments(extra) .launch(); } diff --git a/src/com/android/settings/regionalpreferences/NumberingSystemLocaleListFragment.java b/src/com/android/settings/regionalpreferences/NumberingSystemLocaleListFragment.java new file mode 100644 index 00000000000..6a39b23241c --- /dev/null +++ b/src/com/android/settings/regionalpreferences/NumberingSystemLocaleListFragment.java @@ -0,0 +1,107 @@ +/* + * 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 static android.provider.Settings.ACTION_NUMBERING_SYSTEM_SETTINGS; + +import android.app.Activity; +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.os.Bundle; +import android.os.LocaleList; + +import androidx.annotation.NonNull; + +import com.android.internal.app.LocaleStore; +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +/** Provides locale list for numbering system settings. */ +public class NumberingSystemLocaleListFragment extends DashboardFragment { + + @Override + public void onCreate(@NonNull Bundle icicle) { + super.onCreate(icicle); + + if (isEmptyNumberingSystemLocale()) { + getActivity().setResult(Activity.RESULT_CANCELED); + finish(); + } + + if (getIntent().getAction().equals(ACTION_NUMBERING_SYSTEM_SETTINGS)) { + // TODO: Generically log action. + } + + getActivity().setTitle(R.string.numbers_preferences_title); + getActivity().setResult(Activity.RESULT_OK); + } + + /** + * Get a list of {@link AbstractPreferenceController} for this fragment. + */ + @Override + protected List createPreferenceControllers(Context context) { + NumberingSystemItemController controller = + new NumberingSystemItemController(context, getExtraData()); + controller.setParentFragment(this); + List listControllers = new ArrayList<>(); + listControllers.add(controller); + return listControllers; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.regional_preference_numbering_system_page; + } + + @Override + protected String getLogTag() { + return NumberingSystemLocaleListFragment.class.getSimpleName(); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.NUMBERING_SYSTEM_LANGUAGE_SELECTION_PREFERENCE; + } + + private static boolean isEmptyNumberingSystemLocale() { + 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 localesHasNumberingSystems.isEmpty(); + } + + private static Bundle getExtraData() { + Bundle extra = new Bundle(); + extra.putString(RegionalPreferencesEntriesFragment.ARG_KEY_REGIONAL_PREFERENCE, + NumberingSystemItemController.ARG_VALUE_LANGUAGE_SELECT); + return extra; + } +} diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt b/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt index c581b76cd89..c93099eb9da 100644 --- a/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt +++ b/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt @@ -16,6 +16,7 @@ package com.android.settings.wifi.tether +import android.Manifest import android.app.settings.SettingsEnums import android.content.Context import android.content.Intent @@ -44,6 +45,7 @@ import com.android.settingslib.datastore.DataChangeReason import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObserver +import com.android.settingslib.datastore.Permissions import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider @@ -109,6 +111,12 @@ class WifiHotspotSwitchPreference(context: Context, dataSaverStore: KeyValueStor override val restrictionKeys get() = arrayOf(UserManager.DISALLOW_WIFI_TETHERING) + override fun getReadPermissions(context: Context) = + Permissions.allOf(Manifest.permission.ACCESS_WIFI_STATE) + + override fun getWritePermissions(context: Context) = + Permissions.allOf(Manifest.permission.TETHER_PRIVILEGED) + override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = ReadWritePermit.ALLOW diff --git a/tests/robotests/src/com/android/settings/inputmethod/MousePointerAccelerationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/MousePointerAccelerationPreferenceControllerTest.java new file mode 100644 index 00000000000..75dd741bdcc --- /dev/null +++ b/tests/robotests/src/com/android/settings/inputmethod/MousePointerAccelerationPreferenceControllerTest.java @@ -0,0 +1,122 @@ +/* + * Copyright 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.inputmethod; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.hardware.input.InputSettings; +import android.os.UserHandle; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.Settings; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.hardware.input.Flags; +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +/** Tests for {@link MousePointerAccelerationPreferenceController} */ +@RunWith(RobolectricTestRunner.class) +@Config(shadows = { + com.android.settings.testutils.shadow.ShadowSystemSettings.class, +}) +public class MousePointerAccelerationPreferenceControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private static final String PREFERENCE_KEY = "mouse_pointer_acceleration"; + private static final String SETTING_KEY = Settings.System.MOUSE_POINTER_ACCELERATION_ENABLED; + + private Context mContext; + private MousePointerAccelerationPreferenceController mController; + + @Before + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); + mController = new MousePointerAccelerationPreferenceController( + mContext, PREFERENCE_KEY); + } + + @Test + @EnableFlags(Flags.FLAG_POINTER_ACCELERATION) + public void getAvailabilityStatus_expected() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + @DisableFlags(Flags.FLAG_POINTER_ACCELERATION) + public void getAvailabilityStatus_flagIsDisabled_notSupport() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + @EnableFlags(Flags.FLAG_POINTER_ACCELERATION) + public void setChecked_true_shouldReturnTrue() { + mController.setChecked(true); + + boolean isEnabled = InputSettings.isMousePointerAccelerationEnabled(mContext); + assertThat(isEnabled).isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_POINTER_ACCELERATION) + public void setChecked_false_shouldReturnFalse() { + mController.setChecked(false); + + boolean isEnabled = InputSettings.isMousePointerAccelerationEnabled(mContext); + assertThat(isEnabled).isFalse(); + } + + @Test + @EnableFlags(Flags.FLAG_POINTER_ACCELERATION) + public void isChecked_providerPutInt1_returnTrue() { + Settings.System.putIntForUser( + mContext.getContentResolver(), + SETTING_KEY, + 1, + UserHandle.USER_CURRENT); + + boolean result = mController.isChecked(); + + assertThat(result).isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_POINTER_ACCELERATION) + public void isChecked_providerPutInt0_returnFalse() { + Settings.System.putIntForUser( + mContext.getContentResolver(), + SETTING_KEY, + 0, + UserHandle.USER_CURRENT); + + boolean result = mController.isChecked(); + + assertThat(result).isFalse(); + } +}