diff --git a/Android.bp b/Android.bp index ddd4f7ab8db..c966eca2e92 100644 --- a/Android.bp +++ b/Android.bp @@ -140,6 +140,7 @@ android_library { "android.app.flags-aconfig", "android.provider.flags-aconfig", "android.security.flags-aconfig", + "android.view.contentprotection.flags-aconfig", "keyboard_flags", ], } diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e959597063f..bce30dc7068 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -5488,7 +5488,8 @@ android:name="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService" android:foregroundServiceType="mediaPlayback" android:enabled="true" - android:exported="false" /> + android:exported="true" + android:permission="android.permission.BLUETOOTH_PRIVILEGED" /> @@ -5555,6 +5556,21 @@ android:value="true" /> + + + + + + + + + + diff --git a/res/layout/private_space_education_screen.xml b/res/layout/private_space_education_screen.xml index 3afe7f97ed9..5a34939ac66 100644 --- a/res/layout/private_space_education_screen.xml +++ b/res/layout/private_space_education_screen.xml @@ -24,10 +24,6 @@ app:sucHeaderText="@string/private_space_setup_title" app:sudDescriptionText="@string/private_space_hide_apps_summary" android:icon="@drawable/ic_private_space_icon"> - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 762288cc6f3..23939822b4a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4672,11 +4672,14 @@ Use your keyboard to control the pointer - Mouse reverse scrolling + Reverse scrolling - Scroll up to move the page down + Content moves up when you scroll down + + + Controlled scrolling - Swap left and right buttons + Swap primary mouse button Use the left mouse button as your right @@ -4723,9 +4726,13 @@ Tap to click - Tap dragging + Tap and drag to move items - Tap and drag your finger on the touchpad to move objects + Double-tap an item, hold down on the second tap, and then drag the item to move it + + Touchpad gestures + + Customize individual touchpad navigation gestures Reverse scrolling @@ -4735,9 +4742,9 @@ Click in the bottom right corner of the touchpad for more options - Pointer speed + Cursor speed - Use three finger tap + Customise 3-finger tap Pointer color @@ -4873,7 +4880,7 @@ Pointer speed - Pointer scale + Cursor size Decrease pointer scale @@ -5024,21 +5031,23 @@ Display Color and motion - - Pointer & touchpad accessibility + + Cursor & touchpad accessibility - Pointer color, pointer size & more + Size, color, type - Pointer color customization + Cursor color + + Cursor - Touchpad + Touchpad - Use system gestures + Use 3- or 4-finger gestures - When turned off, 3- or 4-finger gestures are ignored + When turned off, your touchpad will ignore 3- or 4-finger gestures - touchpad, trackpad, swipe + touchpad, trackpad, swipe Color contrast @@ -5528,7 +5537,7 @@ enter settings - Autoclick (dwell timing) + Autoclick (Dwell timing) About autoclick (dwell timing) @@ -5559,6 +5568,12 @@ Longer Auto click time + + + Cursor area size + + + Adjust the autoclick ring indicator area size Vibration & haptics @@ -13343,7 +13358,7 @@ Learn more about Thread - https://developers.home.google.com + https://support.google.com/android?p=thread_toggle Camera access diff --git a/res/xml/accessibility_autoclick_settings.xml b/res/xml/accessibility_autoclick_settings.xml index 3a1bcd3aa05..72371f3e993 100644 --- a/res/xml/accessibility_autoclick_settings.xml +++ b/res/xml/accessibility_autoclick_settings.xml @@ -76,6 +76,15 @@ settings:searchable="false" settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController"/> + + - - - - - + android:title="@string/accessibility_pointer_title"> - + + + + + + + + android:title="@string/accessibility_touchpad_system_gestures_enable_title" + settings:keywords="@string/keywords_accessibility_touchpad_system_gestures_enable" /> diff --git a/res/xml/app_language_picker.xml b/res/xml/app_language_picker.xml new file mode 100644 index 00000000000..be61aa7bb5a --- /dev/null +++ b/res/xml/app_language_picker.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + diff --git a/res/xml/mouse_settings.xml b/res/xml/mouse_settings.xml index 0abfdd0c364..a25d516edbe 100644 --- a/res/xml/mouse_settings.xml +++ b/res/xml/mouse_settings.xml @@ -20,6 +20,12 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/mouse_settings"> + + + + + + + + diff --git a/res/xml/touchpad_and_mouse_settings.xml b/res/xml/touchpad_and_mouse_settings.xml index c470a729ccb..bc9f8427e6f 100644 --- a/res/xml/touchpad_and_mouse_settings.xml +++ b/res/xml/touchpad_and_mouse_settings.xml @@ -75,6 +75,12 @@ settings:controller="com.android.settings.inputmethod.MouseSwapPrimaryButtonPreferenceController" android:order="47"/> + + + + + + diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index e373ccccd1d..91494af29c6 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -528,4 +528,5 @@ public class Settings extends SettingsActivity { public static class HearingDevicesActivity extends SettingsActivity { /* empty */ } public static class HearingDevicesPairingActivity extends SettingsActivity { /* empty */ } public static class ContactsStorageSettingsActivity extends SettingsActivity { /* empty */ } + public static class ContentProtectionSettingsActivity extends SettingsActivity { /* empty */ } } diff --git a/src/com/android/settings/accessibility/ToggleAutoclickCursorAreaSizeController.java b/src/com/android/settings/accessibility/ToggleAutoclickCursorAreaSizeController.java new file mode 100644 index 00000000000..4fde38fd0bb --- /dev/null +++ b/src/com/android/settings/accessibility/ToggleAutoclickCursorAreaSizeController.java @@ -0,0 +1,103 @@ +/* + * Copyright 2025 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.accessibility; + +import static android.content.Context.MODE_PRIVATE; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.OnLifecycleEvent; +import androidx.preference.PreferenceScreen; + +import com.android.server.accessibility.Flags; +import com.android.settings.core.SliderPreferenceController; + +/** Controller class that controls accessibility autoclick cursor area size settings. */ +public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceController + implements LifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener { + + public static final String TAG = ToggleAutoclickCursorAreaSizeController.class.getSimpleName(); + + private static final int MIN_SIZE = 20; + private static final int MAX_SIZE = 100; + private static final int DEFAULT_SIZE = 60; + + private final SharedPreferences mSharedPreferences; + + public ToggleAutoclickCursorAreaSizeController(@NonNull Context context, + @NonNull String preferenceKey) { + super(context, preferenceKey); + mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE); + } + + @OnLifecycleEvent(Lifecycle.Event.ON_START) + public void onStart() { + if (mSharedPreferences != null) { + mSharedPreferences.registerOnSharedPreferenceChangeListener(this); + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + public void onStop() { + if (mSharedPreferences != null) { + mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this); + } + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + } + + @Override + public int getAvailabilityStatus() { + return Flags.enableAutoclickIndicator() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; + } + + @Override + public void onSharedPreferenceChanged( + @NonNull SharedPreferences sharedPreferences, @Nullable String key) { + // TODO(b/383901288): Update slider. + } + + @Override + public boolean setSliderPosition(int position) { + // TODO(b/383901288): Update settings. + return true; + } + + @Override + public int getSliderPosition() { + // TODO(b/383901288): retrieve from settings and fallback to default. + return DEFAULT_SIZE; + } + + @Override + public int getMax() { + return MAX_SIZE; + } + + @Override + public int getMin() { + return MIN_SIZE; + } +} diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java index d8e834dfbf8..ab0ed45d5e9 100644 --- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java @@ -331,7 +331,9 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont MAIN_DEVICE_ID); } }); - if (Flags.enableBluetoothDeviceDetailsPolish()) { + boolean isTempBond = com.android.settingslib.flags.Flags.enableTemporaryBondDevicesUi() + && BluetoothUtils.isTemporaryBondDevice(mCachedDevice.getDevice()); + if (Flags.enableBluetoothDeviceDetailsPolish() && !isTempBond) { ImageButton renameButton = mLayoutPreference.findViewById(R.id.rename_button); renameButton.setVisibility(View.VISIBLE); renameButton.setOnClickListener(view -> { diff --git a/src/com/android/settings/bluetooth/GeneralBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/GeneralBluetoothDetailsHeaderController.java index 57a10278190..2ef8fc07721 100644 --- a/src/com/android/settings/bluetooth/GeneralBluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/GeneralBluetoothDetailsHeaderController.java @@ -89,15 +89,19 @@ public class GeneralBluetoothDetailsHeaderController extends BluetoothDetailsCon if (summary != null) { summary.setText(mCachedDevice.getConnectionSummary()); } - ImageButton renameButton = mLayoutPreference.findViewById(R.id.rename_button); - renameButton.setVisibility(View.VISIBLE); - renameButton.setOnClickListener( - view -> { - RemoteDeviceNameDialogFragment.newInstance(mCachedDevice) - .show( - mFragment.getFragmentManager(), - RemoteDeviceNameDialogFragment.TAG); - }); + boolean isTempBond = com.android.settingslib.flags.Flags.enableTemporaryBondDevicesUi() + && BluetoothUtils.isTemporaryBondDevice(mCachedDevice.getDevice()); + if (!isTempBond) { + ImageButton renameButton = mLayoutPreference.findViewById(R.id.rename_button); + renameButton.setVisibility(View.VISIBLE); + renameButton.setOnClickListener( + view -> { + RemoteDeviceNameDialogFragment.newInstance(mCachedDevice) + .show( + mFragment.getFragmentManager(), + RemoteDeviceNameDialogFragment.TAG); + }); + } } @Override diff --git a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java index 4c7c98eb48f..df24452d3ac 100644 --- a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java @@ -168,7 +168,9 @@ public class LeAudioBluetoothDetailsHeaderController extends BasePreferenceContr if (mLayoutPreference == null || mCachedDevice == null) { return; } - if (Flags.enableBluetoothDeviceDetailsPolish()) { + boolean isTempBond = com.android.settingslib.flags.Flags.enableTemporaryBondDevicesUi() + && BluetoothUtils.isTemporaryBondDevice(mCachedDevice.getDevice()); + if (Flags.enableBluetoothDeviceDetailsPolish() && !isTempBond) { ImageButton renameButton = mLayoutPreference.findViewById(R.id.rename_button); renameButton.setVisibility(View.VISIBLE); renameButton.setOnClickListener(view -> { diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java index 5d26352674f..322fd3cad19 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java @@ -77,7 +77,7 @@ public class AudioStreamMediaService extends Service { private static final int ZERO_PLAYBACK_SPEED = 0; private final PlaybackState.Builder mPlayStatePlayingBuilder = new PlaybackState.Builder() - .setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_SEEK_TO) + .setActions(PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_SEEK_TO) .setState( PlaybackState.STATE_PLAYING, STATIC_PLAYBACK_POSITION, @@ -88,7 +88,7 @@ public class AudioStreamMediaService extends Service { com.android.settings.R.drawable.ic_clear); private final PlaybackState.Builder mPlayStatePausingBuilder = new PlaybackState.Builder() - .setActions(PlaybackState.ACTION_PLAY | PlaybackState.ACTION_SEEK_TO) + .setActions(PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_SEEK_TO) .setState( PlaybackState.STATE_PAUSED, STATIC_PLAYBACK_POSITION, diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index bc2ab68764c..81dc3ad3837 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -189,6 +189,7 @@ import com.android.settings.regionalpreferences.RegionPickerFragment; import com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment; import com.android.settings.regionalpreferences.TemperatureUnitFragment; import com.android.settings.safetycenter.MoreSecurityPrivacyFragment; +import com.android.settings.security.ContentProtectionPreferenceFragment; import com.android.settings.security.LockscreenDashboardFragment; import com.android.settings.security.MemtagPage; import com.android.settings.security.SecurityAdvancedSettings; @@ -415,7 +416,8 @@ public class SettingsGateway { HearingDevicePairingFragment.class.getName(), ZenModesListFragment.class.getName(), ZenModeFragment.class.getName(), - ContactsStorageSettings.class.getName() + ContactsStorageSettings.class.getName(), + ContentProtectionPreferenceFragment.class.getName(), }; public static final String[] SETTINGS_FOR_RESTRICTED = { diff --git a/src/com/android/settings/datausage/AppDataUsagePreference.java b/src/com/android/settings/datausage/AppDataUsagePreference.java index 277c9b3fe7e..2d5c76ac777 100644 --- a/src/com/android/settings/datausage/AppDataUsagePreference.java +++ b/src/com/android/settings/datausage/AppDataUsagePreference.java @@ -21,6 +21,7 @@ import android.widget.ProgressBar; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settingslib.AppItem; import com.android.settingslib.net.UidDetail; import com.android.settingslib.net.UidDetailProvider; @@ -46,7 +47,7 @@ public class AppDataUsagePreference extends AppPreference { if (item.restricted && item.total <= 0) { setSummary(com.android.settings.R.string.data_usage_app_restricted); } else { - setSummary(DataUsageUtils.formatDataUsage(context, item.total)); + setSummary(new DataUsageFormatter(context).formatDataUsage(item.total)); } mDetail = provider.getUidDetail(item.key, false /* blocking */); if (mDetail != null) { diff --git a/src/com/android/settings/datausage/AppDataUsageSummaryController.kt b/src/com/android/settings/datausage/AppDataUsageSummaryController.kt index fb7101dba9b..1cab87f42bf 100644 --- a/src/com/android/settings/datausage/AppDataUsageSummaryController.kt +++ b/src/com/android/settings/datausage/AppDataUsageSummaryController.kt @@ -37,8 +37,7 @@ class AppDataUsageSummaryController(context: Context, preferenceKey: String) : private val dataFlow = MutableStateFlow(NetworkUsageDetailsData.AllZero) private val dataUsageFormatter = DataUsageFormatter(context) - private val emptyDataUsage = - DataUsageFormatter.FormattedDataUsage(context.getPlaceholder(), context.getPlaceholder()) + private val emptyDataUsage = context.getPlaceholder() private val totalUsageFlow = dataFlow.map { dataUsageFormatter.formatDataUsage(it.totalUsage) @@ -66,18 +65,15 @@ class AppDataUsageSummaryController(context: Context, preferenceKey: String) : val backgroundUsage by backgroundUsageFlow.collectAsStateWithLifecycle(emptyDataUsage) Preference(object : PreferenceModel { override val title = stringResource(R.string.total_size_label) - override val summary = { totalUsage.displayText } - override val summaryContentDescription = { totalUsage.contentDescription } + override val summary = { totalUsage } }) Preference(object : PreferenceModel { override val title = stringResource(R.string.data_usage_label_foreground) - override val summary = { foregroundUsage.displayText } - override val summaryContentDescription = { foregroundUsage.contentDescription } + override val summary = { foregroundUsage } }) Preference(object : PreferenceModel { override val title = stringResource(R.string.data_usage_label_background) - override val summary = { backgroundUsage.displayText } - override val summaryContentDescription = { backgroundUsage.contentDescription } + override val summary = { backgroundUsage } }) } } diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java index 69577a85574..3f240e65c09 100644 --- a/src/com/android/settings/datausage/BillingCycleSettings.java +++ b/src/com/android/settings/datausage/BillingCycleSettings.java @@ -152,8 +152,9 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements void updatePrefs() { mBillingCycle.setSummary(null); final long warningBytes = services.mPolicyEditor.getPolicyWarningBytes(mNetworkTemplate); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(requireContext()); if (warningBytes != WARNING_DISABLED) { - mDataWarning.setSummary(DataUsageUtils.formatDataUsage(getContext(), warningBytes)); + mDataWarning.setSummary(dataUsageFormatter.formatDataUsage(warningBytes)); mDataWarning.setEnabled(true); mEnableDataWarning.setChecked(true); } else { @@ -163,7 +164,7 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements } final long limitBytes = services.mPolicyEditor.getPolicyLimitBytes(mNetworkTemplate); if (limitBytes != LIMIT_DISABLED) { - mDataLimit.setSummary(DataUsageUtils.formatDataUsage(getContext(), limitBytes)); + mDataLimit.setSummary(dataUsageFormatter.formatDataUsage(limitBytes)); mDataLimit.setEnabled(true); mEnableDataLimit.setChecked(true); } else { diff --git a/src/com/android/settings/datausage/ChartDataUsagePreference.java b/src/com/android/settings/datausage/ChartDataUsagePreference.java index 0c7db715813..6a79b7a6fe9 100644 --- a/src/com/android/settings/datausage/ChartDataUsagePreference.java +++ b/src/com/android/settings/datausage/ChartDataUsagePreference.java @@ -20,7 +20,6 @@ import android.net.NetworkPolicy; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.format.DateUtils; -import android.text.format.Formatter; import android.text.style.ForegroundColorSpan; import android.util.AttributeSet; import android.util.DataUnit; @@ -34,9 +33,11 @@ import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settings.Utils; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settings.datausage.lib.NetworkCycleChartData; import com.android.settings.datausage.lib.NetworkUsageData; import com.android.settings.widget.UsageView; +import com.android.settingslib.spaprivileged.framework.common.BytesFormatter; import java.util.ArrayList; import java.util.Comparator; @@ -279,10 +280,10 @@ public class ChartDataUsagePreference extends Preference { } private CharSequence getLabel(long bytes, int str, int mLimitColor) { - Formatter.BytesResult result = Formatter.formatBytes(mResources, bytes, - Formatter.FLAG_SHORTER | Formatter.FLAG_IEC_UNITS); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(getContext()); + BytesFormatter.Result result = dataUsageFormatter.formatDataUsageWithUnits(bytes); CharSequence label = TextUtils.expandTemplate(getContext().getText(str), - result.value, result.units); + result.getNumber(), result.getUnits()); return new SpannableStringBuilder().append(label, new ForegroundColorSpan(mLimitColor), 0); } diff --git a/src/com/android/settings/datausage/DataUsageList.kt b/src/com/android/settings/datausage/DataUsageList.kt index a2932776669..8636c56de69 100644 --- a/src/com/android/settings/datausage/DataUsageList.kt +++ b/src/com/android/settings/datausage/DataUsageList.kt @@ -172,7 +172,7 @@ open class DataUsageList : DashboardFragment() { private fun updateSelectedCycle(usageData: NetworkUsageData) { Log.d(TAG, "showing cycle $usageData") - usageAmount?.title = usageData.getDataUsedString(requireContext()).displayText + usageAmount?.title = usageData.getDataUsedString(requireContext()) viewModel.selectedCycleFlow.value = usageData updateApps(usageData) diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java index 07368c728eb..010df148a9f 100644 --- a/src/com/android/settings/datausage/DataUsagePreference.java +++ b/src/com/android/settings/datausage/DataUsagePreference.java @@ -28,6 +28,7 @@ import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settingslib.net.DataUsageController; public class DataUsagePreference extends Preference implements TemplatePreference { @@ -58,8 +59,9 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc final DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate); setTitle(mTitleRes); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(getContext()); setSummary(getContext().getString(R.string.data_usage_template, - DataUsageUtils.formatDataUsage(getContext(), usageInfo.usageLevel), + dataUsageFormatter.formatDataUsage(usageInfo.usageLevel), usageInfo.period)); } final long usageLevel = controller.getHistoricalUsageLevel(template); diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java index dfb35084a12..558730cf78f 100644 --- a/src/com/android/settings/datausage/DataUsageSummary.java +++ b/src/com/android/settings/datausage/DataUsageSummary.java @@ -22,12 +22,7 @@ import android.os.Bundle; import android.os.UserManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; -import android.text.BidiFormatter; -import android.text.Spannable; -import android.text.SpannableString; import android.text.TextUtils; -import android.text.format.Formatter; -import android.text.style.RelativeSizeSpan; import android.util.EventLog; import android.util.Log; @@ -211,34 +206,6 @@ public class DataUsageSummary extends DashboardFragment { updateState(); } - @VisibleForTesting - static CharSequence formatUsage(Context context, String template, long usageLevel) { - final float LARGER_SIZE = 1.25f * 1.25f; // (1/0.8)^2 - final float SMALLER_SIZE = 1.0f / LARGER_SIZE; // 0.8^2 - return formatUsage(context, template, usageLevel, LARGER_SIZE, SMALLER_SIZE); - } - - static CharSequence formatUsage(Context context, String template, long usageLevel, - float larger, float smaller) { - final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE; - - final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(), - usageLevel, Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS); - final SpannableString enlargedValue = new SpannableString(usedResult.value); - enlargedValue.setSpan(new RelativeSizeSpan(larger), 0, enlargedValue.length(), FLAGS); - - final SpannableString amountTemplate = new SpannableString( - context.getString(com.android.internal.R.string.fileSizeSuffix) - .replace("%1$s", "^1").replace("%2$s", "^2")); - final CharSequence formattedUsage = TextUtils.expandTemplate(amountTemplate, - enlargedValue, usedResult.units); - - final SpannableString fullTemplate = new SpannableString(template); - fullTemplate.setSpan(new RelativeSizeSpan(smaller), 0, fullTemplate.length(), FLAGS); - return TextUtils.expandTemplate(fullTemplate, - BidiFormatter.getInstance().unicodeWrap(formattedUsage.toString())); - } - private void updateState() { PreferenceScreen screen = getPreferenceScreen(); for (int i = 1; i < screen.getPreferenceCount(); i++) { diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java index 6500501b210..92c9163ddc0 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java +++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java @@ -24,7 +24,6 @@ import android.telephony.SubscriptionPlan; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; -import android.text.format.Formatter; import android.text.style.AbsoluteSizeSpan; import android.util.AttributeSet; import android.view.View; @@ -39,7 +38,9 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settingslib.Utils; +import com.android.settingslib.spaprivileged.framework.common.BytesFormatter; import com.android.settingslib.utils.StringUtil; import java.util.HashMap; @@ -165,11 +166,12 @@ public class DataUsageSummaryPreference extends Preference { } private void updateDataUsageLabels(PreferenceViewHolder holder) { - TextView usageNumberField = getDataUsed(holder); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(getContext()); - final Formatter.BytesResult usedResult = Formatter.formatBytes(getContext().getResources(), - mDataplanUse, Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS); - final SpannableString usageNumberText = new SpannableString(usedResult.value); + TextView usageNumberField = getDataUsed(holder); + final BytesFormatter.Result usedResult = + dataUsageFormatter.formatDataUsageWithUnits(mDataplanUse); + final SpannableString usageNumberText = new SpannableString(usedResult.getNumber()); final int textSize = getContext().getResources().getDimensionPixelSize(R.dimen.usage_number_text_size); usageNumberText.setSpan(new AbsoluteSizeSpan(textSize), 0, usageNumberText.length(), @@ -177,7 +179,7 @@ public class DataUsageSummaryPreference extends Preference { CharSequence template = getContext().getText(R.string.data_used_formatted); CharSequence usageText = - TextUtils.expandTemplate(template, usageNumberText, usedResult.units); + TextUtils.expandTemplate(template, usageNumberText, usedResult.getUnits()); usageNumberField.setText(usageText); final MeasurableLinearLayout layout = getLayout(holder); @@ -188,13 +190,13 @@ public class DataUsageSummaryPreference extends Preference { if (dataRemaining >= 0) { usageRemainingField.setText( TextUtils.expandTemplate(getContext().getText(R.string.data_remaining), - DataUsageUtils.formatDataUsage(getContext(), dataRemaining))); + dataUsageFormatter.formatDataUsage(dataRemaining))); usageRemainingField.setTextColor( Utils.getColorAttr(getContext(), android.R.attr.colorAccent)); } else { usageRemainingField.setText( TextUtils.expandTemplate(getContext().getText(R.string.data_overusage), - DataUsageUtils.formatDataUsage(getContext(), -dataRemaining))); + dataUsageFormatter.formatDataUsage(-dataRemaining))); usageRemainingField.setTextColor( Utils.getColorAttr(getContext(), android.R.attr.colorError)); } diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt index 6f62c300a84..7a696965109 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt +++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt @@ -24,6 +24,7 @@ import android.util.Log import androidx.lifecycle.LifecycleOwner import androidx.preference.PreferenceScreen import com.android.settings.R +import com.android.settings.datausage.lib.DataUsageFormatter import com.android.settings.datausage.lib.DataUsageLib.getMobileTemplate import com.android.settings.datausage.lib.INetworkCycleDataRepository import com.android.settings.datausage.lib.NetworkCycleDataRepository @@ -72,6 +73,8 @@ open class DataUsageSummaryPreferenceController @JvmOverloads constructor( private lateinit var preference: DataUsageSummaryPreference + private val dataUsageFormatter = DataUsageFormatter(mContext) + override fun getAvailabilityStatus(subId: Int) = if (subInfo != null) AVAILABLE else CONDITIONALLY_UNAVAILABLE @@ -120,8 +123,8 @@ open class DataUsageSummaryPreferenceController @JvmOverloads constructor( private fun setDataBarSize(dataBarSize: Long) { preference.setLabels( - DataUsageUtils.formatDataUsage(mContext, /* byteValue = */ 0), - DataUsageUtils.formatDataUsage(mContext, dataBarSize) + dataUsageFormatter.formatDataUsage(/* byteValue = */ 0), + dataUsageFormatter.formatDataUsage(dataBarSize) ) } @@ -129,22 +132,22 @@ open class DataUsageSummaryPreferenceController @JvmOverloads constructor( warningBytes > 0 && limitBytes > 0 -> { TextUtils.expandTemplate( mContext.getText(R.string.cell_data_warning_and_limit), - DataUsageUtils.formatDataUsage(mContext, warningBytes), - DataUsageUtils.formatDataUsage(mContext, limitBytes), + dataUsageFormatter.formatDataUsage(warningBytes), + dataUsageFormatter.formatDataUsage(limitBytes), ) } warningBytes > 0 -> { TextUtils.expandTemplate( mContext.getText(R.string.cell_data_warning), - DataUsageUtils.formatDataUsage(mContext, warningBytes), + dataUsageFormatter.formatDataUsage(warningBytes), ) } limitBytes > 0 -> { TextUtils.expandTemplate( mContext.getText(R.string.cell_data_limit), - DataUsageUtils.formatDataUsage(mContext, limitBytes), + dataUsageFormatter.formatDataUsage(limitBytes), ) } diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java index b73da1c3ada..e32741d037b 100644 --- a/src/com/android/settings/datausage/DataUsageUtils.java +++ b/src/com/android/settings/datausage/DataUsageUtils.java @@ -31,9 +31,6 @@ import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.text.BidiFormatter; -import android.text.format.Formatter; -import android.text.format.Formatter.BytesResult; import android.util.Log; import com.android.settings.datausage.lib.DataUsageLib; @@ -54,19 +51,6 @@ public final class DataUsageUtils { private DataUsageUtils() { } - /** - * Format byte value to readable string using IEC units. - * - * @deprecated Use {@link com.android.settings.datausage.lib.DataUsageFormatter} instead. - */ - @Deprecated - public static CharSequence formatDataUsage(Context context, long byteValue) { - final BytesResult res = Formatter.formatBytes(context.getResources(), byteValue, - Formatter.FLAG_IEC_UNITS); - return BidiFormatter.getInstance().unicodeWrap(context.getString( - com.android.internal.R.string.fileSizeSuffix, res.value, res.units)); - } - /** * Test if device has an ethernet network connection. */ diff --git a/src/com/android/settings/datausage/lib/DataUsageFormatter.kt b/src/com/android/settings/datausage/lib/DataUsageFormatter.kt index 0a4c06b264b..271be94c97d 100644 --- a/src/com/android/settings/datausage/lib/DataUsageFormatter.kt +++ b/src/com/android/settings/datausage/lib/DataUsageFormatter.kt @@ -16,40 +16,20 @@ package com.android.settings.datausage.lib -import android.annotation.StringRes import android.content.Context import android.content.res.Resources -import android.icu.text.UnicodeSet -import android.icu.text.UnicodeSetSpanner -import android.text.BidiFormatter -import android.text.format.Formatter -import com.android.internal.R +import com.android.settingslib.spaprivileged.framework.common.BytesFormatter -class DataUsageFormatter(private val context: Context) { +class DataUsageFormatter(context: Context) { - data class FormattedDataUsage( - val displayText: String, - val contentDescription: String, - ) { - fun format(context: Context, @StringRes resId: Int, vararg formatArgs: Any?) = - FormattedDataUsage( - displayText = context.getString(resId, displayText, *formatArgs), - contentDescription = context.getString(resId, contentDescription, *formatArgs), - ) - } + private val bytesFormatter = BytesFormatter(context) /** Formats the data usage. */ - fun formatDataUsage(sizeBytes: Long): FormattedDataUsage { - val result = Formatter.formatBytes(context.resources, sizeBytes, Formatter.FLAG_IEC_UNITS) - return FormattedDataUsage( - displayText = BidiFormatter.getInstance().unicodeWrap( - context.getString(R.string.fileSizeSuffix, result.value, result.units) - ), - contentDescription = context.getString( - R.string.fileSizeSuffix, result.value, result.unitsContentDescription - ), - ) - } + fun formatDataUsage(sizeBytes: Long): String = + bytesFormatter.format(sizeBytes, BytesFormatter.UseCase.DataUsage) + + fun formatDataUsageWithUnits(sizeBytes: Long): BytesFormatter.Result = + bytesFormatter.formatWithUnits(sizeBytes, BytesFormatter.UseCase.DataUsage) companion object { /** @@ -59,6 +39,6 @@ class DataUsageFormatter(private val context: Context) { * in Settings, and align with other places in Settings. */ fun Resources.getBytesDisplayUnit(bytes: Long): String = - Formatter.formatBytes(this, bytes, Formatter.FLAG_IEC_UNITS).units + BytesFormatter(this).formatWithUnits(bytes, BytesFormatter.UseCase.DataUsage).units } } diff --git a/src/com/android/settings/datausage/lib/NetworkUsageData.kt b/src/com/android/settings/datausage/lib/NetworkUsageData.kt index 26578e325b4..0c34edf1059 100644 --- a/src/com/android/settings/datausage/lib/NetworkUsageData.kt +++ b/src/com/android/settings/datausage/lib/NetworkUsageData.kt @@ -20,7 +20,6 @@ import android.content.Context import android.text.format.DateUtils import android.util.Range import com.android.settings.R -import com.android.settings.datausage.lib.DataUsageFormatter.FormattedDataUsage /** * Base data structure representing usage data in a period. @@ -38,11 +37,11 @@ data class NetworkUsageData( fun formatDateRange(context: Context): String = DateUtils.formatDateRange(context, startTime, endTime, DATE_FORMAT) - fun formatUsage(context: Context): FormattedDataUsage = + fun formatUsage(context: Context): String = DataUsageFormatter(context).formatDataUsage(usage) - fun getDataUsedString(context: Context): FormattedDataUsage = - formatUsage(context).format(context, R.string.data_used_template) + fun getDataUsedString(context: Context): String = + context.getString(R.string.data_used_template, formatUsage(context)) companion object { val AllZero = NetworkUsageData( diff --git a/src/com/android/settings/development/BackAnimationPreferenceController.java b/src/com/android/settings/development/BackAnimationPreferenceController.java deleted file mode 100644 index f87ee09ef4d..00000000000 --- a/src/com/android/settings/development/BackAnimationPreferenceController.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2017 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.development; - -import static com.android.window.flags.Flags.predictiveBackSystemAnims; - -import android.content.Context; -import android.provider.Settings; - -import androidx.annotation.Nullable; -import androidx.preference.Preference; -import androidx.preference.TwoStatePreference; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.development.DeveloperOptionsPreferenceController; - -/** - * PreferenceController for enabling/disabling animation related to back button and back gestures. - */ -public class BackAnimationPreferenceController extends DeveloperOptionsPreferenceController - implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { - - private static final String BACK_NAVIGATION_ANIMATION_KEY = - "back_navigation_animation"; - - private static final int SETTING_VALUE_OFF = 0; - private static final int SETTING_VALUE_ON = 1; - @Nullable private final DevelopmentSettingsDashboardFragment mFragment; - - @VisibleForTesting - BackAnimationPreferenceController(Context context) { - super(context); - mFragment = null; - } - - - public BackAnimationPreferenceController(Context context, - @Nullable DevelopmentSettingsDashboardFragment fragment) { - super(context); - mFragment = fragment; - } - - @Override - public boolean isAvailable() { - return !predictiveBackSystemAnims(); - } - - @Override - public String getPreferenceKey() { - return BACK_NAVIGATION_ANIMATION_KEY; - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean isEnabled = (Boolean) newValue; - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, - isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF); - if (mFragment != null && isEnabled) { - BackAnimationPreferenceDialog.show(mFragment); - } - return true; - } - - @Override - public void updateState(Preference preference) { - final int mode = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_OFF); - ((TwoStatePreference) mPreference).setChecked(mode != SETTING_VALUE_OFF); - } - - @Override - protected void onDeveloperOptionsSwitchDisabled() { - super.onDeveloperOptionsSwitchDisabled(); - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_OFF); - ((TwoStatePreference) mPreference).setChecked(false); - } -} diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 605f3bbcdd8..0f8b50a542b 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -832,7 +832,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new OverlaySettingsPreferenceController(context)); controllers.add(new StylusHandwritingPreferenceController(context)); controllers.add(new IngressRateLimitPreferenceController((context))); - controllers.add(new BackAnimationPreferenceController(context, fragment)); controllers.add(new PhantomProcessPreferenceController(context)); controllers.add(new ForceEnableNotesRolePreferenceController(context)); controllers.add(new GrammaticalGenderPreferenceController(context)); diff --git a/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java index 0c7c65a7ffa..77a8a9b64f9 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java +++ b/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java @@ -65,7 +65,8 @@ public class DoubleTapPowerForCameraPreferenceController extends BasePreferenceC @Override public int getAvailabilityStatus() { - if (!DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) { + if (!DoubleTapPowerSettingsUtils + .isMultiTargetDoubleTapPowerButtonGestureAvailable(mContext)) { return UNSUPPORTED_ON_DEVICE; } return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext) diff --git a/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java index 56dda4d4953..9efeb9c3304 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java +++ b/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java @@ -65,7 +65,8 @@ public class DoubleTapPowerForWalletPreferenceController extends BasePreferenceC @Override public int getAvailabilityStatus() { - if (!DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) { + if (!DoubleTapPowerSettingsUtils + .isMultiTargetDoubleTapPowerButtonGestureAvailable(mContext)) { return UNSUPPORTED_ON_DEVICE; } return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext) diff --git a/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java index 3eb18eb931d..4a6d328b59e 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java +++ b/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java @@ -57,7 +57,8 @@ public class DoubleTapPowerMainSwitchPreferenceController @Override public int getAvailabilityStatus() { - return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext) + return DoubleTapPowerSettingsUtils + .isMultiTargetDoubleTapPowerButtonGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java index 686d64cf1f5..ee3f5f01718 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java +++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java @@ -18,6 +18,8 @@ package com.android.settings.gestures; import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_DISABLED_MODE; + import android.content.Context; import android.content.SharedPreferences; import android.provider.Settings; @@ -37,7 +39,8 @@ public class DoubleTapPowerPreferenceController extends BasePreferenceController public static boolean isSuggestionComplete(Context context, SharedPreferences prefs) { return !isGestureAvailable(context) - || prefs.getBoolean(DoubleTapPowerSettings.PREF_KEY_SUGGESTION_COMPLETE, false); + || prefs.getBoolean(DoubleTapPowerSettings.PREF_KEY_SUGGESTION_COMPLETE, + false); } private static boolean isGestureAvailable(@NonNull Context context) { @@ -46,7 +49,10 @@ public class DoubleTapPowerPreferenceController extends BasePreferenceController .getBoolean( com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); } - return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(context); + return context.getResources() + .getInteger( + com.android.internal.R.integer.config_doubleTapPowerGestureMode) + != DOUBLE_TAP_POWER_DISABLED_MODE; } @Override @@ -56,7 +62,9 @@ public class DoubleTapPowerPreferenceController extends BasePreferenceController @Override public void displayPreference(@NonNull PreferenceScreen screen) { - if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap()) { + if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap() + || !DoubleTapPowerSettingsUtils + .isMultiTargetDoubleTapPowerButtonGestureAvailable(mContext)) { final Preference preference = screen.findPreference(getPreferenceKey()); if (preference != null) { preference.setTitle(R.string.double_tap_power_for_camera_title); @@ -68,12 +76,14 @@ public class DoubleTapPowerPreferenceController extends BasePreferenceController @Override @NonNull public CharSequence getSummary() { - if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap()) { + if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap() + || !DoubleTapPowerSettingsUtils + .isMultiTargetDoubleTapPowerButtonGestureAvailable(mContext)) { final boolean isCameraDoubleTapPowerGestureEnabled = Settings.Secure.getInt( - mContext.getContentResolver(), - CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, - DoubleTapPowerToOpenCameraPreferenceController.ON) + mContext.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, + DoubleTapPowerToOpenCameraPreferenceController.ON) == DoubleTapPowerToOpenCameraPreferenceController.ON; return mContext.getText( isCameraDoubleTapPowerGestureEnabled @@ -85,7 +95,7 @@ public class DoubleTapPowerPreferenceController extends BasePreferenceController mContext.getText(com.android.settings.R.string.gesture_setting_on); final CharSequence actionString = DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureForCameraLaunchEnabled( - mContext) + mContext) ? mContext.getText(R.string.double_tap_power_camera_action_summary) : mContext.getText(R.string.double_tap_power_wallet_action_summary); return mContext.getString(R.string.double_tap_power_summary, onString, actionString); diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettings.java b/src/com/android/settings/gestures/DoubleTapPowerSettings.java index 076f23fa660..892eb4a5422 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerSettings.java +++ b/src/com/android/settings/gestures/DoubleTapPowerSettings.java @@ -39,9 +39,11 @@ public class DoubleTapPowerSettings extends DashboardFragment { public static final String PREF_KEY_SUGGESTION_COMPLETE = "pref_double_tap_power_suggestion_complete"; + private Context mContext; @Override public void onAttach(Context context) { + mContext = context; super.onAttach(context); SuggestionFeatureProvider suggestionFeatureProvider = FeatureFactory.getFeatureFactory().getSuggestionFeatureProvider(); @@ -61,7 +63,15 @@ public class DoubleTapPowerSettings extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap() + return getDoubleTapPowerSettingsResId(mContext); + } + + private static int getDoubleTapPowerSettingsResId(Context context) { + if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap()) { + return R.xml.double_tap_power_to_open_camera_settings; + } + return DoubleTapPowerSettingsUtils + .isMultiTargetDoubleTapPowerButtonGestureAvailable(context) ? R.xml.double_tap_power_settings : R.xml.double_tap_power_to_open_camera_settings; } @@ -73,11 +83,7 @@ public class DoubleTapPowerSettings extends DashboardFragment { public List getXmlResourcesToIndex( @NonNull Context context, boolean enabled) { final SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = - android.service.quickaccesswallet.Flags - .launchWalletOptionOnPowerDoubleTap() - ? R.xml.double_tap_power_settings - : R.xml.double_tap_power_to_open_camera_settings; + sir.xmlResId = getDoubleTapPowerSettingsResId(context); return List.of(sir); } }; diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java b/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java index a1bf9cbd48c..6347c0f48c5 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java +++ b/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java @@ -29,6 +29,16 @@ import com.android.internal.R; /** Common code for double tap power settings shared between controllers. */ final class DoubleTapPowerSettingsUtils { + /** Configuration value indicating double tap power button gesture is disabled. */ + static final int DOUBLE_TAP_POWER_DISABLED_MODE = 0; + /** Configuration value indicating double tap power button gesture should launch camera. */ + static final int DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE = 1; + /** + * Configuration value indicating double tap power button gesture should launch one of many + * target actions. + */ + static final int DOUBLE_TAP_POWER_MULTI_TARGET_MODE = 2; + /** Setting storing whether the double tap power button gesture is enabled. */ private static final String DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED = Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED; @@ -52,19 +62,23 @@ final class DoubleTapPowerSettingsUtils { /** * @return true if double tap power button gesture is available. */ - public static boolean isDoubleTapPowerButtonGestureAvailable(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_doubleTapPowerGestureEnabled); + public static boolean isMultiTargetDoubleTapPowerButtonGestureAvailable( + @NonNull Context context) { + return context.getResources() + .getInteger( + R.integer.config_doubleTapPowerGestureMode) + == DOUBLE_TAP_POWER_MULTI_TARGET_MODE; } /** * Gets double tap power button gesture enable or disable flag from Settings provider. * - * @return true if double tap on the power button gesture is currently enabled. * @param context App context + * @return true if double tap on the power button gesture is currently enabled. */ public static boolean isDoubleTapPowerButtonGestureEnabled(@NonNull Context context) { return Settings.Secure.getInt( - context.getContentResolver(), DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, ON) + context.getContentResolver(), DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, ON) == ON; } @@ -72,7 +86,7 @@ final class DoubleTapPowerSettingsUtils { * Sets double tap power button gesture enable or disable flag to Settings provider. * * @param context App context - * @param enable enable or disable double tap power button gesture. + * @param enable enable or disable double tap power button gesture. * @return {@code true} if the setting is updated. */ public static boolean setDoubleTapPowerButtonGestureEnabled( @@ -84,19 +98,19 @@ final class DoubleTapPowerSettingsUtils { } /** - * @return true if double tap on the power button gesture for camera launch is currently - * enabled. * @param context App context + * @return true if double tap on the power button gesture for camera launch is currently + * enabled. */ public static boolean isDoubleTapPowerButtonGestureForCameraLaunchEnabled( @NonNull Context context) { return Settings.Secure.getInt( - context.getContentResolver(), - DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION, - context.getResources() - .getInteger( - com.android.internal.R.integer - .config_defaultDoubleTapPowerGestureAction)) + context.getContentResolver(), + DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION, + context.getResources() + .getInteger( + com.android.internal.R.integer + .config_doubleTapPowerGestureMultiTargetDefaultAction)) == DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE; } diff --git a/src/com/android/settings/inputmethod/InputSettingPreferenceController.java b/src/com/android/settings/inputmethod/InputSettingPreferenceController.java index 8dda8c5cd51..9cc8d05be25 100644 --- a/src/com/android/settings/inputmethod/InputSettingPreferenceController.java +++ b/src/com/android/settings/inputmethod/InputSettingPreferenceController.java @@ -40,6 +40,8 @@ import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; import com.android.settings.keyboard.Flags; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.concurrent.TimeUnit; @@ -51,6 +53,7 @@ public abstract class InputSettingPreferenceController extends TogglePreferenceC private static final int CUSTOM_PROGRESS_INTERVAL = 100; private static final long MILLISECOND_IN_SECONDS = TimeUnit.SECONDS.toMillis(1); private final ContentResolver mContentResolver; + protected final MetricsFeatureProvider mMetricsFeatureProvider; private final ContentObserver mContentObserver = new ContentObserver(new Handler(true)) { @Override public void onChange(boolean selfChange, Uri uri) { @@ -72,10 +75,14 @@ public abstract class InputSettingPreferenceController extends TogglePreferenceC return 0; } + protected void onCustomValueUpdated(int thresholdTimeMillis) { + } + public InputSettingPreferenceController(@NonNull Context context, @NonNull String preferenceKey) { super(context, preferenceKey); mContentResolver = context.getContentResolver(); + mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @Override @@ -150,6 +157,7 @@ public abstract class InputSettingPreferenceController extends TogglePreferenceC } } updateInputSettingKeysValue(threshold); + onCustomValueUpdated(threshold); }) .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss()) .create(); diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java index 6bd836feb08..9a0f1c0d6e3 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java @@ -16,6 +16,10 @@ package com.android.settings.inputmethod; +import static android.app.settings.SettingsEnums.ACTION_BOUNCE_KEYS_CUSTOM_VALUE_CHANGE; +import static android.app.settings.SettingsEnums.ACTION_BOUNCE_KEYS_DISABLED; +import static android.app.settings.SettingsEnums.ACTION_BOUNCE_KEYS_ENABLED; + import android.content.Context; import android.hardware.input.InputSettings; import android.net.Uri; @@ -78,9 +82,17 @@ public class KeyboardAccessibilityBounceKeysController extends @Override public boolean setChecked(boolean isChecked) { updateInputSettingKeysValue(isChecked ? BOUNCE_KEYS_THRESHOLD : 0); + mMetricsFeatureProvider.action(mContext, + isChecked ? ACTION_BOUNCE_KEYS_ENABLED : ACTION_BOUNCE_KEYS_DISABLED); return true; } + @Override + protected void onCustomValueUpdated(int thresholdTimeMillis) { + mMetricsFeatureProvider.action(mContext, ACTION_BOUNCE_KEYS_CUSTOM_VALUE_CHANGE, + thresholdTimeMillis); + } + @Override protected void onInputSettingUpdated() { if (mPrimaryPreference != null) { diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java index 34f53c47dce..2db0e05a2de 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java @@ -16,6 +16,9 @@ package com.android.settings.inputmethod; +import static android.app.settings.SettingsEnums.ACTION_MOUSE_KEYS_DISABLED; +import static android.app.settings.SettingsEnums.ACTION_MOUSE_KEYS_ENABLED; + import android.content.Context; import android.hardware.input.InputSettings; import android.net.Uri; @@ -63,6 +66,8 @@ public class KeyboardAccessibilityMouseKeysController extends public boolean setChecked(boolean isChecked) { InputSettings.setAccessibilityMouseKeysEnabled(mContext, isChecked); + mMetricsFeatureProvider.action(mContext, + isChecked ? ACTION_MOUSE_KEYS_ENABLED : ACTION_MOUSE_KEYS_DISABLED); return true; } diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java index 857623a6839..451742ff2d4 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java @@ -16,6 +16,10 @@ package com.android.settings.inputmethod; +import static android.app.settings.SettingsEnums.ACTION_SLOW_KEYS_CUSTOM_VALUE_CHANGE; +import static android.app.settings.SettingsEnums.ACTION_SLOW_KEYS_DISABLED; +import static android.app.settings.SettingsEnums.ACTION_SLOW_KEYS_ENABLED; + import android.content.Context; import android.hardware.input.InputSettings; import android.net.Uri; @@ -58,6 +62,8 @@ public class KeyboardAccessibilitySlowKeysController extends @Override public boolean setChecked(boolean isChecked) { updateInputSettingKeysValue(isChecked ? SLOW_KEYS_THRESHOLD : 0); + mMetricsFeatureProvider.action(mContext, + isChecked ? ACTION_SLOW_KEYS_ENABLED : ACTION_SLOW_KEYS_DISABLED); return true; } @@ -98,6 +104,12 @@ public class KeyboardAccessibilitySlowKeysController extends InputSettings.setAccessibilitySlowKeysThreshold(mContext, thresholdTimeMillis); } + @Override + protected void onCustomValueUpdated(int thresholdTimeMillis) { + mMetricsFeatureProvider.action(mContext, + ACTION_SLOW_KEYS_CUSTOM_VALUE_CHANGE, thresholdTimeMillis); + } + @Override protected int getInputSettingKeysValue() { return InputSettings.getAccessibilitySlowKeysThreshold(mContext); diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java index fd2cb2e6e11..f0dcc9350c6 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java @@ -16,6 +16,9 @@ package com.android.settings.inputmethod; +import static android.app.settings.SettingsEnums.ACTION_STICKY_KEYS_DISABLED; +import static android.app.settings.SettingsEnums.ACTION_STICKY_KEYS_ENABLED; + import android.content.Context; import android.hardware.input.InputSettings; import android.net.Uri; @@ -52,6 +55,8 @@ public class KeyboardAccessibilityStickyKeysController extends public boolean setChecked(boolean isChecked) { InputSettings.setAccessibilityStickyKeysEnabled(mContext, isChecked); + mMetricsFeatureProvider.action(mContext, + isChecked ? ACTION_STICKY_KEYS_ENABLED : ACTION_STICKY_KEYS_DISABLED); return true; } diff --git a/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java b/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java index 39e605d1d59..8c06c30ec28 100644 --- a/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java +++ b/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java @@ -68,7 +68,7 @@ public class KeyboardRepeatKeysMainFragment extends DashboardFragment @Override public int getMetricsCategory() { - return SettingsEnums.PHYSICAL_KEYBOARD_A11Y; + return SettingsEnums.PHYSICAL_KEYBOARD_REPEAT_KEYS; } @Override diff --git a/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java b/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java index dd9c1ddf62f..1f6035f03ec 100644 --- a/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java +++ b/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java @@ -83,7 +83,7 @@ public class MouseKeysMainPageFragment extends DashboardFragment @Override public int getMetricsCategory() { - return SettingsEnums.PHYSICAL_KEYBOARD_A11Y; + return SettingsEnums.SETTINGS_PHYSICAL_KEYBOARD_MOUSE_KEYS; } @Override diff --git a/src/com/android/settings/inputmethod/MouseReverseVerticalScrollingPreferenceController.java b/src/com/android/settings/inputmethod/MouseReverseVerticalScrollingPreferenceController.java index 977e906e2a5..a1a86153577 100644 --- a/src/com/android/settings/inputmethod/MouseReverseVerticalScrollingPreferenceController.java +++ b/src/com/android/settings/inputmethod/MouseReverseVerticalScrollingPreferenceController.java @@ -16,6 +16,9 @@ package com.android.settings.inputmethod; +import static android.app.settings.SettingsEnums.ACTION_MOUSE_REVERSE_VERTICAL_SCROLLING_DISABLED; +import static android.app.settings.SettingsEnums.ACTION_MOUSE_REVERSE_VERTICAL_SCROLLING_ENABLED; + import android.content.Context; import android.hardware.input.InputSettings; @@ -23,12 +26,16 @@ import androidx.annotation.NonNull; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class MouseReverseVerticalScrollingPreferenceController extends TogglePreferenceController { + private final MetricsFeatureProvider mMetricsFeatureProvider; public MouseReverseVerticalScrollingPreferenceController( @NonNull Context context, @NonNull String key) { super(context, key); + mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @Override @@ -39,6 +46,9 @@ public class MouseReverseVerticalScrollingPreferenceController extends TogglePre @Override public boolean setChecked(boolean isChecked) { InputSettings.setMouseReverseVerticalScrolling(mContext, isChecked); + mMetricsFeatureProvider.action(mContext, + isChecked ? ACTION_MOUSE_REVERSE_VERTICAL_SCROLLING_ENABLED : + ACTION_MOUSE_REVERSE_VERTICAL_SCROLLING_DISABLED); return true; } diff --git a/src/com/android/settings/inputmethod/MouseScrollingAccelerationPreferenceController.java b/src/com/android/settings/inputmethod/MouseScrollingAccelerationPreferenceController.java new file mode 100644 index 00000000000..7c9ff2aefe8 --- /dev/null +++ b/src/com/android/settings/inputmethod/MouseScrollingAccelerationPreferenceController.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 MouseScrollingAccelerationPreferenceController extends TogglePreferenceController { + + public MouseScrollingAccelerationPreferenceController( + @NonNull Context context, @NonNull String key) { + super(context, key); + } + + @Override + public boolean isChecked() { + return !InputSettings.isMouseScrollingAccelerationEnabled(mContext); + } + + @Override + public boolean setChecked(boolean isChecked) { + InputSettings.setMouseScrollingAcceleration(mContext, !isChecked); + return true; + } + + @Override + public int getAvailabilityStatus() { + if (!InputSettings.isMouseScrollingAccelerationFeatureFlagEnabled()) { + return UNSUPPORTED_ON_DEVICE; + } + return AVAILABLE; + } + + @Override + public int getSliceHighlightMenuRes() { + return R.string.menu_key_system; + } +} diff --git a/src/com/android/settings/inputmethod/MouseSwapPrimaryButtonPreferenceController.java b/src/com/android/settings/inputmethod/MouseSwapPrimaryButtonPreferenceController.java index 88199d8d64e..63dfc053df6 100644 --- a/src/com/android/settings/inputmethod/MouseSwapPrimaryButtonPreferenceController.java +++ b/src/com/android/settings/inputmethod/MouseSwapPrimaryButtonPreferenceController.java @@ -16,6 +16,9 @@ package com.android.settings.inputmethod; +import static android.app.settings.SettingsEnums.ACTION_MOUSE_SWAP_PRIMARY_BUTTON_DISABLED; +import static android.app.settings.SettingsEnums.ACTION_MOUSE_SWAP_PRIMARY_BUTTON_ENABLED; + import android.content.Context; import android.hardware.input.InputSettings; @@ -23,12 +26,16 @@ import androidx.annotation.NonNull; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class MouseSwapPrimaryButtonPreferenceController extends TogglePreferenceController { + private final MetricsFeatureProvider mMetricsFeatureProvider; public MouseSwapPrimaryButtonPreferenceController( @NonNull Context context, @NonNull String key) { super(context, key); + mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @Override @@ -39,6 +46,9 @@ public class MouseSwapPrimaryButtonPreferenceController extends TogglePreference @Override public boolean setChecked(boolean isChecked) { InputSettings.setMouseSwapPrimaryButton(mContext, isChecked); + mMetricsFeatureProvider.action(mContext, + isChecked ? ACTION_MOUSE_SWAP_PRIMARY_BUTTON_ENABLED : + ACTION_MOUSE_SWAP_PRIMARY_BUTTON_DISABLED); return true; } diff --git a/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt b/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt index aa113b692dc..2d8c0f77024 100644 --- a/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt +++ b/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt @@ -31,7 +31,6 @@ import androidx.preference.PreferenceScreen import com.android.settings.R import com.android.settings.core.BasePreferenceController import com.android.settings.datausage.DataUsageUtils -import com.android.settings.datausage.lib.DataUsageFormatter.FormattedDataUsage import com.android.settings.datausage.lib.DataUsageLib import com.android.settings.datausage.lib.NetworkCycleDataRepository import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.AllTimeRange @@ -88,7 +87,7 @@ class DataUsagePreferenceController(context: Context, key: String) : getDataUsageSummaryAndEnabled() } preference.isEnabled = enabled - preference.summary = summary?.displayText + preference.summary = summary } private fun getNetworkTemplate(): NetworkTemplate? = @@ -100,12 +99,16 @@ class DataUsagePreferenceController(context: Context, key: String) : fun createNetworkCycleDataRepository(): NetworkCycleDataRepository? = networkTemplate?.let { NetworkCycleDataRepository(mContext, it) } - private fun getDataUsageSummaryAndEnabled(): Pair { + private fun getDataUsageSummaryAndEnabled(): Pair { val repository = createNetworkCycleDataRepository() ?: return null to false repository.loadFirstCycle()?.let { usageData -> - val formattedDataUsage = usageData.formatUsage(mContext) - .format(mContext, R.string.data_usage_template, usageData.formatDateRange(mContext)) + val formattedDataUsage = + mContext.getString( + R.string.data_usage_template, + usageData.formatUsage(mContext), + usageData.formatDateRange(mContext), + ) val hasUsage = usageData.usage > 0 || repository.queryUsage(AllTimeRange).usage > 0 return formattedDataUsage to hasUsage } diff --git a/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt b/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt index 7b8cf8c8b55..7e6e72613b7 100644 --- a/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt +++ b/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt @@ -113,7 +113,7 @@ private class AppDataUsagePresenter( } else { context.getString( R.string.data_summary_format, - appUsageData.formatUsage(context).displayText, + appUsageData.formatUsage(context), appUsageData.formatStartDate(context), ) } diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleAutoclickCursorAreaSizeControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleAutoclickCursorAreaSizeControllerTest.java new file mode 100644 index 00000000000..b2c5f06263d --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleAutoclickCursorAreaSizeControllerTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2025 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.accessibility; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.kotlin.VerificationKt.verify; + +import android.content.Context; +import android.content.SharedPreferences; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; + +import androidx.test.core.app.ApplicationProvider; + +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.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link ToggleAutoclickCursorAreaSizeController}. */ +@RunWith(RobolectricTestRunner.class) +public class ToggleAutoclickCursorAreaSizeControllerTest { + + private static final String PREFERENCE_KEY = "accessibility_control_autoclick_cursor_area_size"; + private static final String PACKAGE = "package"; + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private final Context mContext = ApplicationProvider.getApplicationContext(); + private ToggleAutoclickCursorAreaSizeController mController; + + @Before + public void setUp() { + mController = new ToggleAutoclickCursorAreaSizeController(mContext, PREFERENCE_KEY); + } + + @Test + @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) + public void getAvailabilityStatus_availableWhenFlagOn() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + @DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) + public void getAvailabilityStatus_conditionallyUnavailableWhenFlagOn() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } + + @Test + public void onStart_registerOnSharedPreferenceChangeListener() { + final SharedPreferences prefs = mock(SharedPreferences.class); + final Context context = mock(Context.class); + doReturn(PACKAGE).when(context).getPackageName(); + doReturn(prefs).when(context).getSharedPreferences(anyString(), anyInt()); + final ToggleAutoclickCursorAreaSizeController controller = + new ToggleAutoclickCursorAreaSizeController(context, PREFERENCE_KEY); + + controller.onStart(); + + verify(prefs).registerOnSharedPreferenceChangeListener(controller); + } + + @Test + public void onStop_unregisterOnSharedPreferenceChangeListener() { + final SharedPreferences prefs = mock(SharedPreferences.class); + final Context context = mock(Context.class); + doReturn(PACKAGE).when(context).getPackageName(); + doReturn(prefs).when(context).getSharedPreferences(anyString(), anyInt()); + final ToggleAutoclickCursorAreaSizeController controller = + new ToggleAutoclickCursorAreaSizeController(context, PREFERENCE_KEY); + + controller.onStop(); + + verify(prefs).unregisterOnSharedPreferenceChangeListener(controller); + } +} diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java index fc1df5a0f69..53a8f5d2cdd 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java @@ -79,9 +79,12 @@ public class AdvancedBluetoothDetailsHeaderControllerTest { private static final int LOW_BATTERY_LEVEL_THRESHOLD = 15; private static final int BATTERY_LEVEL_5 = 5; private static final int BATTERY_LEVEL_50 = 50; + private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25; private static final String ICON_URI = "content://test.provider/icon.png"; private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C"; private static final String DEVICE_SUMMARY = "test summary"; + private static final String TEMP_BOND_METADATA = + "le_audio_sharing"; private Context mContext; @@ -531,6 +534,23 @@ public class AdvancedBluetoothDetailsHeaderControllerTest { assertThat(button.getVisibility()).isEqualTo(View.VISIBLE); } + @Test + @EnableFlags({Flags.FLAG_ENABLE_BLUETOOTH_DEVICE_DETAILS_POLISH, + com.android.settingslib.flags.Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI}) + public void temporaryBondDevice_renameButtonNotShown() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) + .thenReturn("true".getBytes()); + when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS)) + .thenReturn(TEMP_BOND_METADATA.getBytes()); + Set cacheBluetoothDevices = new HashSet<>(); + when(mCachedDevice.getMemberDevice()).thenReturn(cacheBluetoothDevices); + + mController.onStart(); + + ImageButton button = mLayoutPreference.findViewById(R.id.rename_button); + assertThat(button.getVisibility()).isEqualTo(View.GONE); + } + private void assertBatteryPredictionVisible(LinearLayout linearLayout, int visible) { final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction); assertThat(textView.getVisibility()).isEqualTo(visible); diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index 2a9cca9c669..54e4554802b 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -16,8 +16,6 @@ package com.android.settings.datausage; -import static com.google.common.truth.Truth.assertThat; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -92,15 +90,6 @@ public class DataUsageSummaryTest { doNothing().when(mDataUsageSummary).addWifiSection(); } - @Test - public void formatUsage_shouldLookLikeFormatFileSize() { - final long usage = 2147483648L; // 2GB - final String formattedUsage = - DataUsageSummary.formatUsage(mContext, "^1", usage).toString(); - final CharSequence formattedInIECUnit = DataUsageUtils.formatDataUsage(mContext, usage); - assertThat(formattedUsage).isEqualTo(formattedInIECUnit); - } - @Test @Config(shadows = ShadowSubscriptionManager.class) public void configuration_withSim_shouldShowMobileAndWifi() { diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java index a465d742356..f78bb472805 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java @@ -29,7 +29,6 @@ import android.content.Context; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.telephony.TelephonyManager; -import android.util.DataUnit; import org.junit.Before; import org.junit.Test; @@ -74,14 +73,6 @@ public final class DataUsageUtilsTest { assertThat(hasMobileData).isFalse(); } - @Test - public void formatDataUsage_useIECUnit() { - final CharSequence formattedDataUsage = DataUsageUtils.formatDataUsage( - mContext, DataUnit.GIBIBYTES.toBytes(1)); - - assertThat(formattedDataUsage).isEqualTo("1.00 GB"); - } - @Test public void hasEthernet_shouldQueryEthernetSummaryForUser() throws Exception { ShadowPackageManager pm = shadowOf(RuntimeEnvironment.application.getPackageManager()); diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java index cc710ec29e6..1647a9c1862 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java @@ -16,6 +16,9 @@ package com.android.settings.gestures; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_DISABLED_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; @@ -72,7 +75,8 @@ public class DoubleTapPowerForCameraPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerGestureNotAvailable_preferenceUnsupported() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_DISABLED_MODE); assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); @@ -80,7 +84,8 @@ public class DoubleTapPowerForCameraPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerButtonDisabled_preferenceDisabled() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); assertThat(mController.getAvailabilityStatus()) @@ -89,7 +94,8 @@ public class DoubleTapPowerForCameraPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerCameraLaunchEnabled_preferenceEnabled() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); assertThat(mController.getAvailabilityStatus()) diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java index c86a82edd0d..60b35102d99 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java @@ -16,6 +16,9 @@ package com.android.settings.gestures; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_DISABLED_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; @@ -74,7 +77,8 @@ public class DoubleTapPowerForWalletPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerGestureNotAvailable_preferenceUnsupported() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_DISABLED_MODE); assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); @@ -82,7 +86,8 @@ public class DoubleTapPowerForWalletPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerButtonDisabled_preferenceDisabled() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); assertThat(mController.getAvailabilityStatus()) @@ -91,7 +96,8 @@ public class DoubleTapPowerForWalletPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerWalletLaunchEnabled_preferenceEnabled() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); assertThat(mController.getAvailabilityStatus()) diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java index 502e52ec6c3..5d9656c466b 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java @@ -16,6 +16,9 @@ package com.android.settings.gestures; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_DISABLED_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; @@ -54,7 +57,8 @@ public class DoubleTapPowerMainSwitchPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerGestureAvailable_preferenceEnabled() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.AVAILABLE); @@ -62,7 +66,8 @@ public class DoubleTapPowerMainSwitchPreferenceControllerTest { @Test public void getAvailabilityStatus_setDoubleTapPowerGestureUnavailable_preferenceUnsupported() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_DISABLED_MODE); assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java index 17b03f355bf..b2ff5a65b59 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java @@ -20,6 +20,9 @@ import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_D import static android.provider.Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED; import static com.android.settings.gestures.DoubleTapPowerPreferenceController.isSuggestionComplete; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_DISABLED_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; import static com.android.settings.gestures.DoubleTapPowerToOpenCameraPreferenceController.OFF; import static com.android.settings.gestures.DoubleTapPowerToOpenCameraPreferenceController.ON; @@ -58,7 +61,8 @@ import org.robolectric.annotation.Config; @Config(shadows = SettingsShadowResources.class) public class DoubleTapPowerPreferenceControllerTest { - @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private Context mContext; private ContentResolver mContentResolver; private DoubleTapPowerPreferenceController mController; @@ -83,18 +87,30 @@ public class DoubleTapPowerPreferenceControllerTest { @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void isAvailable_flagEnabled_configIsTrue_returnsTrue() { + public void isAvailable_flagEnabled_configIsMultiTargetMode_returnsTrue() { SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, Boolean.TRUE); + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); assertThat(mController.isAvailable()).isTrue(); } @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void isAvailable_flagEnabled_configIsFalse_returnsFalse() { + public void isAvailable_flagEnabled_configIsCameraLaunchMode_returnsTrue() { SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, Boolean.FALSE); + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isAvailable_flagEnabled_configIsDisabledMode_returnsFalse() { + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_DISABLED_MODE); assertThat(mController.isAvailable()).isFalse(); } @@ -121,18 +137,20 @@ public class DoubleTapPowerPreferenceControllerTest { @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void isSuggestionCompleted_enableFlag_doubleTapPower_trueWhenNotAvailable() { + public void isSuggestionCompleted_flagEnabled_configIsMultiTargetMode_trueWhenNotAvailable() { SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, false); + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_DISABLED_MODE); assertThat(isSuggestionComplete(mContext, null /* prefs */)).isTrue(); } @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void isSuggestionCompleted_enableFlag_doubleTapPower_falseWhenNotVisited() { + public void isSuggestionCompleted_enableFlag_configIsMultiTargetMode_falseWhenNotVisited() { SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, true); + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); // No stored value in shared preferences if not visited yet. final SharedPreferences prefs = new SuggestionFeatureProviderImpl().getSharedPrefs(mContext); @@ -142,9 +160,10 @@ public class DoubleTapPowerPreferenceControllerTest { @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void isSuggestionCompleted_enableFlag_doubleTapPower_trueWhenVisited() { + public void isSuggestionCompleted_enableFlag_configIsMultiTargetMode_trueWhenVisited() { SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, true); + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); // No stored value in shared preferences if not visited yet. final SharedPreferences prefs = new SuggestionFeatureProviderImpl().getSharedPrefs(mContext); @@ -189,13 +208,30 @@ public class DoubleTapPowerPreferenceControllerTest { @Test @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void displayPreference_flagDisabled_doubleTapPowerLegacyTitleIsDisplayed() { + public void displayPreference_flagDisabled_cameraLaunchTitleIsDisplayed() { mController.displayPreference(mScreen); assertThat( - TextUtils.equals( - mPreference.getTitle(), - mContext.getText(R.string.double_tap_power_for_camera_title))) + TextUtils.equals( + mPreference.getTitle(), + mContext.getText(R.string.double_tap_power_for_camera_title))) + .isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void + displayPreference_flagEnabled_configIsCameraLaunchMode_cameraLaunchTitleIsDisplayed() { + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); + + mController.displayPreference(mScreen); + + assertThat( + TextUtils.equals( + mPreference.getTitle(), + mContext.getText(R.string.double_tap_power_for_camera_title))) .isTrue(); } @@ -206,9 +242,9 @@ public class DoubleTapPowerPreferenceControllerTest { Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON); assertThat( - TextUtils.equals( - mController.getSummary(), - mContext.getText(R.string.gesture_setting_on))) + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_on))) .isTrue(); } @@ -219,9 +255,42 @@ public class DoubleTapPowerPreferenceControllerTest { Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, OFF); assertThat( - TextUtils.equals( - mController.getSummary(), - mContext.getText(R.string.gesture_setting_off))) + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_off))) + .isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getSummary_flagEnabled_doubleTapPowerEnabled_configIsCameraLaunchMode_returnsOn() { + // Set the setting to be enabled. + Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON); + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_on))) + .isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void + getSummary_flagEnabled_doubleTapPowerDisabled_configIsCameraLaunchMode_returnsOff() { + // Set the setting to be disabled. + Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, OFF); + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_off))) .isTrue(); } @@ -233,9 +302,9 @@ public class DoubleTapPowerPreferenceControllerTest { mContentResolver, DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, 0 /* OFF */); assertThat( - TextUtils.equals( - mController.getSummary(), - mContext.getText(R.string.gesture_setting_off))) + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_off))) .isTrue(); } @@ -248,13 +317,13 @@ public class DoubleTapPowerPreferenceControllerTest { DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); assertThat( - TextUtils.equals( - mController.getSummary(), - mContext.getString( - R.string.double_tap_power_summary, - mContext.getText(R.string.gesture_setting_on), - mContext.getText( - R.string.double_tap_power_camera_action_summary)))) + TextUtils.equals( + mController.getSummary(), + mContext.getString( + R.string.double_tap_power_summary, + mContext.getText(R.string.gesture_setting_on), + mContext.getText( + R.string.double_tap_power_camera_action_summary)))) .isTrue(); } @@ -267,13 +336,13 @@ public class DoubleTapPowerPreferenceControllerTest { DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); assertThat( - TextUtils.equals( - mController.getSummary(), - mContext.getString( - R.string.double_tap_power_summary, - mContext.getText(R.string.gesture_setting_on), - mContext.getText( - R.string.double_tap_power_wallet_action_summary)))) + TextUtils.equals( + mController.getSummary(), + mContext.getString( + R.string.double_tap_power_summary, + mContext.getText(R.string.gesture_setting_on), + mContext.getText( + R.string.double_tap_power_wallet_action_summary)))) .isTrue(); } } diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java index 7d4f52e67a2..40c13806fd6 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java @@ -16,6 +16,9 @@ package com.android.settings.gestures; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; + import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.DisableFlags; @@ -25,6 +28,7 @@ import android.provider.SearchIndexableResource; import android.service.quickaccesswallet.Flags; import com.android.settings.R; +import com.android.settings.testutils.shadow.SettingsShadowResources; import org.junit.Before; import org.junit.Rule; @@ -32,13 +36,16 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.List; +@Config(shadows = SettingsShadowResources.class) @RunWith(RobolectricTestRunner.class) public class DoubleTapPowerSettingsTest { - @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private DoubleTapPowerSettings mSettings; @Before @@ -48,10 +55,29 @@ public class DoubleTapPowerSettingsTest { @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void getPreferenceScreenResId_flagEnabled_returnsFlagEnabledResId() { + public void + getPreferenceScreenResId_flagEnabled_configIsMultiTargetMode_returnsMultiTargetResId() { + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); + mSettings.onAttach(RuntimeEnvironment.getApplication()); + assertThat(mSettings.getPreferenceScreenResId()).isEqualTo(R.xml.double_tap_power_settings); } + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void + getPreferenceScreenResId_flagEnabled_configIsCameraMode_returnsCameraLaunchResId() { + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); + mSettings.onAttach(RuntimeEnvironment.getApplication()); + + assertThat(mSettings.getPreferenceScreenResId()).isEqualTo( + R.xml.double_tap_power_to_open_camera_settings); + } + @Test @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) public void getPreferenceScreenResId_flagDisabled_returnsFlagDisabledResId() { @@ -61,7 +87,12 @@ public class DoubleTapPowerSettingsTest { @Test @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void testSearchIndexProvider_flagEnabled_shouldIndexFlagEnabledResource() { + public void + testSearchIndexProvider_flagEnabled_configIsMultiTargetMode_indexMultiTargetResId() { + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); + final List indexRes = DoubleTapPowerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( RuntimeEnvironment.getApplication(), true /* enabled */); @@ -70,9 +101,26 @@ public class DoubleTapPowerSettingsTest { assertThat(indexRes.get(0).xmlResId).isEqualTo(R.xml.double_tap_power_settings); } + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void + testSearchIndexProvider_flagEnabled_configIsCameraLaunchMode_indexCameraLaunchResId() { + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_doubleTapPowerGestureMode, + DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); + + final List indexRes = + DoubleTapPowerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( + RuntimeEnvironment.getApplication(), true /* enabled */); + + assertThat(indexRes).isNotNull(); + assertThat(indexRes.get(0).xmlResId).isEqualTo( + R.xml.double_tap_power_to_open_camera_settings); + } + @Test @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) - public void testSearchIndexProvider_flagDisabled_shouldIndexFlagDisabledResource() { + public void testSearchIndexProvider_flagDisabled_indexFlagDisabledResource() { final List indexRes = DoubleTapPowerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( RuntimeEnvironment.getApplication(), true /* enabled */); diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java index 817f198a5b2..401a848ed0c 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java @@ -16,6 +16,8 @@ package com.android.settings.gestures; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_DISABLED_MODE; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.OFF; import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.ON; @@ -55,18 +57,22 @@ public class DoubleTapPowerSettingsUtilsTest { } @Test - public void isDoubleTapPowerButtonGestureAvailable_setAvailable_returnsTrue() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + public void isMultiTargetDoubleTapPowerButtonGestureAvailable_setAvailable_returnsTrue() { + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_MULTI_TARGET_MODE); - assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) + assertThat(DoubleTapPowerSettingsUtils.isMultiTargetDoubleTapPowerButtonGestureAvailable( + mContext)) .isTrue(); } @Test - public void isDoubleTapPowerButtonGestureAvailable_setUnavailable_returnsFalse() { - when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + public void isMultiTargetDoubleTapPowerButtonGestureAvailable_setUnavailable_returnsFalse() { + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMode)).thenReturn( + DOUBLE_TAP_POWER_DISABLED_MODE); - assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) + assertThat(DoubleTapPowerSettingsUtils.isMultiTargetDoubleTapPowerButtonGestureAvailable( + mContext)) .isFalse(); } @@ -103,10 +109,10 @@ public class DoubleTapPowerSettingsUtilsTest { DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); assertThat( - Settings.Secure.getInt( - mContext.getContentResolver(), - Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, - OFF)) + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + OFF)) .isEqualTo(ON); } @@ -115,10 +121,10 @@ public class DoubleTapPowerSettingsUtilsTest { DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); assertThat( - Settings.Secure.getInt( - mContext.getContentResolver(), - Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, - ON)) + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + ON)) .isEqualTo(OFF); } @@ -130,8 +136,8 @@ public class DoubleTapPowerSettingsUtilsTest { DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); assertThat( - DoubleTapPowerSettingsUtils - .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) .isTrue(); } @@ -144,32 +150,32 @@ public class DoubleTapPowerSettingsUtilsTest { DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); assertThat( - DoubleTapPowerSettingsUtils - .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) .isFalse(); } @Test public void isDoubleTapPowerButtonGestureForCameraLaunchEnabled_defaultSetToCamera_returnsTrue() { - when(mResources.getInteger(R.integer.config_defaultDoubleTapPowerGestureAction)) + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMultiTargetDefaultAction)) .thenReturn(DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); assertThat( - DoubleTapPowerSettingsUtils - .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) .isTrue(); } @Test public void isDoubleTapPowerButtonGestureForCameraLaunchEnabled_defaultNotCamera_returnsFalse() { - when(mResources.getInteger(R.integer.config_defaultDoubleTapPowerGestureAction)) + when(mResources.getInteger(R.integer.config_doubleTapPowerGestureMultiTargetDefaultAction)) .thenReturn(DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); assertThat( - DoubleTapPowerSettingsUtils - .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) .isFalse(); } @@ -180,10 +186,10 @@ public class DoubleTapPowerSettingsUtilsTest { assertThat(result).isTrue(); assertThat( - Settings.Secure.getInt( - mContext.getContentResolver(), - Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, - DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE)) + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, + DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE)) .isEqualTo(DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); } @@ -194,10 +200,10 @@ public class DoubleTapPowerSettingsUtilsTest { assertThat(result).isTrue(); assertThat( - Settings.Secure.getInt( - mContext.getContentResolver(), - Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, - DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE)) + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, + DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE)) .isEqualTo(DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); } } diff --git a/tests/robotests/src/com/android/settings/inputmethod/MouseScrollingAccelerationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/MouseScrollingAccelerationPreferenceControllerTest.java new file mode 100644 index 00000000000..08a7392bcb2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/inputmethod/MouseScrollingAccelerationPreferenceControllerTest.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 MouseScrollingAccelerationPreferenceController} */ +@RunWith(RobolectricTestRunner.class) +@Config(shadows = { + com.android.settings.testutils.shadow.ShadowSystemSettings.class, +}) +public class MouseScrollingAccelerationPreferenceControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private static final String PREFERENCE_KEY = "mouse_scrolling_acceleration"; + private static final String SETTING_KEY = Settings.System.MOUSE_SCROLLING_ACCELERATION; + + private Context mContext; + private MouseScrollingAccelerationPreferenceController mController; + + @Before + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); + mController = new MouseScrollingAccelerationPreferenceController( + mContext, PREFERENCE_KEY); + } + + @Test + @EnableFlags(Flags.FLAG_MOUSE_SCROLLING_ACCELERATION) + public void getAvailabilityStatus_expected() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + @DisableFlags(Flags.FLAG_MOUSE_SCROLLING_ACCELERATION) + public void getAvailabilityStatus_flagIsDisabled_notSupport() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + @EnableFlags(Flags.FLAG_MOUSE_SCROLLING_ACCELERATION) + public void setChecked_false_shouldReturnTrue() { + mController.setChecked(false); + + boolean isEnabled = InputSettings.isMouseScrollingAccelerationEnabled(mContext); + assertThat(isEnabled).isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_MOUSE_SCROLLING_ACCELERATION) + public void setChecked_false_shouldReturnFalse() { + mController.setChecked(true); + + boolean isEnabled = InputSettings.isMouseScrollingAccelerationEnabled(mContext); + assertThat(isEnabled).isFalse(); + } + + @Test + @EnableFlags(Flags.FLAG_MOUSE_SCROLLING_ACCELERATION) + public void isChecked_providerPutInt1_returnFalse() { + Settings.System.putIntForUser( + mContext.getContentResolver(), + SETTING_KEY, + 1, + UserHandle.USER_CURRENT); + + boolean result = mController.isChecked(); + + assertThat(result).isFalse(); + } + + @Test + @EnableFlags(Flags.FLAG_MOUSE_SCROLLING_ACCELERATION) + public void isChecked_providerPutInt0_returnTrue() { + Settings.System.putIntForUser( + mContext.getContentResolver(), + SETTING_KEY, + 0, + UserHandle.USER_CURRENT); + + boolean result = mController.isChecked(); + + assertThat(result).isTrue(); + } +} diff --git a/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt b/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt index be839dd416f..9323a4a7759 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt @@ -56,13 +56,10 @@ class AppDataUsageSummaryControllerTest { composeTestRule.onNode(hasTextExactly("Total", "6.75 kB")).assertIsDisplayed() composeTestRule.onNode(hasTextExactly("Foreground", "5.54 kB")).assertIsDisplayed() composeTestRule.onNode(hasTextExactly("Background", "1.21 kB")).assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("6.75 kB").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("5.54 kB").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("1.21 kB").assertIsDisplayed() } @Test - fun summary_zero() { + fun summary_smallByte() { val appUsage = NetworkUsageDetailsData( range = Range(1L, 2L), totalUsage = 3, @@ -75,12 +72,9 @@ class AppDataUsageSummaryControllerTest { controller.Content() } - composeTestRule.onNode(hasTextExactly("Total", "3 B")).assertIsDisplayed() - composeTestRule.onNode(hasTextExactly("Foreground", "1 B")).assertIsDisplayed() - composeTestRule.onNode(hasTextExactly("Background", "2 B")).assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("3 byte").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("1 byte").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("2 byte").assertIsDisplayed() + composeTestRule.onNode(hasTextExactly("Total", "3 byte")).assertIsDisplayed() + composeTestRule.onNode(hasTextExactly("Foreground", "1 byte")).assertIsDisplayed() + composeTestRule.onNode(hasTextExactly("Background", "2 byte")).assertIsDisplayed() } private companion object { diff --git a/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt index 35a1a235bbe..afc196d8a6e 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt @@ -182,8 +182,8 @@ class DataUsageSummaryPreferenceControllerTest { val limitInfo = argumentCaptor { verify(preference).setLimitInfo(capture()) }.firstValue.toString() - assertThat(limitInfo).isEqualTo("1 B data warning") - verify(preference).setLabels("0 B", "1 B") + assertThat(limitInfo).isEqualTo("1 byte data warning") + verify(preference).setLabels("0 byte", "1 byte") } @Test @@ -200,8 +200,8 @@ class DataUsageSummaryPreferenceControllerTest { val limitInfo = argumentCaptor { verify(preference).setLimitInfo(capture()) }.firstValue.toString() - assertThat(limitInfo).isEqualTo("1 B data limit") - verify(preference).setLabels("0 B", "1 B") + assertThat(limitInfo).isEqualTo("1 byte data limit") + verify(preference).setLabels("0 byte", "1 byte") } @Test @@ -219,7 +219,7 @@ class DataUsageSummaryPreferenceControllerTest { verify(preference).setLimitInfo(capture()) }.firstValue.toString() assertThat(limitInfo).isEqualTo("512 MB data warning / 1.00 GB data limit") - verify(preference).setLabels("0 B", "1.00 GB") + verify(preference).setLabels("0 byte", "1.00 GB") } @Test @@ -256,7 +256,7 @@ class DataUsageSummaryPreferenceControllerTest { POSITIVE_DATA_PLAN_INFO.dataPlanSize, ) verify(preference).setChartEnabled(true) - verify(preference).setLabels("0 B", "9 B") + verify(preference).setLabels("0 byte", "9 byte") val progress = argumentCaptor { verify(preference).setProgress(capture()) }.firstValue diff --git a/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt b/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt index 071234dcd65..97a6c0f7fd2 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt @@ -21,7 +21,6 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.datausage.lib.DataUsageFormatter.Companion.getBytesDisplayUnit import com.google.common.truth.Truth.assertThat - import org.junit.Test import org.junit.runner.RunWith @@ -33,26 +32,23 @@ class DataUsageFormatterTest { @Test fun formatDataUsage_0() { - val (displayText, contentDescription) = dataUsageFormatter.formatDataUsage(0) + val displayText = dataUsageFormatter.formatDataUsage(0) - assertThat(displayText).isEqualTo("0 B") - assertThat(contentDescription).isEqualTo("0 byte") + assertThat(displayText).isEqualTo("0 byte") } @Test fun formatDataUsage_1000() { - val (displayText, contentDescription) = dataUsageFormatter.formatDataUsage(1000) + val displayText = dataUsageFormatter.formatDataUsage(1000) assertThat(displayText).isEqualTo("0.98 kB") - assertThat(contentDescription).isEqualTo("0.98 kB") } @Test fun formatDataUsage_2000000() { - val (displayText, contentDescription) = dataUsageFormatter.formatDataUsage(2000000) + val displayText = dataUsageFormatter.formatDataUsage(2000000) assertThat(displayText).isEqualTo("1.91 MB") - assertThat(contentDescription).isEqualTo("1.91 MB") } @Test diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt index f4974e9cd8e..f16c9fae017 100644 --- a/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt @@ -143,7 +143,7 @@ class DataUsagePreferenceControllerTest { controller.onViewCreated(TestLifecycleOwner()) waitUntil { preference.isEnabled } - waitUntil { preference.summary?.contains("0 B used") == true } + waitUntil { preference.summary?.contains("0 byte used") == true } } @Test @@ -159,7 +159,7 @@ class DataUsagePreferenceControllerTest { controller.onViewCreated(TestLifecycleOwner()) waitUntil { !preference.isEnabled } - waitUntil { preference.summary?.contains("0 B used") == true } + waitUntil { preference.summary?.contains("0 byte used") == true } } @Test diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt index f70f5d5ad63..d493b66737d 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt @@ -134,7 +134,7 @@ class AppDataUsagePreferenceTest { setContent() - composeTestRule.waitUntilExists(hasText("123 B used since Oct 25, 2022")) + composeTestRule.waitUntilExists(hasText("123 byte used since Oct 25, 2022")) } @Test diff --git a/tests/unit/src/com/android/settings/development/BackAnimationPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/BackAnimationPreferenceControllerTest.java deleted file mode 100644 index 1d93e88b64a..00000000000 --- a/tests/unit/src/com/android/settings/development/BackAnimationPreferenceControllerTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2022 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.development; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.app.Instrumentation; -import android.content.ContentResolver; -import android.content.Context; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.UserHandle; -import android.platform.test.annotations.RequiresFlagsDisabled; -import android.platform.test.annotations.RequiresFlagsEnabled; -import android.platform.test.flag.junit.CheckFlagsRule; -import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.provider.Settings; - -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; -import androidx.preference.SwitchPreference; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.window.flags.Flags; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -@RunWith(AndroidJUnit4.class) -public class BackAnimationPreferenceControllerTest { - - private static final int SETTING_VALUE_OFF = 0; - private static final int SETTING_VALUE_ON = 1; - - private SwitchPreference mPreference; - - private Context mContext; - private BackAnimationPreferenceController mController; - private Looper mLooper; - - @Rule - public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - mContext = instrumentation.getTargetContext(); - mController = new BackAnimationPreferenceController(mContext); - mPreference = new SwitchPreference(mContext); - if (Looper.myLooper() == null) { - Looper.prepare(); - } - mLooper = Looper.myLooper(); - - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, -1); - - final PreferenceManager preferenceManager = new PreferenceManager(mContext); - final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext); - mPreference.setKey(mController.getPreferenceKey()); - screen.addPreference(mPreference); - mController.displayPreference(screen); - } - - @Test - @RequiresFlagsEnabled(Flags.FLAG_PREDICTIVE_BACK_SYSTEM_ANIMS) - public void controllerNotAvailable_whenAconfigFlagEnabled() { - assertFalse(mController.isAvailable()); - } - - @Test - @RequiresFlagsDisabled(Flags.FLAG_PREDICTIVE_BACK_SYSTEM_ANIMS) - public void controllerAvailable_whenAconfigFlagDisabled() { - assertTrue(mController.isAvailable()); - } - - @Test - public void onPreferenceChange_switchEnabled_shouldEnableBackAnimations() { - mController.onPreferenceChange(mPreference, true /* new value */); - - final int mode = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, -1 /* default */); - assertThat(mode).isEqualTo(SETTING_VALUE_ON); - } - - @Test - public void onPreferenceChange_switchDisabled_shouldDisableBackAnimations() { - mController.onPreferenceChange(mPreference, false /* new value */); - - final int mode = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, -1 /* default */); - assertThat(mode).isEqualTo(SETTING_VALUE_OFF); - } - - @Test - public void updateState_settingEnabled_preferenceShouldBeChecked() { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_ON); - mController.updateState(mPreference); - assertTrue(mPreference.isChecked()); - } - - @Test - public void updateState_settingDisabled_preferenceShouldNotBeChecked() { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_OFF); - - mController.updateState(mPreference); - assertFalse(mPreference.isChecked()); - } - - @Test - public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() - throws InterruptedException { - ContentResolver contentResolver = mContext.getContentResolver(); - int mode = doAndWaitForSettingChange(() -> mController.onDeveloperOptionsSwitchDisabled(), - contentResolver); - assertThat(mode).isEqualTo(SETTING_VALUE_OFF); - assertFalse(mPreference.isEnabled()); - assertFalse(mPreference.isChecked()); - } - - private int doAndWaitForSettingChange(Runnable runnable, ContentResolver contentResolver) { - CountDownLatch countDownLatch = new CountDownLatch(1); - ContentObserver settingsObserver = - new ContentObserver(new Handler(mLooper)) { - @Override - public void onChange(boolean selfChange, Uri uri) { - countDownLatch.countDown(); - } - }; - contentResolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.ENABLE_BACK_ANIMATION), - false, settingsObserver, UserHandle.USER_SYSTEM - ); - runnable.run(); - try { - countDownLatch.await(500, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - Assert.fail(e.getMessage()); - } - return Settings.Global.getInt(contentResolver, - Settings.Global.ENABLE_BACK_ANIMATION, -1 /* default */); - } -}