diff --git a/res/drawable-v35/expressive_battery_hints_chip_bg.xml b/res/drawable-v35/expressive_battery_hints_chip_bg.xml new file mode 100644 index 00000000000..86e9f6a699c --- /dev/null +++ b/res/drawable-v35/expressive_battery_hints_chip_bg.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/res/drawable-v35/expressive_battery_hints_chip_bg_ripple.xml b/res/drawable-v35/expressive_battery_hints_chip_bg_ripple.xml new file mode 100644 index 00000000000..542a40c6ffb --- /dev/null +++ b/res/drawable-v35/expressive_battery_hints_chip_bg_ripple.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_settings_globe.xml b/res/drawable/ic_settings_globe.xml deleted file mode 100644 index 9834df6adba..00000000000 --- a/res/drawable/ic_settings_globe.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - \ No newline at end of file diff --git a/res/drawable/ic_settings_language_32dp.xml b/res/drawable/ic_settings_language_32dp.xml new file mode 100644 index 00000000000..b603d55598f --- /dev/null +++ b/res/drawable/ic_settings_language_32dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/layout-v35/expressive_warning_frame_preference.xml b/res/layout-v35/expressive_warning_frame_preference.xml new file mode 100644 index 00000000000..ba110443146 --- /dev/null +++ b/res/layout-v35/expressive_warning_frame_preference.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/locale_order_list.xml b/res/layout/locale_order_list.xml index da1eb62d996..36bb06d060b 100644 --- a/res/layout/locale_order_list.xml +++ b/res/layout/locale_order_list.xml @@ -44,7 +44,8 @@ android:textAlignment="textStart" android:text="@string/add_a_language" style="@style/Base.Widget.AppCompat.Button.Borderless" - android:textAppearance="?android:attr/textAppearanceListItem"/> + android:textAppearance="?android:attr/textAppearanceListItem" + android:visibility="gone"/> diff --git a/res/layout/power_anomaly_hints.xml b/res/layout/power_anomaly_hints.xml index 7ee419e4dcb..9498523d670 100644 --- a/res/layout/power_anomaly_hints.xml +++ b/res/layout/power_anomaly_hints.xml @@ -17,13 +17,12 @@ + android:id="@+id/warning_chip" + android:padding="8dp"> - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout/preference_volume_slider.xml b/res/layout/preference_volume_slider.xml index 50095f4f188..1d9a8484920 100644 --- a/res/layout/preference_volume_slider.xml +++ b/res/layout/preference_volume_slider.xml @@ -66,6 +66,8 @@ android:layout_gravity="center_vertical" android:paddingStart="0dp" android:paddingEnd="12dp" + android:progressBackgroundTint="@color/settingslib_materialColorOutline" + android:progressTint="@color/settingslib_materialColorPrimaryFixed" android:layout_width="match_parent" android:layout_height="48dp"/> diff --git a/res/layout/private_dns_mode_dialog.xml b/res/layout/private_dns_mode_dialog.xml index 96ebd2c3955..bee949a906e 100644 --- a/res/layout/private_dns_mode_dialog.xml +++ b/res/layout/private_dns_mode_dialog.xml @@ -16,8 +16,10 @@ + android:layout_height="wrap_content" + android:theme="@style/Theme.AppCompat.DayNight"> - + android:hint="@string/private_dns_title" + android:theme="@style/Theme.Settings" + app:endIconMode="clear_text" + app:errorEnabled="true"> + + + - - - + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 0d0b9e6e6e7..0e88e265867 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -555,4 +555,10 @@ 5dp 2dp 10dp + + + 10dp + 16dp + 24dp + 32dp diff --git a/res/values/strings.xml b/res/values/strings.xml index c1b10146131..6f328a341db 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -305,8 +305,6 @@ Media devices - - Guest devices Call devices @@ -502,7 +500,7 @@ Your device settings and regional preferences will change. - + Change @@ -530,10 +528,11 @@ More language settings - Change region to %s ? + Change region to %1$s ? - Your device will keep %s as a system language - The digits used will be dependent on the numbering system + Your device will keep %1$s as a system language + + Most apps will use your regional preferences @@ -2937,6 +2936,12 @@ Emergency address Used as your location when you make an emergency call over Wi\u2011Fi + + Hostname + + The field is required + + The hostname you typed isn\u2019t valid Learn more about Private DNS features @@ -13968,13 +13973,15 @@ Share with %1$s Close - + Connect another pair of compatible headphones, or share your stream\'s name and password with the other person - + Let others scan this code and listen to your audio\n\nStream name: %1$s\nPassword: %2$s - + + Let others scan this code and listen to your audio\n\nStream name: %1$s + or pair another set of compatible headphones - + Pair another set of compatible headphones, or share your audio stream QR code with the other person Sharing audio diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml index e8c169ce92c..06fb5a7941d 100644 --- a/res/xml/connected_devices.xml +++ b/res/xml/connected_devices.xml @@ -26,17 +26,6 @@ settings:allowDividerBelow="true" settings:controller="com.android.settings.slices.SlicePreferenceController" /> - - - - - + + + + + !anyTemporaryBondDevice(entry.getValue())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } mDeviceItemsInSharingSession = AudioSharingUtils.buildOrderedConnectedLeadAudioSharingDeviceItem( mBtManager, mGroupedConnectedDevices, /* filterByInSharing= */ true); } - private boolean anyTemporaryBondDevice(List connectedDevices) { - return connectedDevices.stream().anyMatch(BluetoothUtils::isTemporaryBondDevice); - } - @Nullable private Pair getActiveItemWithIndex() { List deviceItems = new ArrayList<>(mDeviceItemsInSharingSession); diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java index cf71d5f4685..14a559014cf 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java @@ -186,14 +186,17 @@ public class AudioSharingDialogFragment extends InstrumentedDialogFragment { Drawable qrCodeDrawable = metadata == null ? null : getQrCodeDrawable(metadata, getContext()).orElse(null); if (qrCodeDrawable != null) { + String broadcastName = + metadata.getBroadcastName() == null ? "" : metadata.getBroadcastName(); + boolean hasPassword = metadata.getBroadcastCode() != null + && metadata.getBroadcastCode().length > 0; + String message = hasPassword ? getString( + R.string.audio_sharing_dialog_qr_code_content, broadcastName, + new String(metadata.getBroadcastCode(), StandardCharsets.UTF_8)) : + getString(R.string.audio_sharing_dialog_qr_code_content_no_password, + broadcastName); builder.setCustomImage(qrCodeDrawable) - .setCustomMessage( - getString( - R.string.audio_sharing_dialog_qr_code_content, - metadata.getBroadcastName(), - new String( - metadata.getBroadcastCode(), - StandardCharsets.UTF_8))) + .setCustomMessage(message) .setCustomMessage2(R.string.audio_sharing_dialog_pair_new_device_content) .setCustomNegativeButton(R.string.audio_streams_dialog_close, v -> onCancelClick()); diff --git a/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupController.java deleted file mode 100644 index ff3aa2c12e0..00000000000 --- a/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupController.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 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.connecteddevice.audiosharing; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.Preference; -import androidx.preference.PreferenceGroup; -import androidx.preference.PreferenceScreen; - -import com.android.settings.bluetooth.BluetoothDeviceUpdater; -import com.android.settings.bluetooth.Utils; -import com.android.settings.connecteddevice.DevicePreferenceCallback; -import com.android.settings.core.BasePreferenceController; -import com.android.settings.dashboard.DashboardFragment; -import com.android.settingslib.bluetooth.BluetoothCallback; -import com.android.settingslib.bluetooth.BluetoothEventManager; -import com.android.settingslib.bluetooth.BluetoothUtils; -import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.flags.Flags; -import com.android.settingslib.utils.ThreadUtils; - -/** - * Controller to maintain the {@link androidx.preference.PreferenceGroup} for all connected - * temporary bond devices. It uses {@link DevicePreferenceCallback} to add/remove - * {@link Preference} - */ -public class TemporaryBondDeviceGroupController extends BasePreferenceController implements - DefaultLifecycleObserver, DevicePreferenceCallback, BluetoothCallback { - private static final String TAG = "TemporaryBondDeviceGroupController"; - private static final String KEY = "temp_bond_device_list"; - - @Nullable - private final BluetoothEventManager mEventManager; - @Nullable - private PreferenceGroup mPreferenceGroup; - @Nullable - private BluetoothDeviceUpdater mBluetoothDeviceUpdater; - - - public TemporaryBondDeviceGroupController(@NonNull Context context) { - super(context, KEY); - LocalBluetoothManager btManager = Utils.getLocalBtManager(mContext); - mEventManager = btManager == null ? null : btManager.getEventManager(); - } - - @Override - public void onStart(@NonNull LifecycleOwner owner) { - if (!isAvailable()) { - Log.d(TAG, "Skip onStart(), feature is not supported."); - return; - } - if (mEventManager == null) { - Log.d(TAG, "onStart() Bluetooth is not supported on this device"); - return; - } - var unused = ThreadUtils.postOnBackgroundThread(() -> { - mEventManager.registerCallback(this); - if (mBluetoothDeviceUpdater != null) { - mBluetoothDeviceUpdater.registerCallback(); - mBluetoothDeviceUpdater.refreshPreference(); - } - }); - } - - @Override - public void onStop(@NonNull LifecycleOwner owner) { - var unused = ThreadUtils.postOnBackgroundThread(() -> { - if (mBluetoothDeviceUpdater != null) { - mBluetoothDeviceUpdater.unregisterCallback(); - } - if (mEventManager != null) { - mEventManager.unregisterCallback(this); - return; - } - Log.d(TAG, "onStop() Bluetooth is not supported on this device"); - }); - } - - @Override - public void displayPreference(@NonNull PreferenceScreen screen) { - super.displayPreference(screen); - mPreferenceGroup = screen.findPreference(KEY); - if (mPreferenceGroup != null) { - mPreferenceGroup.setVisible(false); - } - - if (isAvailable() && mBluetoothDeviceUpdater != null) { - mBluetoothDeviceUpdater.setPrefContext(screen.getContext()); - mBluetoothDeviceUpdater.forceUpdate(); - } - } - - @Override - public void onDeviceAdded(@NonNull Preference preference) { - if (mPreferenceGroup != null) { - mPreferenceGroup.addPreference(preference); - Log.d(TAG, "Temporary bond device added"); - if (mPreferenceGroup.getPreferenceCount() == 1) { - mPreferenceGroup.setVisible(true); - } - } - } - - @Override - public void onDeviceRemoved(@NonNull Preference preference) { - if (mPreferenceGroup != null) { - mPreferenceGroup.removePreference(preference); - Log.d(TAG, "Temporary bond device removed"); - if (mPreferenceGroup.getPreferenceCount() == 0) { - mPreferenceGroup.setVisible(false); - } - } - } - - @Override - public int getAvailabilityStatus() { - return (BluetoothUtils.isAudioSharingUIAvailable(mContext) - && mBluetoothDeviceUpdater != null && Flags.enableTemporaryBondDevicesUi()) - ? AVAILABLE_UNSEARCHABLE - : UNSUPPORTED_ON_DEVICE; - } - - @Override - public String getPreferenceKey() { - return KEY; - } - - /** - * Initialize the controller. - * - * @param fragment The fragment to provide the context and metrics category for {@link - * TemporaryBondDeviceGroupUpdater} and provide the host for dialogs. - */ - public void init(@NonNull DashboardFragment fragment) { - mBluetoothDeviceUpdater = new TemporaryBondDeviceGroupUpdater(fragment.getContext(), - TemporaryBondDeviceGroupController.this, - fragment.getMetricsCategory()); - } - - @VisibleForTesting - void setBluetoothDeviceUpdater(@Nullable BluetoothDeviceUpdater bluetoothDeviceUpdater) { - mBluetoothDeviceUpdater = bluetoothDeviceUpdater; - } - - @VisibleForTesting - void setPreferenceGroup(@Nullable PreferenceGroup preferenceGroup) { - mPreferenceGroup = preferenceGroup; - } -} diff --git a/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupUpdater.java deleted file mode 100644 index 59e37c51c08..00000000000 --- a/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupUpdater.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 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.connecteddevice.audiosharing; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.android.settings.bluetooth.BluetoothDeviceUpdater; -import com.android.settings.connecteddevice.DevicePreferenceCallback; -import com.android.settingslib.bluetooth.BluetoothUtils; -import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.settingslib.flags.Flags; - -/** Maintain and update connected temporary bond bluetooth devices */ -public class TemporaryBondDeviceGroupUpdater extends BluetoothDeviceUpdater { - private static final String TAG = "TemporaryBondDeviceGroupUpdater"; - private static final String PREF_KEY_PREFIX = "temp_bond_bt_"; - - public TemporaryBondDeviceGroupUpdater( - @NonNull Context context, - @NonNull DevicePreferenceCallback devicePreferenceCallback, - int metricsCategory) { - super(context, devicePreferenceCallback, metricsCategory); - } - - @Override - public boolean isFilterMatched(@NonNull CachedBluetoothDevice cachedDevice) { - // Only connected temporary bond device should be shown in this section when Audio - // sharing UI is available. - boolean isFilterMatched = Flags.enableTemporaryBondDevicesUi() - && BluetoothUtils.isTemporaryBondDevice(cachedDevice.getDevice()) - && isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice) - && BluetoothUtils.isAudioSharingUIAvailable(mContext); - Log.d( - TAG, - "isFilterMatched() device : " - + cachedDevice.getName() - + ", isFilterMatched : " - + isFilterMatched); - return isFilterMatched; - } - - @Override - protected String getPreferenceKeyPrefix() { - return PREF_KEY_PREFIX; - } - - @Override - protected String getLogTag() { - return TAG; - } - - @Override - protected void update(CachedBluetoothDevice cachedBluetoothDevice) { - super.update(cachedBluetoothDevice); - Log.d(TAG, "Map : " + mPreferenceMap); - } -} diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java index af03bab7579..5de96b33c80 100644 --- a/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragment.java @@ -59,6 +59,7 @@ import com.android.settingslib.widget.TwoTargetPreference; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.function.Consumer; /** * The Settings screen for External Displays configuration and connection management. @@ -85,8 +86,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen BUILTIN_DISPLAY_LIST(70, "builtin_display_list_preference", R.string.builtin_display_settings_category), - DISPLAYS_LIST(80, "displays_list_preference", null), - // If shown, footer should appear below everything. FOOTER(90, "footer_preference", null); @@ -333,15 +332,6 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen return args != null ? args.getInt(DISPLAY_ID_ARG, INVALID_DISPLAY) : INVALID_DISPLAY; } - @NonNull - private PreferenceCategory getDisplaysListPreference(@NonNull Context context) { - if (mDisplaysPreference == null) { - mDisplaysPreference = new PreferenceCategory(context); - PrefBasics.DISPLAYS_LIST.apply(mDisplaysPreference); - } - return mDisplaysPreference; - } - @NonNull private PreferenceCategory getBuiltinDisplayListPreference(@NonNull Context context) { if (mBuiltinDisplayPreference == null) { @@ -455,6 +445,26 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen EXTERNAL_DISPLAY_NOT_FOUND_FOOTER_RESOURCE)); } + private static PreferenceCategory getCategoryForDisplay(@NonNull Display display, + @NonNull PrefRefresh screen, @NonNull Context context) { + // The rest of the settings are in a category with the display name as the title. + String categoryKey = "expanded_display_items_" + display.getDisplayId(); + var category = (PreferenceCategory) screen.findUnusedPreference(categoryKey); + + if (category != null) { + screen.addPreference(category); + } else { + category = new PreferenceCategory(context); + screen.addPreference(category); + category.setPersistent(false); + category.setKey(categoryKey); + category.setTitle(display.getName()); + category.setOrder(PrefBasics.BUILTIN_DISPLAY_LIST.order + 1); + } + + return category; + } + private void showDisplaySettings(@NonNull Display display, @NonNull PrefRefresh screen, @NonNull Context context) { final var isEnabled = mInjector != null && mInjector.isDisplayEnabled(display); @@ -469,8 +479,18 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen if (!isTopologyPaneEnabled(mInjector)) { screen.addPreference(updateIllustrationImage(context, displayRotation)); } - screen.addPreference(updateResolutionPreference(context, display)); - screen.addPreference(updateRotationPreference(context, display, displayRotation)); + + Consumer adder; + if (isTopologyPaneEnabled(mInjector)) { + adder = getCategoryForDisplay(display, screen, context)::addPreference; + // The category may have already been populated if it was retrieved from the PrefRefresh + // backup, but we still need to update resolution and rotation items. + } else { + adder = screen::addPreference; + } + + adder.accept(updateResolutionPreference(context, display)); + adder.accept(updateRotationPreference(context, display, displayRotation)); if (isResolutionSettingEnabled(mInjector)) { // Do not show the footer about changing resolution affecting apps. This is not in the // UX design for v2, and there is no good place to put it, since (a) if it is on the @@ -483,12 +503,12 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen // TODO(b/352648432): probably remove footer once the pane and rest of v2 UI is in // place. if (!isTopologyPaneEnabled(mInjector)) { - screen.addPreference(updateFooterPreference(context, + adder.accept(updateFooterPreference(context, EXTERNAL_DISPLAY_CHANGE_RESOLUTION_FOOTER_RESOURCE)); } } if (isDisplaySizeSettingEnabled(mInjector)) { - screen.addPreference(updateSizePreference(context)); + adder.accept(updateSizePreference(context)); } } @@ -508,23 +528,28 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen private void showDisplaysList(@NonNull List displaysToShow, @NonNull PrefRefresh screen, @NonNull Context context) { maybeAddV2Components(context, screen); - var displayGroupPref = getDisplaysListPreference(context); - if (!displaysToShow.isEmpty()) { - screen.addPreference(displayGroupPref); - } - try (var groupCleanable = new PrefRefresh(displayGroupPref)) { - for (var display : displaysToShow) { - var pref = getDisplayPreference(context, display, groupCleanable); - pref.setSummary(display.getMode().getPhysicalWidth() + " x " - + display.getMode().getPhysicalHeight()); - } + int order = PrefBasics.BUILTIN_DISPLAY_LIST.order; + for (var display : displaysToShow) { + var pref = getDisplayPreference(context, display, screen, ++order); + pref.setSummary(display.getMode().getPhysicalWidth() + " x " + + display.getMode().getPhysicalHeight()); } } + @VisibleForTesting + static String displayListDisplayCategoryKey(int displayId) { + return "display_list_display_category_" + displayId; + } + + @VisibleForTesting + static String resolutionRotationPreferenceKey(int displayId) { + return "display_id_" + displayId; + } + private Preference getDisplayPreference(@NonNull Context context, - @NonNull Display display, @NonNull PrefRefresh groupCleanable) { - var itemKey = "display_id_" + display.getDisplayId(); - var categoryKey = itemKey + "_category"; + @NonNull Display display, @NonNull PrefRefresh groupCleanable, int categoryOrder) { + var itemKey = resolutionRotationPreferenceKey(display.getDisplayId()); + var categoryKey = displayListDisplayCategoryKey(display.getDisplayId()); var category = (PreferenceCategory) groupCleanable.findUnusedPreference(categoryKey); if (category != null) { @@ -534,6 +559,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen category = new PreferenceCategory(context); category.setPersistent(false); category.setKey(categoryKey); + category.setOrder(categoryOrder); // Must add the category to the hierarchy before adding its descendants. Otherwise // the category will not have a preference manager, which causes an exception when a // child is added to it. diff --git a/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java index 1890fbd9818..dfa808f644d 100644 --- a/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java +++ b/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceController.java @@ -16,6 +16,7 @@ package com.android.settings.development; +import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController.A2DP_OFFLOAD_SUPPORTED_PROPERTY; import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController.A2DP_OFFLOAD_DISABLED_PROPERTY; import android.bluetooth.BluetoothAdapter; @@ -105,13 +106,14 @@ public class BluetoothLeAudioHwOffloadPreferenceController (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); final boolean leAudioOffloadSupported = SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY, false); - final boolean a2dpOffloadDisabled = - SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); - if (leAudioEnabled && leAudioOffloadSupported && !a2dpOffloadDisabled) { - ((TwoStatePreference) mPreference).setChecked(true); - SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, "true"); - } else { + final boolean a2dpOffloadSupported = + SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false); + + if(!leAudioEnabled || !leAudioOffloadSupported || !a2dpOffloadSupported) { mPreference.setEnabled(false); + } else { + ((TwoStatePreference) mPreference).setChecked(false); + SystemProperties.set(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, "false"); } } diff --git a/src/com/android/settings/development/DesktopExperiencePreferenceController.java b/src/com/android/settings/development/DesktopExperiencePreferenceController.java index f6173a974e7..28e92fcdac5 100644 --- a/src/com/android/settings/development/DesktopExperiencePreferenceController.java +++ b/src/com/android/settings/development/DesktopExperiencePreferenceController.java @@ -98,7 +98,7 @@ public class DesktopExperiencePreferenceController extends DeveloperOptionsPrefe @Override public CharSequence getSummary() { - if (DesktopModeStatus.isInternalDisplayEligibleToHostDesktops(mContext) + if (DesktopModeStatus.isDeviceEligibleForDesktopMode(mContext) && !DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODE.isTrue()) { return mContext.getString( R.string.enable_desktop_experience_features_summary_with_desktop); diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java index 421963eb31c..b49d62d444f 100644 --- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java +++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java @@ -17,6 +17,7 @@ package com.android.settings.deviceinfo; import android.content.Context; +import android.os.UserManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -30,6 +31,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settings.network.SubscriptionUtil; +import com.android.settingslib.Utils; import java.util.ArrayList; import java.util.List; @@ -51,8 +53,13 @@ public class PhoneNumberPreferenceController extends BasePreferenceController { @Override public int getAvailabilityStatus() { - return SubscriptionUtil.isSimHardwareVisible(mContext) ? - AVAILABLE : UNSUPPORTED_ON_DEVICE; + if (!SubscriptionUtil.isSimHardwareVisible(mContext) || Utils.isWifiOnly(mContext)) { + return UNSUPPORTED_ON_DEVICE; + } + if (!mContext.getSystemService(UserManager.class).isAdminUser()) { + return DISABLED_FOR_USER; + } + return AVAILABLE; } @Override diff --git a/src/com/android/settings/fuelgauge/PowerUsageTimeController.java b/src/com/android/settings/fuelgauge/PowerUsageTimeController.java index 0dfdd5d3238..e01a95c99a6 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageTimeController.java +++ b/src/com/android/settings/fuelgauge/PowerUsageTimeController.java @@ -93,10 +93,10 @@ public class PowerUsageTimeController extends BasePreferenceController { || (summaryTimeMs == 0 && !TextUtils.equals(anomalyHintKey, preference.getKey()))) { return false; } - preference.setTimeTitle(mContext.getString(titleResId)); - preference.setTimeSummary(getPowerUsageTimeInfo(summaryTimeMs)); + preference.setTitle(mContext.getString(titleResId)); + preference.setSummary(getPowerUsageTimeInfo(summaryTimeMs)); if (TextUtils.equals(anomalyHintKey, preference.getKey())) { - preference.setAnomalyHint(anomalyHintText); + preference.setHint(anomalyHintText); } preference.setVisible(true); return true; diff --git a/src/com/android/settings/fuelgauge/PowerUsageTimePreference.java b/src/com/android/settings/fuelgauge/PowerUsageTimePreference.java index 16c7770181b..d2f39ff5f19 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageTimePreference.java +++ b/src/com/android/settings/fuelgauge/PowerUsageTimePreference.java @@ -17,74 +17,17 @@ package com.android.settings.fuelgauge; import android.content.Context; -import android.text.TextUtils; import android.util.AttributeSet; -import android.view.View; -import android.widget.TextView; -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceViewHolder; - -import com.android.settings.R; +import com.android.settingslib.widget.GroupSectionDividerMixin; /** Custom preference for displaying the app power usage time. */ -public class PowerUsageTimePreference extends Preference { +public class PowerUsageTimePreference extends WarningFramePreference implements + GroupSectionDividerMixin { private static final String TAG = "PowerUsageTimePreference"; - @VisibleForTesting CharSequence mTimeTitle; - @VisibleForTesting CharSequence mTimeSummary; - @VisibleForTesting CharSequence mAnomalyHintText; - public PowerUsageTimePreference(Context context, AttributeSet attrs) { super(context, attrs); - setLayoutResource(R.layout.power_usage_time); - } - - void setTimeTitle(CharSequence timeTitle) { - if (!TextUtils.equals(mTimeTitle, timeTitle)) { - mTimeTitle = timeTitle; - notifyChanged(); - } - } - - void setTimeSummary(CharSequence timeSummary) { - if (!TextUtils.equals(mTimeSummary, timeSummary)) { - mTimeSummary = timeSummary; - notifyChanged(); - } - } - - void setAnomalyHint(CharSequence anomalyHintText) { - if (!TextUtils.equals(mAnomalyHintText, anomalyHintText)) { - mAnomalyHintText = anomalyHintText; - notifyChanged(); - } - } - - private void showAnomalyHint(PreferenceViewHolder view) { - if (TextUtils.isEmpty(mAnomalyHintText)) { - return; - } - final View anomalyHintView = view.findViewById(R.id.anomaly_hints); - if (anomalyHintView == null) { - return; - } - final TextView warningInfo = anomalyHintView.findViewById(R.id.warning_info); - if (warningInfo == null) { - return; - } - warningInfo.setText(mAnomalyHintText); - anomalyHintView.setVisibility(View.VISIBLE); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - super.onBindViewHolder(view); - - ((TextView) view.findViewById(R.id.time_title)).setText(mTimeTitle); - ((TextView) view.findViewById(R.id.time_summary)).setText(mTimeSummary); - - showAnomalyHint(view); + setSelectable(false); } } diff --git a/src/com/android/settings/fuelgauge/WarningFramePreference.java b/src/com/android/settings/fuelgauge/WarningFramePreference.java new file mode 100644 index 00000000000..fef03a5158b --- /dev/null +++ b/src/com/android/settings/fuelgauge/WarningFramePreference.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 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.fuelgauge; + +import android.annotation.Nullable; +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.settings.R; +import com.android.settingslib.Utils; +import com.android.settingslib.widget.SettingsThemeHelper; + +/** + * Custom preference for displaying the {@link Preference} with an optional hint chip. + */ +public class WarningFramePreference extends Preference { + private final int mTitleColorNormal; + private final int mSummaryColorNormal; + private final int mWarningChipBackgroundResId; + private final boolean mIsExpressiveTheme; + + @Nullable private CharSequence mHintText; + + public WarningFramePreference(Context context, AttributeSet attrs) { + super(context, attrs); + mIsExpressiveTheme = SettingsThemeHelper.isExpressiveTheme(context); + int layoutResId = + mIsExpressiveTheme + ? R.layout.expressive_warning_frame_preference + : R.layout.warning_frame_preference; + setLayoutResource(layoutResId); + mWarningChipBackgroundResId = + mIsExpressiveTheme + ? R.drawable.expressive_battery_hints_chip_bg_ripple + : R.drawable.battery_hints_chip_bg_ripple; + mTitleColorNormal = + Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary); + mSummaryColorNormal = + Utils.getColorAttrDefaultColor(context, android.R.attr.textColorSecondary); + } + + /** Sets the text of hint to show. */ + public void setHint(@Nullable CharSequence hintText) { + if (!TextUtils.equals(mHintText, hintText)) { + mHintText = hintText; + notifyChanged(); + } + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + + if (mIsExpressiveTheme) { + final View preferenceFrame = view.findViewById(R.id.preference_frame); + preferenceFrame.setBackground(null); + preferenceFrame.setPadding(0, 0, 0, 0); + } + + final View warningChipFrame = view.findViewById(R.id.warning_chip_frame); + warningChipFrame + .findViewById(R.id.warning_padding_placeholder) + .setVisibility(getIcon() != null ? View.VISIBLE : View.GONE); + if (!TextUtils.isEmpty(mHintText)) { + ((TextView) warningChipFrame.findViewById(R.id.warning_info)).setText(mHintText); + warningChipFrame.setVisibility(View.VISIBLE); + warningChipFrame + .findViewById(R.id.warning_chip) + .setBackgroundResource(mWarningChipBackgroundResId); + } else { + warningChipFrame.setVisibility(View.GONE); + } + ((TextView) view.findViewById(android.R.id.title)).setTextColor(mTitleColorNormal); + ((TextView) view.findViewById(android.R.id.summary)).setTextColor(mSummaryColorNormal); + } +} + diff --git a/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java b/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java deleted file mode 100644 index 592d30833ed..00000000000 --- a/src/com/android/settings/fuelgauge/batteryusage/AnomalyAppItemPreference.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.fuelgauge.batteryusage; - -import android.annotation.Nullable; -import android.content.Context; -import android.text.TextUtils; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.preference.PreferenceViewHolder; - -import com.android.settings.R; - -class AnomalyAppItemPreference extends PowerGaugePreference { - - private static final String TAG = "AnomalyAppItemPreference"; - - private CharSequence mAnomalyHintText; - - AnomalyAppItemPreference(Context context) { - super(context, /* attrs */ null); - setLayoutResource(R.layout.anomaly_app_item_preference); - } - - void setAnomalyHint(@Nullable CharSequence anomalyHintText) { - if (!TextUtils.equals(mAnomalyHintText, anomalyHintText)) { - mAnomalyHintText = anomalyHintText; - notifyChanged(); - } - } - - @Override - public void onBindViewHolder(PreferenceViewHolder viewHolder) { - super.onBindViewHolder(viewHolder); - final LinearLayout warningChipView = - (LinearLayout) viewHolder.findViewById(R.id.warning_chip); - - if (!TextUtils.isEmpty(mAnomalyHintText)) { - ((TextView) warningChipView.findViewById(R.id.warning_info)).setText(mAnomalyHintText); - warningChipView.setVisibility(View.VISIBLE); - } else { - warningChipView.setVisibility(View.GONE); - } - } -} diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java index 6fd4eb5449f..280fa185e0c 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownController.java @@ -381,15 +381,15 @@ public class BatteryUsageBreakdownController extends BasePreferenceController continue; } final String prefKey = entry.getKey(); - AnomalyAppItemPreference preference = mRootPreferenceGroup.findPreference(prefKey); + PowerGaugePreference preference = mRootPreferenceGroup.findPreference(prefKey); if (preference != null) { isAdded = true; } else { - preference = (AnomalyAppItemPreference) mPreferenceCache.get(prefKey); + preference = (PowerGaugePreference) mPreferenceCache.get(prefKey); } // Creates new instance if cached preference is not found. if (preference == null) { - preference = new AnomalyAppItemPreference(mPrefContext); + preference = new PowerGaugePreference(mPrefContext); preference.setKey(prefKey); mPreferenceCache.put(prefKey, preference); } @@ -398,7 +398,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController preference.setOrder(++preferenceOrder); preference.setSingleLineTitle(true); // Updates App item preference style - preference.setAnomalyHint(isAnomalyBatteryDiffEntry(entry) ? mAnomalyHintString : null); + preference.setHint(isAnomalyBatteryDiffEntry(entry) ? mAnomalyHintString : null); // Sets the BatteryDiffEntry to preference for launching detailed page. preference.setBatteryDiffEntry(entry); preference.setSelectable(entry.validForRestriction()); diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreference.java index 1fc9abd4c5e..866b9ae6e05 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreference.java +++ b/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreference.java @@ -28,7 +28,7 @@ import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settings.Utils; -import com.android.settingslib.widget.AppPreference; +import com.android.settings.fuelgauge.WarningFramePreference; /** * Custom preference for displaying battery usage info as a bar and an icon on the left for the @@ -37,7 +37,7 @@ import com.android.settingslib.widget.AppPreference; *

The battery usage info could be usage percentage or usage time. The preference won't show any * icon if it is null. */ -public class PowerGaugePreference extends AppPreference { +public class PowerGaugePreference extends WarningFramePreference { // Please see go/battery-usage-app-list-alpha private static final float SELECTABLE_ALPHA = 1f; @@ -51,7 +51,6 @@ public class PowerGaugePreference extends AppPreference { private CharSequence mContentDescription; private CharSequence mProgress; private CharSequence mProgressContentDescription; - private boolean mShowAnomalyIcon; public PowerGaugePreference( Context context, Drawable icon, CharSequence contentDescription, BatteryEntry info) { @@ -79,7 +78,6 @@ public class PowerGaugePreference extends AppPreference { setWidgetLayoutResource(R.layout.preference_widget_summary); mInfo = info; mContentDescription = contentDescription; - mShowAnomalyIcon = false; mTitleColorNormal = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary); } @@ -108,17 +106,6 @@ public class PowerGaugePreference extends AppPreference { return mProgress.toString(); } - /** Sets whether to show anomaly icon */ - public void shouldShowAnomalyIcon(boolean showAnomalyIcon) { - mShowAnomalyIcon = showAnomalyIcon; - notifyChanged(); - } - - /** Gets whether to show anomaly icon */ - public boolean showAnomalyIcon() { - return mShowAnomalyIcon; - } - public void setBatteryDiffEntry(BatteryDiffEntry entry) { mBatteryDiffEntry = entry; } @@ -149,12 +136,6 @@ public class PowerGaugePreference extends AppPreference { if (!TextUtils.isEmpty(mProgressContentDescription)) { subtitle.setContentDescription(mProgressContentDescription); } - if (mShowAnomalyIcon) { - subtitle.setCompoundDrawablesRelativeWithIntrinsicBounds( - R.drawable.ic_warning_24dp, 0, 0, 0); - } else { - subtitle.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0); - } if (mContentDescription != null) { final TextView titleView = (TextView) view.findViewById(android.R.id.title); titleView.setContentDescription(mContentDescription); diff --git a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java index 314ccec8a80..795420cbee5 100644 --- a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java +++ b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java @@ -16,7 +16,6 @@ package com.android.settings.homepage.contextualcards.conditional; -import android.app.Flags; import android.app.NotificationManager; import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; @@ -87,12 +86,8 @@ public class DndConditionCardController implements ConditionalCardController { @Override public void onActionClick() { - if (Flags.modesApi()) { - mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG, - /* fromUser= */ true); - } else { - mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG); - } + mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG, + /* fromUser= */ true); } @Override diff --git a/src/com/android/settings/localepicker/LocaleDialogFragment.java b/src/com/android/settings/localepicker/LocaleDialogFragment.java index 91cbc87ee2e..a3a4b8fee72 100644 --- a/src/com/android/settings/localepicker/LocaleDialogFragment.java +++ b/src/com/android/settings/localepicker/LocaleDialogFragment.java @@ -29,19 +29,20 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.TextView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import androidx.appcompat.app.AlertDialog; import com.android.internal.app.LocaleStore; import com.android.settings.R; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.utils.CustomDialogHelper; /** * Create a dialog for system locale events. @@ -58,7 +59,6 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { static final String ARG_SHOW_DIALOG = "arg_show_dialog"; private boolean mShouldKeepDialog; - private AlertDialog mAlertDialog; private OnBackInvokedDispatcher mBackDispatcher; private OnBackInvokedCallback mBackCallback = () -> { @@ -106,45 +106,53 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { LocaleListEditor parentFragment = (LocaleListEditor) getParentFragment(); LocaleDialogController controller = getLocaleDialogController(getContext(), this, parentFragment); - LocaleDialogController.DialogContent dialogContent = controller.getDialogContent(); - ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(getContext()).inflate( - R.layout.locale_dialog, null); - setDialogTitle(viewGroup, dialogContent.mTitle); - setDialogMessage(viewGroup, dialogContent.mMessage); - - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()) - .setView(viewGroup); - if (!dialogContent.mPositiveButton.isEmpty()) { - builder.setPositiveButton(dialogContent.mPositiveButton, controller); - } - if (!dialogContent.mNegativeButton.isEmpty()) { - builder.setNegativeButton(dialogContent.mNegativeButton, controller); - } - mAlertDialog = builder.create(); - getOnBackInvokedDispatcher().registerOnBackInvokedCallback(PRIORITY_DEFAULT, mBackCallback); - mAlertDialog.setCanceledOnTouchOutside(false); - mAlertDialog.setOnDismissListener(dialogInterface -> { - mAlertDialog.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback( - mBackCallback); + Dialog dialog = createDialog(getContext(), controller); + dialog.setCanceledOnTouchOutside(false); + getOnBackInvokedDispatcher(dialog).registerOnBackInvokedCallback(PRIORITY_DEFAULT, + mBackCallback); + dialog.setOnDismissListener(dialogInterface -> { + getOnBackInvokedDispatcher(dialog).unregisterOnBackInvokedCallback( + mBackCallback); }); - return mAlertDialog; + return dialog; } - private static void setDialogTitle(View root, String content) { - TextView titleView = root.findViewById(R.id.dialog_title); - if (titleView == null) { - return; + private Dialog createDialog(Context context, LocaleDialogController controller) { + CustomDialogHelper dialogHelper = new CustomDialogHelper(context); + LocaleDialogController.DialogContent dialogContent = controller.getDialogContent(); + dialogHelper.setIcon(context.getDrawable(R.drawable.ic_settings_language_32dp)) + .setTitle(dialogContent.mTitle) + .setMessage(dialogContent.mMessage) + .setIconPadding(0, + context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_icon_padding), + 0, 0) + .setTitlePadding(0, + context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_title_padding), + 0, + context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_title_padding)) + .setMessagePadding(context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_message_padding_left_right), 0, + context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_message_padding_left_right), + context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_message_padding_bottom)) + .setPositiveButton(dialogContent.mPositiveButton, + view -> { + controller.onClick(dialogHelper.getDialog(), + DialogInterface.BUTTON_POSITIVE); + dialogHelper.getDialog().dismiss(); + }); + if (dialogContent.mNegativeButton != 0) { + dialogHelper.setBackButton(dialogContent.mNegativeButton, view -> { + controller.onClick(dialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE); + dialogHelper.getDialog().dismiss(); + }); } - titleView.setText(content); - } - - private static void setDialogMessage(View root, String content) { - TextView textView = root.findViewById(R.id.dialog_msg); - if (textView == null) { - return; - } - textView.setText(content); + return dialogHelper.getDialog(); } @VisibleForTesting @@ -158,11 +166,11 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { } @VisibleForTesting - public OnBackInvokedDispatcher getOnBackInvokedDispatcher() { + public @NonNull OnBackInvokedDispatcher getOnBackInvokedDispatcher(@NonNull Dialog dialog) { if (mBackDispatcher != null) { return mBackDispatcher; } else { - return mAlertDialog.getOnBackInvokedDispatcher(); + return dialog.getOnBackInvokedDispatcher(); } } @@ -223,15 +231,15 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { R.string.title_change_system_locale), mLocaleInfo.getFullNameNative()); dialogContent.mMessage = mContext.getString( R.string.desc_notice_device_locale_settings_change); - dialogContent.mPositiveButton = mContext.getString( - R.string.button_label_confirmation_of_system_locale_change); - dialogContent.mNegativeButton = mContext.getString(R.string.cancel); + dialogContent.mPositiveButton = + R.string.button_label_confirmation_of_system_locale_change; + dialogContent.mNegativeButton = R.string.cancel; break; case DIALOG_NOT_AVAILABLE_LOCALE: dialogContent.mTitle = String.format(mContext.getString( R.string.title_unavailable_locale), mLocaleInfo.getFullNameNative()); dialogContent.mMessage = mContext.getString(R.string.desc_unavailable_locale); - dialogContent.mPositiveButton = mContext.getString(R.string.okay); + dialogContent.mPositiveButton = R.string.okay; break; case DIALOG_ADD_SYSTEM_LOCALE: dialogContent.mTitle = String.format(mContext.getString( @@ -239,8 +247,8 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { mLocaleInfo.getFullNameNative()); dialogContent.mMessage = mContext.getString( R.string.desc_system_locale_addition); - dialogContent.mPositiveButton = mContext.getString(R.string.add); - dialogContent.mNegativeButton = mContext.getString(R.string.cancel); + dialogContent.mPositiveButton = R.string.add; + dialogContent.mNegativeButton = R.string.cancel; break; default: break; @@ -252,8 +260,8 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment { static class DialogContent { String mTitle = ""; String mMessage = ""; - String mPositiveButton = ""; - String mNegativeButton = ""; + int mPositiveButton = 0; + int mNegativeButton = 0; } } } diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java index f9c50b79bd7..b1f005a79ab 100644 --- a/src/com/android/settings/localepicker/LocaleListEditor.java +++ b/src/com/android/settings/localepicker/LocaleListEditor.java @@ -43,9 +43,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentManager; +import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.RecyclerView; @@ -53,10 +54,12 @@ import com.android.internal.app.LocalePicker; import com.android.internal.app.LocaleStore; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; +import com.android.settings.flags.Flags; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexableRaw; +import com.android.settingslib.utils.CustomDialogHelper; import com.android.settingslib.utils.StringUtil; import com.android.settingslib.widget.LayoutPreference; @@ -69,6 +72,8 @@ import java.util.Locale; */ @SearchIndexable public class LocaleListEditor extends RestrictedSettingsFragment implements View.OnTouchListener { + public static final int REQUEST_LOCALE_PICKER = 0; + protected static final String INTENT_LOCALE_KEY = "localeInfo"; protected static final String EXTRA_SYSTEM_LOCALE_DIALOG_TYPE = "system_locale_dialog_type"; protected static final String EXTRA_RESULT_LOCALE = "result_locale"; @@ -81,16 +86,16 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View private static final String INDEX_KEY_ADD_LANGUAGE = "add_language"; private static final String KEY_LANGUAGES_PICKER = "languages_picker"; private static final String KEY_CATEGORY_TERMS_OF_ADDRESS = "key_category_terms_of_address"; + private static final String KEY_ADD_A_LANGUAGE = "add_a_language"; private static final String TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT = "dialog_confirm_system_default"; private static final String TAG_DIALOG_NOT_AVAILABLE = "dialog_not_available_locale"; private static final String TAG_DIALOG_ADD_SYSTEM_LOCALE = "dialog_add_system_locale"; private static final int MENU_ID_REMOVE = Menu.FIRST + 1; - private static final int REQUEST_LOCALE_PICKER = 0; private LocaleDragAndDropAdapter mAdapter; private Menu mMenu; private View mAddLanguage; - private AlertDialog mSuggestionDialog = null; + private Preference mAddLanguagePreference; private boolean mRemoveMode; private boolean mShowingRemoveDialog; private boolean mLocaleAdditionMode = false; @@ -281,7 +286,11 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View private void setRemoveMode(boolean mRemoveMode) { this.mRemoveMode = mRemoveMode; mAdapter.setRemoveMode(mRemoveMode); - mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE); + if (Flags.settingsExpressiveDesignEnabled()) { + mAddLanguagePreference.setVisible(!mRemoveMode); + } else { + mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE); + } updateVisibilityOfRemoveMenu(); } @@ -330,7 +339,6 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View private void showDialogForAddedLocale() { Log.d(TAG, "show confirmation dialog"); Intent intent = this.getIntent(); - String dialogType = intent.getStringExtra(EXTRA_SYSTEM_LOCALE_DIALOG_TYPE); String appLocaleTag = intent.getStringExtra(EXTRA_APP_LOCALE); LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo( @@ -344,17 +352,6 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View localeDialogFragment.show(mFragmentManager, TAG_DIALOG_ADD_SYSTEM_LOCALE); } - private void customizeLayout(AlertDialog.Builder dialogBuilder, String language) { - View dialogView = getLocaleDialogView(); - dialogBuilder.setView(dialogView); - TextView title = dialogView.findViewById(R.id.dialog_title); - title.setText( - String.format(getContext().getResources().getString( - R.string.title_system_locale_addition), language)); - TextView message = dialogView.findViewById(R.id.dialog_msg); - message.setText(R.string.desc_system_locale_addition); - } - protected View getLocaleDialogView() { LayoutInflater inflater = this.getLayoutInflater(); return inflater.inflate(R.layout.locale_dialog, null); @@ -374,25 +371,33 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View return; } + int messagePaddingLeftRight = getContext().getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_message_padding_left_right); + int messagePaddingBottom = getContext().getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_message_padding_bottom); // All locales selected, warning dialog, can't remove them all if (checkedCount == mAdapter.getItemCount()) { mShowingRemoveDialog = true; - new AlertDialog.Builder(getActivity()) - .setTitle(R.string.dlg_remove_locales_error_title) - .setMessage(R.string.dlg_remove_locales_error_message) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }) - .setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - mShowingRemoveDialog = false; - } - }) - .create() - .show(); + + CustomDialogHelper dialogHelper = createRegionDialog(getContext(), + getContext().getString(R.string.dlg_remove_locales_error_title)); + dialogHelper.setMessage(R.string.dlg_remove_locales_error_message) + .setMessagePadding(messagePaddingLeftRight, 0, messagePaddingLeftRight, + messagePaddingBottom) + .setPositiveButton(android.R.string.ok, + view -> { + dialogHelper.getDialog().dismiss(); + }) + .setBackButton(R.string.cancel, view -> { + dialogHelper.getDialog().dismiss(); + }); + dialogHelper.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + mShowingRemoveDialog = false; + } + }); + dialogHelper.getDialog().show(); return; } @@ -400,54 +405,63 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View R.string.dlg_remove_locales_title); mShowingRemoveDialog = true; - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + CustomDialogHelper dialogHelper = createRegionDialog(getContext(), title); if (mAdapter.isFirstLocaleChecked()) { - builder.setMessage(R.string.dlg_remove_locales_message); + dialogHelper.setMessage(R.string.dlg_remove_locales_message) + .setMessagePadding(messagePaddingLeftRight, 0, messagePaddingLeftRight, + messagePaddingBottom); } - builder.setTitle(title) - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - setRemoveMode(false); - } - }) - .setPositiveButton(R.string.locale_remove_menu, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // This is a sensitive area to change. - // removeChecked() triggers a system update and "kills" the frame. - // This means that saveState + restoreState are called before - // setRemoveMode is called. - // So we want that mRemoveMode and dialog status have the right - // values - // before that save. - // We can't just call setRemoveMode(false) before calling - // removeCheched - // because that unchecks all items and removeChecked would have - // nothing - // to remove. - mRemoveMode = false; - mShowingRemoveDialog = false; - LocaleStore.LocaleInfo firstLocale = - mAdapter.getFeedItemList().get(0); - mAdapter.removeChecked(); - boolean isFirstRemoved = - firstLocale != mAdapter.getFeedItemList().get(0); - showConfirmDialog(isFirstRemoved, isFirstRemoved ? firstLocale - : mAdapter.getFeedItemList().get(0)); - setRemoveMode(false); - } + dialogHelper.setPositiveButton(R.string.locale_remove_menu, + view -> { + // This is a sensitive area to change. + // removeChecked() triggers a system update and "kills" the frame. + // This means that saveState + restoreState are called before + // setRemoveMode is called. + // So we want that mRemoveMode and dialog status have the right + // values + // before that save. + // We can't just call setRemoveMode(false) before calling + // removeCheched + // because that unchecks all items and removeChecked would have + // nothing + // to remove. + mRemoveMode = false; + mShowingRemoveDialog = false; + LocaleStore.LocaleInfo firstLocale = + mAdapter.getFeedItemList().get(0); + mAdapter.removeChecked(); + boolean isFirstRemoved = + firstLocale != mAdapter.getFeedItemList().get(0); + showConfirmDialog(isFirstRemoved, isFirstRemoved ? firstLocale + : mAdapter.getFeedItemList().get(0)); + setRemoveMode(false); + dialogHelper.getDialog().dismiss(); }) - .setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - mShowingRemoveDialog = false; - } - }) - .create() - .show(); + .setBackButton(R.string.cancel, view -> { + setRemoveMode(false); + dialogHelper.getDialog().dismiss(); + }); + dialogHelper.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + mShowingRemoveDialog = false; + } + }); + dialogHelper.getDialog().show(); + } + + private CustomDialogHelper createRegionDialog(Context context, String title) { + CustomDialogHelper dialogHelper = new CustomDialogHelper(context); + dialogHelper.setIcon(context.getDrawable(R.drawable.ic_settings_language_32dp)) + .setTitle(title) + .setIconPadding(0, context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_icon_padding), 0, 0) + .setTitlePadding(0, context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_title_padding), 0, + context.getResources().getDimensionPixelSize( + R.dimen.locale_picker_dialog_title_padding)); + return dialogHelper; } @Override @@ -483,20 +497,23 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View list.setAdapter(mAdapter); list.setOnTouchListener(this); list.requestFocus(); + if (Flags.settingsExpressiveDesignEnabled()) { + mAddLanguagePreference = getPreferenceScreen().findPreference(KEY_ADD_A_LANGUAGE); + } else { + mAddLanguage = layout.findViewById(R.id.add_language); + mAddLanguage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(@NonNull View v) { + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() + .logSettingsTileClick(INDEX_KEY_ADD_LANGUAGE, getMetricsCategory()); - mAddLanguage = layout.findViewById(R.id.add_language); - mAddLanguage.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() - .logSettingsTileClick(INDEX_KEY_ADD_LANGUAGE, getMetricsCategory()); - - final Intent intent = new Intent(getActivity(), - LocalePickerWithRegionActivity.class); - intent.putExtras(getActivity().getIntent().getExtras()); - startActivityForResult(intent, REQUEST_LOCALE_PICKER); - } - }); + final Intent intent = new Intent(getActivity(), + LocalePickerWithRegionActivity.class); + intent.putExtras(getActivity().getIntent().getExtras()); + startActivityForResult(intent, REQUEST_LOCALE_PICKER); + } + }); + } } @Override diff --git a/src/com/android/settings/localepicker/LocalePickerBaseListPreferenceController.java b/src/com/android/settings/localepicker/LocalePickerBaseListPreferenceController.java index c65382f1f39..8bcbe313a2d 100644 --- a/src/com/android/settings/localepicker/LocalePickerBaseListPreferenceController.java +++ b/src/com/android/settings/localepicker/LocalePickerBaseListPreferenceController.java @@ -75,9 +75,6 @@ public abstract class LocalePickerBaseListPreferenceController extends public LocalePickerBaseListPreferenceController(@NonNull Context context, @NonNull String preferenceKey) { super(context, preferenceKey); - mLocaleList = getLocaleCollectorController(context).getSupportedLocaleList(null, - false, false); - mLocaleOptions = new ArrayList<>(mLocaleList.size()); mPreferences = new ArrayMap<>(); mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @@ -246,7 +243,7 @@ public abstract class LocalePickerBaseListPreferenceController extends private void setupLocaleList() { mLocaleList = getLocaleCollectorController(mContext).getSupportedLocaleList( mParentLocale, false, mIsCountryMode); - mLocaleOptions.clear(); + mLocaleOptions = new ArrayList<>(mLocaleList.size()); } private List getSortedLocaleList( @@ -262,7 +259,9 @@ public abstract class LocalePickerBaseListPreferenceController extends boolean shouldShowLocaleEditor = shouldShowLocaleEditor(localeInfo); if (shouldShowLocaleEditor) { List feedItemList = getUserLocaleList(); - feedItemList.add(localeInfo); + for (LocaleStore.LocaleInfo locale : mLocaleList) { + feedItemList.add(locale); + } LocaleList localeList = new LocaleList(feedItemList.stream() .map(LocaleStore.LocaleInfo::getLocale) .toArray(Locale[]::new)); diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java index 3b99777720a..fc517ac4495 100644 --- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java +++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java @@ -23,14 +23,12 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.settings.SettingsEnums; import android.content.ActivityNotFoundException; -import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.ConnectivitySettingsManager; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings; import android.text.Editable; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; @@ -55,6 +53,7 @@ import com.android.settingslib.HelpUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; +import com.google.android.material.textfield.TextInputLayout; import com.google.common.net.InternetDomainName; import java.util.HashMap; @@ -64,7 +63,7 @@ import java.util.Map; * Dialog to set the Private DNS */ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat implements - DialogInterface.OnClickListener, RadioGroup.OnCheckedChangeListener, TextWatcher { + RadioGroup.OnCheckedChangeListener, TextWatcher { public static final String ANNOTATION_URL = "url"; @@ -80,16 +79,9 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat } @VisibleForTesting - static final String MODE_KEY = Settings.Global.PRIVATE_DNS_MODE; + TextInputLayout mHostnameLayout; @VisibleForTesting - static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER; - - public static String getHostnameFromSettings(ContentResolver cr) { - return Settings.Global.getString(cr, HOSTNAME_KEY); - } - - @VisibleForTesting - EditText mEditText; + EditText mHostnameText; @VisibleForTesting RadioGroup mRadioGroup; @VisibleForTesting @@ -136,22 +128,17 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat // by the controller. holder.itemView.setEnabled(true); } + + setSaveButtonListener(); } @Override protected void onBindDialogView(View view) { final Context context = getContext(); - final ContentResolver contentResolver = context.getContentResolver(); - mMode = ConnectivitySettingsManager.getPrivateDnsMode(context); - - mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname); - mEditText.addTextChangedListener(this); - mEditText.setText(getHostnameFromSettings(contentResolver)); - mRadioGroup = view.findViewById(R.id.private_dns_radio_group); - mRadioGroup.setOnCheckedChangeListener(this); mRadioGroup.check(PRIVATE_DNS_MAP.getOrDefault(mMode, R.id.private_dns_mode_opportunistic)); + mRadioGroup.setOnCheckedChangeListener(this); // Initial radio button text final RadioButton offRadioButton = view.findViewById(R.id.private_dns_mode_off); @@ -163,6 +150,13 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat final RadioButton providerRadioButton = view.findViewById(R.id.private_dns_mode_provider); providerRadioButton.setText(com.android.settingslib.R.string.private_dns_mode_provider); + mHostnameLayout = view.findViewById(R.id.private_dns_mode_provider_hostname_layout); + mHostnameText = view.findViewById(R.id.private_dns_mode_provider_hostname); + if (mHostnameText != null) { + mHostnameText.setText(ConnectivitySettingsManager.getPrivateDnsHostname(context)); + mHostnameText.addTextChangedListener(this); + } + final TextView helpTextView = view.findViewById(R.id.private_dns_help_info); helpTextView.setMovementMethod(LinkMovementMethod.getInstance()); final Intent helpIntent = HelpUtils.getHelpIntent(context, @@ -176,22 +170,8 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat } else { helpTextView.setText(""); } - } - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - final Context context = getContext(); - if (mMode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME) { - // Only clickable if hostname is valid, so we could save it safely - ConnectivitySettingsManager.setPrivateDnsHostname(context, - mEditText.getText().toString()); - } - - FeatureFactory.getFeatureFactory().getMetricsFeatureProvider().action(context, - SettingsEnums.ACTION_PRIVATE_DNS_MODE, mMode); - ConnectivitySettingsManager.setPrivateDnsMode(context, mMode); - } + updateDialogInfo(); } @Override @@ -241,24 +221,58 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat return getEnforcedAdmin() != null; } - private Button getSaveButton() { - final AlertDialog dialog = (AlertDialog) getDialog(); - if (dialog == null) { - return null; - } - return dialog.getButton(DialogInterface.BUTTON_POSITIVE); - } - private void updateDialogInfo() { final boolean modeProvider = PRIVATE_DNS_MODE_PROVIDER_HOSTNAME == mMode; - if (mEditText != null) { - mEditText.setEnabled(modeProvider); - } - final Button saveButton = getSaveButton(); - if (saveButton != null) { - saveButton.setEnabled(modeProvider - ? InternetDomainName.isValid(mEditText.getText().toString()) - : true); + if (mHostnameLayout != null) { + mHostnameLayout.setEnabled(modeProvider); + mHostnameLayout.setErrorEnabled(false); } } + + private void setSaveButtonListener() { + View.OnClickListener onClickListener = v -> doSaveButton(); + DialogInterface.OnShowListener onShowListener = dialog -> { + if (dialog == null) { + Log.e(TAG, "The DialogInterface is null!"); + return; + } + Button saveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE); + if (saveButton == null) { + Log.e(TAG, "Can't get the save button!"); + return; + } + saveButton.setOnClickListener(onClickListener); + }; + setOnShowListener(onShowListener); + } + + @VisibleForTesting + void doSaveButton() { + Context context = getContext(); + if (mMode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME) { + if (mHostnameLayout == null || mHostnameText == null) { + Log.e(TAG, "Can't find hostname resources!"); + return; + } + if (mHostnameText.getText().isEmpty()) { + mHostnameLayout.setError(context.getString(R.string.private_dns_field_require)); + Log.w(TAG, "The hostname is empty!"); + return; + } + if (!InternetDomainName.isValid(mHostnameText.getText().toString())) { + mHostnameLayout.setError(context.getString(R.string.private_dns_hostname_invalid)); + Log.w(TAG, "The hostname is invalid!"); + return; + } + + ConnectivitySettingsManager.setPrivateDnsHostname(context, + mHostnameText.getText().toString()); + } + + ConnectivitySettingsManager.setPrivateDnsMode(context, mMode); + + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() + .action(context, SettingsEnums.ACTION_PRIVATE_DNS_MODE, mMode); + getDialog().dismiss(); + } } diff --git a/src/com/android/settings/network/PrivateDnsPreferenceController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java index 21e4926f490..291ce3307fd 100644 --- a/src/com/android/settings/network/PrivateDnsPreferenceController.java +++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java @@ -135,7 +135,7 @@ public class PrivateDnsPreferenceController extends BasePreferenceController com.android.settingslib.R.string.private_dns_mode_opportunistic); case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME: return dnsesResolved - ? PrivateDnsModeDialogPreference.getHostnameFromSettings(cr) + ? ConnectivitySettingsManager.getPrivateDnsHostname(mContext) : res.getString( com.android.settingslib.R.string.private_dns_mode_provider_failure); } diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java index 3886c3beeab..615351d26c9 100644 --- a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java +++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java @@ -107,8 +107,8 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc } final PersistableBundle carrierConfig = getCarrierConfigForSubId(subId); - if ((carrierConfig == null) - || carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL)) { + if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig) || + carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL)) { return CONDITIONALLY_UNAVAILABLE; } diff --git a/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt index db16acdfc59..40cb6f93ace 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt +++ b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt @@ -25,6 +25,8 @@ import com.android.settings.R import com.android.settings.flags.Flags import com.android.settings.network.SubscriptionUtil import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle +import com.android.settingslib.spaprivileged.framework.common.userManager +import com.android.settingslib.Utils /** Preference controller for "Phone number" */ class MobileNetworkPhoneNumberPreferenceController @@ -41,13 +43,14 @@ constructor( mSubId = subId } - override fun getAvailabilityStatus(subId: Int): Int = - when { - !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE - SubscriptionManager.isValidSubscriptionId(subId) && - SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE - else -> CONDITIONALLY_UNAVAILABLE - } + override fun getAvailabilityStatus(subId: Int): Int = when { + !Flags.isDualSimOnboardingEnabled() + || !SubscriptionManager.isValidSubscriptionId(subId) + || !SubscriptionUtil.isSimHardwareVisible(mContext) + || Utils.isWifiOnly(mContext) -> CONDITIONALLY_UNAVAILABLE + !mContext.userManager.isAdminUser -> DISABLED_FOR_USER + else -> AVAILABLE + } override fun displayPreference(screen: PreferenceScreen) { super.displayPreference(screen) diff --git a/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java b/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java index 1d1b07d85a6..3d259262f38 100644 --- a/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java +++ b/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java @@ -59,7 +59,7 @@ abstract class AbstractZenModeHeaderController extends AbstractZenModePreference @Override public boolean isAvailable() { - return Flags.modesApi() && Flags.modesUi(); + return Flags.modesUi(); } protected void setUpHeader(PreferenceScreen screen, int iconSizePx) { diff --git a/src/com/android/settings/notification/modes/ZenSettingsObserver.java b/src/com/android/settings/notification/modes/ZenSettingsObserver.java index 0f22d7de341..280d76cf480 100644 --- a/src/com/android/settings/notification/modes/ZenSettingsObserver.java +++ b/src/com/android/settings/notification/modes/ZenSettingsObserver.java @@ -43,7 +43,7 @@ class ZenSettingsObserver extends ContentObserver { } void register() { - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { mContext.getContentResolver().registerContentObserver(ZEN_MODE_URI, false, this); mContext.getContentResolver().registerContentObserver(ZEN_MODE_CONFIG_ETAG_URI, false, this); @@ -51,7 +51,7 @@ class ZenSettingsObserver extends ContentObserver { } void unregister() { - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { mContext.getContentResolver().unregisterContentObserver(this); } } diff --git a/src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceController.java b/src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceController.java index 3a809d077fe..59c0a5c7138 100644 --- a/src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceController.java +++ b/src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceController.java @@ -167,7 +167,7 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK); AutomaticZenRule rule; - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { rule = new AutomaticZenRule.Builder(ruleName, mRuleInfo.defaultConditionId) .setType(mRuleInfo.type) .setOwner(mRuleInfo.serviceComponent) diff --git a/src/com/android/settings/notification/zen/ZenAccessSettings.java b/src/com/android/settings/notification/zen/ZenAccessSettings.java index ebf91bf0284..6727bfb5bb3 100644 --- a/src/com/android/settings/notification/zen/ZenAccessSettings.java +++ b/src/com/android/settings/notification/zen/ZenAccessSettings.java @@ -76,7 +76,7 @@ public class ZenAccessSettings extends EmptyTextSettings implements @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - setEmptyText(Flags.modesApi() && Flags.modesUi() + setEmptyText(Flags.modesUi() ? R.string.zen_modes_access_empty_text : R.string.zen_access_empty_text); } @@ -89,7 +89,7 @@ public class ZenAccessSettings extends EmptyTextSettings implements @Override public void onResume() { super.onResume(); - requireActivity().setTitle(Flags.modesApi() && Flags.modesUi() + requireActivity().setTitle(Flags.modesUi() ? R.string.manage_zen_modes_access_title : R.string.manage_zen_access_title); reloadList(); @@ -145,7 +145,7 @@ public class ZenAccessSettings extends EmptyTextSettings implements pref.setOnPreferenceClickListener(preference -> { AppInfoBase.startAppInfoFragment( ZenAccessDetails.class /* fragment */, - getString(Flags.modesApi() && Flags.modesUi() + getString(Flags.modesUi() ? R.string.manage_zen_modes_access_title : R.string.manage_zen_access_title), pkg, diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java index 2eb87c5c1aa..093da67d198 100644 --- a/src/com/android/settings/notification/zen/ZenModeBackend.java +++ b/src/com/android/settings/notification/zen/ZenModeBackend.java @@ -95,32 +95,19 @@ public class ZenModeBackend { } protected boolean updateZenRule(String id, AutomaticZenRule rule) { - if (android.app.Flags.modesApi()) { - return mNotificationManager.updateAutomaticZenRule(id, rule, /* fromUser= */ true); - } else { - return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule); - } + return mNotificationManager.updateAutomaticZenRule(id, rule, /* fromUser= */ true); } protected void setZenMode(int zenMode) { - if (android.app.Flags.modesApi()) { - mNotificationManager.setZenMode(zenMode, null, TAG, /* fromUser= */ true); - } else { - NotificationManager.from(mContext).setZenMode(zenMode, null, TAG); - } + mNotificationManager.setZenMode(zenMode, null, TAG, /* fromUser= */ true); mZenMode = getZenMode(); } protected void setZenModeForDuration(int minutes) { Uri conditionId = ZenModeConfig.toTimeCondition(mContext, minutes, ActivityManager.getCurrentUser(), true).id; - if (android.app.Flags.modesApi()) { - mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, - conditionId, TAG, /* fromUser= */ true); - } else { - mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, - conditionId, TAG); - } + mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, + conditionId, TAG, /* fromUser= */ true); mZenMode = getZenMode(); } @@ -190,14 +177,9 @@ public class ZenModeBackend { int priorityConversationSenders) { mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders, priorityMessageSenders, suppressedVisualEffects, priorityConversationSenders); - if (android.app.Flags.modesApi()) { - mNotificationManager.setNotificationPolicy(mPolicy, /* fromUser= */ true); - } else { - mNotificationManager.setNotificationPolicy(mPolicy); - } + mNotificationManager.setNotificationPolicy(mPolicy, /* fromUser= */ true); } - private int getNewSuppressedEffects(boolean suppress, int effectType) { int effects = mPolicy.suppressedVisualEffects; @@ -373,11 +355,7 @@ public class ZenModeBackend { } public boolean removeZenRule(String ruleId) { - if (android.app.Flags.modesApi()) { - return mNotificationManager.removeAutomaticZenRule(ruleId, /* fromUser= */ true); - } else { - return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId); - } + return mNotificationManager.removeAutomaticZenRule(ruleId, /* fromUser= */ true); } public NotificationManager.Policy getConsolidatedPolicy() { @@ -386,11 +364,7 @@ public class ZenModeBackend { protected String addZenRule(AutomaticZenRule rule) { try { - if (android.app.Flags.modesApi()) { - return mNotificationManager.addAutomaticZenRule(rule, /* fromUser= */ true); - } else { - return NotificationManager.from(mContext).addAutomaticZenRule(rule); - } + return mNotificationManager.addAutomaticZenRule(rule, /* fromUser= */ true); } catch (Exception e) { return null; } diff --git a/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java index 4c647cce3b9..9e23e367982 100644 --- a/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java +++ b/src/com/android/settings/notification/zen/ZenModeRuleSettingsBase.java @@ -104,16 +104,11 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase { Bundle bundle = new Bundle(); bundle.putString(ZenCustomRuleSettings.RULE_ID, mId); - // When modes_api flag is on, we skip the radio button screen distinguishing - // between "default" and "custom" and take users directly to the custom - // settings screen. - String destination = ZenCustomRuleSettings.class.getName(); - int sourceMetricsCategory = 0; - if (Flags.modesApi()) { - // From ZenRuleCustomPolicyPreferenceController#launchCustomSettings - destination = ZenCustomRuleConfigSettings.class.getName(); - sourceMetricsCategory = SettingsEnums.ZEN_CUSTOM_RULE_SOUND_SETTINGS; - } + // Skip the radio button screen distinguishing between "default" and + // "custom" and take users directly to the custom settings screen. + // From ZenRuleCustomPolicyPreferenceController#launchCustomSettings + String destination = ZenCustomRuleConfigSettings.class.getName(); + int sourceMetricsCategory = SettingsEnums.ZEN_CUSTOM_RULE_SOUND_SETTINGS; new SubSettingLauncher(mContext) .setDestination(destination) .setArguments(bundle) @@ -165,7 +160,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase { protected void updateScheduleRule(ZenModeConfig.ScheduleInfo schedule) { mRule.setConditionId(ZenModeConfig.toScheduleConditionId(schedule)); - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { mRule.setTriggerDescription( SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, schedule)); } @@ -174,7 +169,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase { protected void updateEventRule(ZenModeConfig.EventInfo event) { mRule.setConditionId(ZenModeConfig.toEventConditionId(event)); - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { mRule.setTriggerDescription( SystemZenRules.getTriggerDescriptionForScheduleEvent(mContext, event)); } diff --git a/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java b/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java index d16b1e4ba45..8adeac5f4e8 100644 --- a/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java +++ b/src/com/android/settings/notification/zen/ZenModeSliceBuilder.java @@ -19,7 +19,6 @@ package com.android.settings.notification.zen; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; import android.annotation.ColorInt; -import android.app.Flags; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.settings.SettingsEnums; @@ -117,12 +116,8 @@ public class ZenModeSliceBuilder { } else { zenMode = Settings.Global.ZEN_MODE_OFF; } - if (Flags.modesApi()) { - NotificationManager.from(context).setZenMode(zenMode, /* conditionId= */ null, TAG, - /* fromUser= */ true); - } else { - NotificationManager.from(context).setZenMode(zenMode, null /* conditionId */, TAG); - } + NotificationManager.from(context).setZenMode(zenMode, /* conditionId= */ null, TAG, + /* fromUser= */ true); // Do not notifyChange on Uri. The service takes longer to update the current value than it // does for the Slice to check the current value again. Let {@link SliceBroadcastRelay} // handle it. diff --git a/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java b/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java index 082b2a53ae5..2ae11378c04 100644 --- a/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenRuleButtonsPreferenceController.java @@ -19,19 +19,14 @@ package com.android.settings.notification.zen; import android.app.AutomaticZenRule; import android.app.settings.SettingsEnums; import android.content.Context; -import android.content.Intent; -import android.os.Bundle; import android.text.TextUtils; import android.view.View; import androidx.fragment.app.Fragment; -import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceScreen; -import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.core.SubSettingLauncher; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.widget.ActionButtonsPreference; @@ -87,7 +82,6 @@ public class ZenRuleButtonsPreferenceController extends AbstractZenModePreferenc mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK); mRule.setName(ruleName); - mRule.setModified(true); mBackend.updateZenRule(mId, mRule); } }); diff --git a/src/com/android/settings/notification/zen/ZenRulePreference.java b/src/com/android/settings/notification/zen/ZenRulePreference.java index 06302134eb3..32b2a8828c0 100644 --- a/src/com/android/settings/notification/zen/ZenRulePreference.java +++ b/src/com/android/settings/notification/zen/ZenRulePreference.java @@ -143,8 +143,7 @@ public class ZenRulePreference extends PrimarySwitchPreference { private String computeRuleSummary(AutomaticZenRule rule) { if (rule != null) { - if (Flags.modesApi() && Flags.modesUi() - && !TextUtils.isEmpty(rule.getTriggerDescription())) { + if (Flags.modesUi() && !TextUtils.isEmpty(rule.getTriggerDescription())) { return rule.getTriggerDescription(); } diff --git a/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java index 48960661972..7a1df0493b8 100644 --- a/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java +++ b/src/com/android/settings/notification/zen/ZenRuleSelectionDialog.java @@ -181,7 +181,7 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment { rt.title = mContext.getString(R.string.zen_schedule_rule_type_name); rt.packageName = ZenModeConfig.getEventConditionProvider().getPackageName(); rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule); - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { rt.type = AutomaticZenRule.TYPE_SCHEDULE_TIME; rt.defaultTriggerDescription = SystemZenRules.getTriggerDescriptionForScheduleTime( mContext, schedule); @@ -201,7 +201,7 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment { rt.title = mContext.getString(R.string.zen_event_rule_type_name); rt.packageName = ZenModeConfig.getScheduleConditionProvider().getPackageName(); rt.defaultConditionId = ZenModeConfig.toEventConditionId(event); - if (Flags.modesApi() && Flags.modesUi()) { + if (Flags.modesUi()) { rt.type = AutomaticZenRule.TYPE_SCHEDULE_CALENDAR; rt.defaultTriggerDescription = SystemZenRules.getTriggerDescriptionForScheduleEvent( mContext, event); diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index 80f73b95c66..7892ac47ffa 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -560,6 +560,7 @@ public class ChooseLockPassword extends SettingsActivity { setupPasswordRequirementsView(headerLayout); mPasswordRestrictionView.setLayoutManager(new LinearLayoutManager(getActivity())); + mPasswordRestrictionView.setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE); mPasswordEntry = view.findViewById(R.id.password_entry); mPasswordEntry.setOnEditorActionListener(this); mPasswordEntry.addTextChangedListener(this); @@ -770,7 +771,7 @@ public class ChooseLockPassword extends SettingsActivity { // If the stage changed, announce the header for accessibility. This // is a no-op when accessibility is disabled. if (previousStage != stage) { - mLayout.announceForAccessibility(mLayout.getHeaderText()); + getActivity().setTitle(mLayout.getHeaderText()); } } diff --git a/src/com/android/settings/password/PasswordRequirementAdapter.java b/src/com/android/settings/password/PasswordRequirementAdapter.java index b17f86481df..157a716ce9a 100644 --- a/src/com/android/settings/password/PasswordRequirementAdapter.java +++ b/src/com/android/settings/password/PasswordRequirementAdapter.java @@ -20,9 +20,9 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; @@ -66,15 +66,20 @@ public class PasswordRequirementAdapter extends return mRequirements[position].hashCode(); } - @Override - public void onViewAttachedToWindow(@NonNull PasswordRequirementViewHolder holder) { - holder.mDescriptionText.announceForAccessibility(holder.mDescriptionText.getText()); - } - @Override public void onBindViewHolder(PasswordRequirementViewHolder holder, int position) { final int fontSize = mContext.getResources().getDimensionPixelSize( R.dimen.password_requirement_font_size); + + final String requirement = mRequirements[position]; + holder.mDescriptionText.setAccessibilityDelegate(new View.AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + holder.mDescriptionText.setStateDescription(requirement); + } + }); + holder.mDescriptionText.setText(mRequirements[position]); if (mIsTooShortError) { holder.mDescriptionText.setTextAppearance(R.style.ScreenLockPasswordHintTextFontStyle); diff --git a/src/com/android/settings/shortcut/ShortcutsUpdateReceiver.java b/src/com/android/settings/shortcut/ShortcutsUpdateReceiver.java index 657af5ba027..3fde390917d 100644 --- a/src/com/android/settings/shortcut/ShortcutsUpdateReceiver.java +++ b/src/com/android/settings/shortcut/ShortcutsUpdateReceiver.java @@ -32,7 +32,7 @@ public class ShortcutsUpdateReceiver extends BroadcastReceiver { @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { - if (!Flags.modesApi() || !Flags.modesUi()) { + if (!Flags.modesUi()) { return; } diff --git a/src/com/android/settings/shortcut/ShortcutsUpdater.java b/src/com/android/settings/shortcut/ShortcutsUpdater.java index 90a60fda379..30cb5c11aa7 100644 --- a/src/com/android/settings/shortcut/ShortcutsUpdater.java +++ b/src/com/android/settings/shortcut/ShortcutsUpdater.java @@ -86,7 +86,7 @@ public class ShortcutsUpdater { private static ComponentName maybeGetReplacingComponent(Context context, ComponentName cn) { // ZenModeSettingsActivity is replaced by ModesSettingsActivity and will be deleted // soon (so we shouldn't use ZenModeSettingsActivity.class). - if (Flags.modesApi() && Flags.modesUi() + if (Flags.modesUi() && cn.getClassName().endsWith("Settings$ZenModeSettingsActivity")) { return new ComponentName(context, Settings.ModesSettingsActivity.class); } diff --git a/src/com/android/settings/sound/TopLevelSoundPreferenceController.java b/src/com/android/settings/sound/TopLevelSoundPreferenceController.java index ddc33992d8d..c219d7ca740 100644 --- a/src/com/android/settings/sound/TopLevelSoundPreferenceController.java +++ b/src/com/android/settings/sound/TopLevelSoundPreferenceController.java @@ -33,7 +33,7 @@ public class TopLevelSoundPreferenceController extends BasePreferenceController @Override public void updateState(Preference preference) { super.updateState(preference); - preference.setSummary(Flags.modesApi() && Flags.modesUi() + preference.setSummary(Flags.modesUi() ? R.string.sound_dashboard_summary : R.string.sound_dashboard_summary_with_dnd); } diff --git a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java index ad155ffd743..f68a8d4cf6a 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java @@ -68,9 +68,6 @@ public class ConnectedBluetoothDeviceUpdaterTest { private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C"; private static final String TEST_EXCLUSIVE_MANAGER = "com.test.manager"; - private static final String TEMP_BOND_METADATA = - "le_audio_sharing"; - private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25; @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @@ -408,22 +405,6 @@ public class ConnectedBluetoothDeviceUpdaterTest { verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice); } - @Test - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI) - public void update_temporaryBondDevice_removePreference() { - setUpDeviceUpdaterWithAudioMode(AudioManager.MODE_NORMAL); - when(mBluetoothDeviceUpdater - .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true); - when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true); - when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS)) - .thenReturn(TEMP_BOND_METADATA.getBytes()); - - mBluetoothDeviceUpdater.update(mCachedBluetoothDevice); - - verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice); - verify(mBluetoothDeviceUpdater, never()).addPreference(mCachedBluetoothDevice); - } - private void setUpDeviceUpdaterWithAudioMode(int audioMode) { mAudioManager.setMode(audioMode); mBluetoothDeviceUpdater = spy(new ConnectedBluetoothDeviceUpdater(mContext, diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java index a1cc1d80acb..ecf6d003cef 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java @@ -75,7 +75,6 @@ public class ConnectedDeviceDashboardFragmentTest { private static final String KEY_AUDIO_SHARING_SETTINGS = "connected_device_audio_sharing_settings"; private static final String KEY_ADD_BT_DEVICES = "add_bt_devices"; - private static final String KEY_TEMPORARY_BOND_DEVICES = "temp_bond_device_list"; private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; private static final String SLICE_ACTION = "com.android.settings.SEARCH_RESULT_TRAMPOLINE"; @@ -130,8 +129,7 @@ public class ConnectedDeviceDashboardFragmentTest { KEY_SAVED_DEVICE_SEE_ALL, KEY_FAST_PAIR_DEVICE_SEE_ALL, KEY_AUDIO_SHARING_DEVICES, - KEY_AUDIO_SHARING_SETTINGS, - KEY_TEMPORARY_BOND_DEVICES); + KEY_AUDIO_SHARING_SETTINGS); } @Test diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java index a2ac0cc99c9..4f6fed7b732 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java @@ -43,7 +43,6 @@ import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.os.Looper; -import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.view.View; @@ -111,11 +110,8 @@ public class AudioSharingCallAudioPreferenceControllerTest { private static final String PREF_KEY = "calls_and_alarms"; private static final String TEST_DEVICE_NAME1 = "test1"; private static final String TEST_DEVICE_NAME2 = "test2"; - private static final String TEMP_BOND_METADATA = - "le_audio_sharing"; private static final int TEST_DEVICE_GROUP_ID1 = 1; private static final int TEST_DEVICE_GROUP_ID2 = 2; - private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25; private static final String TEST_SETTINGS_KEY = "bluetooth_le_broadcast_fallback_active_group_id"; @@ -447,23 +443,6 @@ public class AudioSharingCallAudioPreferenceControllerTest { assertThat(mPreference.getSummary().toString()).isEmpty(); } - @Test - @EnableFlags(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI) - public void displayPreference_hasTemporaryBondDevice_doNotShow() { - Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); - when(mBroadcast.isEnabled(any())).thenReturn(true); - when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); - when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); - when(mDevice2.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS)).thenReturn( - TEMP_BOND_METADATA.getBytes()); - - mController.displayPreference(mScreen); - shadowOf(Looper.getMainLooper()).idle(); - - assertThat(mController.mGroupedConnectedDevices).hasSize(0); - } - @Test public void displayPreference_clickToShowCorrectDialog() { AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java index 145a5c7a549..d964b9cbd79 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java @@ -93,8 +93,14 @@ public class AudioSharingDialogFragmentTest { private static final String METADATA_STR = "BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;" + "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;"; + private static final String METADATA_STR_NO_PASSWORD = + "BLUETOOTH:UUID:184F;BN:SG9ja2V5;AT:0;AD:AABBCC001122;BI:DE51E9;SQ:1;AS:1;PI:FFFF;" + + "NS:1;BS:1;NB:1;;"; private static final BluetoothLeBroadcastMetadata METADATA = BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(METADATA_STR); + private static final BluetoothLeBroadcastMetadata METADATA_NO_PASSWORD = + BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata( + METADATA_STR_NO_PASSWORD); private Fragment mParent; private FakeFeatureFactory mFeatureFactory; @@ -290,6 +296,50 @@ public class AudioSharingDialogFragmentTest { assertThat(dialog.isShowing()).isFalse(); } + @Test + public void onCreateDialog_noExtraConnectedDevice_hasMetadataNoPassword_showCancelButton() { + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + AtomicBoolean isCancelBtnClicked = new AtomicBoolean(false); + AudioSharingDialogFragment.show( + mParent, + new ArrayList<>(), + METADATA_NO_PASSWORD, + new AudioSharingDialogFragment.DialogEventListener() { + @Override + public void onCancelClick() { + isCancelBtnClicked.set(true); + } + }, + TEST_EVENT_DATA_LIST); + shadowMainLooper().idle(); + AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + assertThat(dialog).isNotNull(); + ImageView image = dialog.findViewById(R.id.description_image); + assertThat(image).isNotNull(); + TextView text = dialog.findViewById(R.id.description_text); + assertThat(text).isNotNull(); + assertThat(METADATA_NO_PASSWORD).isNotNull(); + assertThat(text.getText().toString()).isEqualTo( + mParent.getString(R.string.audio_sharing_dialog_qr_code_content_no_password, + METADATA_NO_PASSWORD.getBroadcastName())); + TextView textBottom = dialog.findViewById(R.id.description_text_2); + assertThat(textBottom).isNotNull(); + assertThat(textBottom.getText().toString()).isEqualTo( + mParent.getString(R.string.audio_sharing_dialog_pair_new_device_content)); + Button cancelBtn = dialog.findViewById(R.id.negative_btn); + assertThat(cancelBtn).isNotNull(); + cancelBtn.performClick(); + shadowMainLooper().idle(); + + verify(mFeatureFactory.metricsFeatureProvider) + .action( + any(Context.class), + eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED), + eq(TEST_EVENT_DATA)); + assertThat(isCancelBtnClicked.get()).isTrue(); + assertThat(dialog.isShowing()).isFalse(); + } + @Test public void onCreateDialog_flagOn_singleExtraConnectedDevice() { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupControllerTest.java deleted file mode 100644 index a85555d36d5..00000000000 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupControllerTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * 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.connecteddevice.audiosharing; - -import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothStatusCodes; -import android.content.Context; -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 androidx.lifecycle.LifecycleOwner; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceGroup; -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; -import androidx.test.core.app.ApplicationProvider; - -import com.android.settings.bluetooth.Utils; -import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; -import com.android.settings.testutils.shadow.ShadowBluetoothUtils; -import com.android.settingslib.bluetooth.BluetoothCallback; -import com.android.settingslib.bluetooth.BluetoothEventManager; -import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.flags.Flags; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadow.api.Shadow; - -/** Tests for {@link TemporaryBondDeviceGroupController}. */ -@RunWith(RobolectricTestRunner.class) -@Config( - shadows = { - ShadowBluetoothAdapter.class, - ShadowBluetoothUtils.class - }) -public class TemporaryBondDeviceGroupControllerTest { - private static final String KEY = "temp_bond_device_list"; - private static final String PREFERENCE_KEY_1 = "pref_key_1"; - - @Rule - public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); - - @Mock - private TemporaryBondDeviceGroupUpdater mBluetoothDeviceUpdater; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private PreferenceManager mPreferenceManager; - @Mock - private LocalBluetoothManager mLocalBtManager; - @Mock - private BluetoothEventManager mEventManager; - @Mock private PreferenceScreen mScreen; - - - private PreferenceGroup mPreferenceGroup; - private Context mContext; - private Preference mPreference; - private TemporaryBondDeviceGroupController mTemporaryBondDeviceGroupController; - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = ApplicationProvider.getApplicationContext(); - mPreference = new Preference(mContext); - mPreference.setKey(PREFERENCE_KEY_1); - mPreferenceGroup = spy(new PreferenceCategory(mContext)); - when(mPreferenceGroup.getPreferenceManager()).thenReturn(mPreferenceManager); - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); - when(mScreen.getContext()).thenReturn(mContext); - when(mScreen.findPreference(KEY)).thenReturn(mPreferenceGroup); - - ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager; - mLocalBtManager = Utils.getLocalBtManager(mContext); - when(mLocalBtManager.getEventManager()).thenReturn(mEventManager); - ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( - BluetoothAdapter.getDefaultAdapter()); - shadowBluetoothAdapter.setEnabled(true); - shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( - BluetoothStatusCodes.FEATURE_SUPPORTED); - shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( - BluetoothStatusCodes.FEATURE_SUPPORTED); - - mTemporaryBondDeviceGroupController = spy(new TemporaryBondDeviceGroupController(mContext)); - mTemporaryBondDeviceGroupController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); - mTemporaryBondDeviceGroupController.setPreferenceGroup(mPreferenceGroup); - } - - @Test - @RequiresFlagsDisabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI) - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) - public void onStart_flagOff_doNothing() { - mTemporaryBondDeviceGroupController.onStart(mLifecycleOwner); - - verify(mEventManager, never()).registerCallback(any(BluetoothCallback.class)); - verify(mBluetoothDeviceUpdater, never()).registerCallback(); - verify(mBluetoothDeviceUpdater, never()).refreshPreference(); - } - - @Test - @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI) - public void onStart_audioSharingUINotAvailable_doNothing() { - mTemporaryBondDeviceGroupController.onStart(mLifecycleOwner); - - verify(mEventManager, never()).registerCallback(any(BluetoothCallback.class)); - verify(mBluetoothDeviceUpdater, never()).registerCallback(); - verify(mBluetoothDeviceUpdater, never()).refreshPreference(); - } - - @Test - @RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI, - Flags.FLAG_ENABLE_LE_AUDIO_SHARING}) - public void onStart_registerCallbacks() { - mTemporaryBondDeviceGroupController.onStart(mLifecycleOwner); - - verify(mEventManager).registerCallback(any(BluetoothCallback.class)); - verify(mBluetoothDeviceUpdater).registerCallback(); - verify(mBluetoothDeviceUpdater).refreshPreference(); - } - - @Test - @RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI, - Flags.FLAG_ENABLE_LE_AUDIO_SHARING}) - public void onStop_unregisterCallbacks() { - mTemporaryBondDeviceGroupController.onStop(mLifecycleOwner); - - verify(mEventManager).unregisterCallback(any(BluetoothCallback.class)); - verify(mBluetoothDeviceUpdater).unregisterCallback(); - } - - @Test - @RequiresFlagsDisabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI) - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) - public void displayPreference_flagOff_doNothing() { - mTemporaryBondDeviceGroupController.displayPreference(mScreen); - - assertThat(mPreferenceGroup.isVisible()).isFalse(); - verify(mBluetoothDeviceUpdater, never()).forceUpdate(); - } - - @Test - @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI) - public void displayPreference_audioSharingUINotAvailable_doNothing() { - mTemporaryBondDeviceGroupController.displayPreference(mScreen); - - assertThat(mPreferenceGroup.isVisible()).isFalse(); - verify(mBluetoothDeviceUpdater, never()).forceUpdate(); - } - - @Test - @RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI, - Flags.FLAG_ENABLE_LE_AUDIO_SHARING}) - public void displayPreference_updateDeviceList() { - mTemporaryBondDeviceGroupController.displayPreference(mScreen); - - assertThat(mPreferenceGroup.isVisible()).isFalse(); - verify(mBluetoothDeviceUpdater).setPrefContext(mContext); - verify(mBluetoothDeviceUpdater).forceUpdate(); - } - - @Test - public void onDeviceAdded_firstAdd_becomeVisibleAndPreferenceAdded() { - mTemporaryBondDeviceGroupController.onDeviceAdded(mPreference); - - assertThat(mPreferenceGroup.isVisible()).isTrue(); - assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); - } - - @Test - public void onDeviceRemoved_lastRemove_becomeInvisibleAndPreferenceRemoved() { - mPreferenceGroup.addPreference(mPreference); - - mTemporaryBondDeviceGroupController.onDeviceRemoved(mPreference); - - assertThat(mPreferenceGroup.isVisible()).isFalse(); - assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0); - } - - @Test - public void onDeviceRemoved_notLastRemove_stillVisible() { - mPreferenceGroup.setVisible(true); - mPreferenceGroup.addPreference(mPreference); - mPreferenceGroup.addPreference(new Preference(mContext)); - - mTemporaryBondDeviceGroupController.onDeviceRemoved(mPreference); - - assertThat(mPreferenceGroup.isVisible()).isTrue(); - assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); - } - - @Test - public void getPreferenceKey_returnsCorrectKey() { - assertThat(mTemporaryBondDeviceGroupController.getPreferenceKey()).isEqualTo(KEY); - } - - @Test - @RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI, - Flags.FLAG_ENABLE_LE_AUDIO_SHARING}) - public void getAvailabilityStatus_returnsAvailable() { - assertThat(mTemporaryBondDeviceGroupController.getAvailabilityStatus()).isEqualTo( - AVAILABLE_UNSEARCHABLE); - } -} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupUpdaterTest.java deleted file mode 100644 index 0b34c101719..00000000000 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/TemporaryBondDeviceGroupUpdaterTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 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.connecteddevice.audiosharing; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothStatusCodes; -import android.content.Context; -import android.platform.test.annotations.RequiresFlagsEnabled; -import android.platform.test.flag.junit.CheckFlagsRule; -import android.platform.test.flag.junit.DeviceFlagsValueProvider; - -import androidx.test.core.app.ApplicationProvider; - -import com.android.settings.bluetooth.Utils; -import com.android.settings.connecteddevice.DevicePreferenceCallback; -import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; -import com.android.settings.testutils.shadow.ShadowBluetoothUtils; -import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; -import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.flags.Flags; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadow.api.Shadow; - -import java.util.ArrayList; -import java.util.Collection; - -/** Tests for {@link TemporaryBondDeviceGroupUpdater}. */ -@RunWith(RobolectricTestRunner.class) -@Config( - shadows = { - ShadowBluetoothAdapter.class, - ShadowBluetoothUtils.class - }) -public class TemporaryBondDeviceGroupUpdaterTest { - private static final String TAG = "TemporaryBondDeviceGroupUpdater"; - private static final String PREF_KEY_PREFIX = "temp_bond_bt_"; - private static final String TEMP_BOND_METADATA = - "le_audio_sharing"; - private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25; - - @Rule - public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); - - @Mock - private DevicePreferenceCallback mDevicePreferenceCallback; - @Mock - private CachedBluetoothDevice mCachedBluetoothDevice; - @Mock - private BluetoothDevice mBluetoothDevice; - @Mock - private LocalBluetoothManager mLocalBtManager; - @Mock - private CachedBluetoothDeviceManager mCachedDeviceManager; - - private TemporaryBondDeviceGroupUpdater mDeviceUpdater; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( - BluetoothAdapter.getDefaultAdapter()); - shadowBluetoothAdapter.setEnabled(true); - shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( - BluetoothStatusCodes.FEATURE_SUPPORTED); - shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( - BluetoothStatusCodes.FEATURE_SUPPORTED); - Context context = ApplicationProvider.getApplicationContext(); - ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager; - mLocalBtManager = Utils.getLocalBtManager(context); - when(mLocalBtManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); - when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); - Collection cachedDevices = new ArrayList<>(); - cachedDevices.add(mCachedBluetoothDevice); - when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(cachedDevices); - mDeviceUpdater = - spy( - new TemporaryBondDeviceGroupUpdater( - context, mDevicePreferenceCallback, /* metricsCategory= */ 0)); - mDeviceUpdater.setPrefContext(context); - } - - @After - public void tearDown() { - ShadowBluetoothUtils.reset(); - } - - @Test - @RequiresFlagsEnabled({Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI, - Flags.FLAG_ENABLE_LE_AUDIO_SHARING}) - public void isFilterMatched_isTemporaryBondDevice_returnsTrue() { - when(mBluetoothDevice.isConnected()).thenReturn(true); - when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); - when(mBluetoothDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS)) - .thenReturn(TEMP_BOND_METADATA.getBytes()); - - assertThat(mDeviceUpdater.isFilterMatched(mCachedBluetoothDevice)).isTrue(); - } - - @Test - public void getLogTag_returnsCorrectTag() { - assertThat(mDeviceUpdater.getLogTag()).isEqualTo(TAG); - } - - @Test - public void getPreferenceKey_returnsCorrectKey() { - assertThat(mDeviceUpdater.getPreferenceKeyPrefix()).isEqualTo(PREF_KEY_PREFIX); - } -} diff --git a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java index aa05f628f7f..c2a4d033080 100644 --- a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioHwOffloadPreferenceControllerTest.java @@ -20,6 +20,8 @@ import static android.bluetooth.BluetoothStatusCodes.FEATURE_SUPPORTED; import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController .A2DP_OFFLOAD_DISABLED_PROPERTY; +import static com.android.settings.development.BluetoothA2dpHwOffloadPreferenceController + .A2DP_OFFLOAD_SUPPORTED_PROPERTY; import static com.android.settings.development.BluetoothLeAudioHwOffloadPreferenceController .LE_AUDIO_OFFLOAD_DISABLED_PROPERTY; import static com.android.settings.development.BluetoothLeAudioHwOffloadPreferenceController @@ -120,4 +122,17 @@ public class BluetoothLeAudioHwOffloadPreferenceControllerTest { leAueioDisabled = SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, false); assertThat(leAueioDisabled).isTrue(); } + + @Test + public void asDisableDeveloperOption_ResetLEOffloadBasedOnA2dpLeAudioOffloadSupported() { + SystemProperties.set(LE_AUDIO_OFFLOAD_SUPPORTED_PROPERTY, Boolean.toString(true)); + SystemProperties.set(A2DP_OFFLOAD_SUPPORTED_PROPERTY, Boolean.toString(true)); + + SystemProperties.set( + LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, Boolean.toString(true)); + mController.onDeveloperOptionsSwitchDisabled(); + boolean leAueioDisabled = + SystemProperties.getBoolean(LE_AUDIO_OFFLOAD_DISABLED_PROPERTY, false); + assertThat(leAueioDisabled).isFalse(); + } } diff --git a/tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java index 6296626dedb..388e9b21f29 100644 --- a/tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java @@ -102,7 +102,8 @@ public class DesktopExperiencePreferenceControllerTest { // Set desktop mode available when(mResources.getBoolean(com.android.internal.R.bool.config_isDesktopModeSupported)) .thenReturn(true); - when(mResources.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops)) + when(mResources + .getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops)) .thenReturn(true); ShadowSystemProperties.override("persist.wm.debug.desktop_mode_enforce_device_restrictions", "false"); diff --git a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java index 02aa8725bd0..9f718f9db62 100644 --- a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java @@ -104,7 +104,8 @@ public class DesktopModePreferenceControllerTest { // Set desktop mode available when(mResources.getBoolean(R.bool.config_isDesktopModeSupported)) .thenReturn(true); - when(mResources.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops)) + when(mResources + .getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops)) .thenReturn(true); ShadowSystemProperties.override("persist.wm.debug.desktop_mode_enforce_device_restrictions", "false"); diff --git a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java index f3b96a4425f..2284d92cd70 100644 --- a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java @@ -97,7 +97,8 @@ public class DesktopModeSecondaryDisplayPreferenceControllerTest { when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); mController.displayPreference(mScreen); when(mResources.getBoolean(R.bool.config_isDesktopModeSupported)).thenReturn(false); - when(mResources.getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops)) + when(mResources + .getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops)) .thenReturn(false); } diff --git a/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java index cf32ae83e00..b4b0bccf832 100644 --- a/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java @@ -91,6 +91,7 @@ public class FreeformWindowsPreferenceControllerTest { doReturn(mFragmentManager).when(mActivity).getSupportFragmentManager(); doReturn(mActivity).when(mFragment).getActivity(); doReturn(true).when(mResources).getBoolean(R.bool.config_isDesktopModeSupported); + doReturn(true).when(mResources).getBoolean(R.bool.config_canInternalDisplayHostDesktops); mController = new FreeformWindowsPreferenceController(mContext, mFragment); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); when(mContext.getPackageManager()).thenReturn(mPackageManager); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageTimeControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageTimeControllerTest.java index e8eb1260bcd..60ece9df424 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageTimeControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageTimeControllerTest.java @@ -99,9 +99,9 @@ public final class PowerUsageTimeControllerTest { /* anomalyHintText= */ null); verifyOnePreferenceInvisible(mBackgroundTimePreference); - verify(mScreenTimePreference).setTimeTitle("Screen time"); - verify(mScreenTimePreference).setTimeSummary("1 min"); - verify(mScreenTimePreference, never()).setAnomalyHint(anyString()); + verify(mScreenTimePreference).setTitle("Screen time"); + verify(mScreenTimePreference).setSummary("1 min"); + verify(mScreenTimePreference, never()).setHint(anyString()); } @Test @@ -117,9 +117,9 @@ public final class PowerUsageTimeControllerTest { /* anomalyHintText= */ null); verifyOnePreferenceInvisible(mScreenTimePreference); - verify(mBackgroundTimePreference).setTimeTitle("Background time"); - verify(mBackgroundTimePreference).setTimeSummary("2 min"); - verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString()); + verify(mBackgroundTimePreference).setTitle("Background time"); + verify(mBackgroundTimePreference).setSummary("2 min"); + verify(mBackgroundTimePreference, never()).setHint(anyString()); } @Test @@ -135,12 +135,12 @@ public final class PowerUsageTimeControllerTest { /* anomalyHintText= */ null); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference).setTimeTitle("Screen time"); - verify(mScreenTimePreference).setTimeSummary("1 min"); - verify(mScreenTimePreference, never()).setAnomalyHint(anyString()); - verify(mBackgroundTimePreference).setTimeTitle("Background time"); - verify(mBackgroundTimePreference).setTimeSummary("2 min"); - verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString()); + verify(mScreenTimePreference).setTitle("Screen time"); + verify(mScreenTimePreference).setSummary("1 min"); + verify(mScreenTimePreference, never()).setHint(anyString()); + verify(mBackgroundTimePreference).setTitle("Background time"); + verify(mBackgroundTimePreference).setSummary("2 min"); + verify(mBackgroundTimePreference, never()).setHint(anyString()); verify(mPowerUsageTimeCategory).setTitle("App usage for 12 am-2 am"); } @@ -173,8 +173,8 @@ public final class PowerUsageTimeControllerTest { /* anomalyHintText= */ null); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference).setTimeSummary("1 min"); - verify(mBackgroundTimePreference).setTimeSummary("Less than a minute"); + verify(mScreenTimePreference).setSummary("1 min"); + verify(mBackgroundTimePreference).setSummary("Less than a minute"); } @Test @@ -190,8 +190,8 @@ public final class PowerUsageTimeControllerTest { /* anomalyHintText= */ null); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference).setTimeSummary("Less than a minute"); - verify(mBackgroundTimePreference).setTimeSummary("2 min"); + verify(mScreenTimePreference).setSummary("Less than a minute"); + verify(mBackgroundTimePreference).setSummary("2 min"); } @Test @@ -207,8 +207,8 @@ public final class PowerUsageTimeControllerTest { /* anomalyHintText= */ null); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference).setTimeSummary("Less than a minute"); - verify(mBackgroundTimePreference).setTimeSummary("Less than a minute"); + verify(mScreenTimePreference).setSummary("Less than a minute"); + verify(mBackgroundTimePreference).setSummary("Less than a minute"); } @Test @@ -224,8 +224,8 @@ public final class PowerUsageTimeControllerTest { TEST_ANOMALY_HINT_TEXT); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference).setAnomalyHint(TEST_ANOMALY_HINT_TEXT); - verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString()); + verify(mScreenTimePreference).setHint(TEST_ANOMALY_HINT_TEXT); + verify(mBackgroundTimePreference, never()).setHint(anyString()); } @Test @@ -241,8 +241,8 @@ public final class PowerUsageTimeControllerTest { TEST_ANOMALY_HINT_TEXT); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference, never()).setAnomalyHint(anyString()); - verify(mBackgroundTimePreference).setAnomalyHint(TEST_ANOMALY_HINT_TEXT); + verify(mScreenTimePreference, never()).setHint(anyString()); + verify(mBackgroundTimePreference).setHint(TEST_ANOMALY_HINT_TEXT); } @Test @@ -258,9 +258,9 @@ public final class PowerUsageTimeControllerTest { TEST_ANOMALY_HINT_TEXT); verifyAllPreferencesVisible(true); - verify(mScreenTimePreference).setTimeSummary("Less than a minute"); - verify(mScreenTimePreference).setAnomalyHint(TEST_ANOMALY_HINT_TEXT); - verify(mBackgroundTimePreference, never()).setAnomalyHint(anyString()); + verify(mScreenTimePreference).setSummary("Less than a minute"); + verify(mScreenTimePreference).setHint(TEST_ANOMALY_HINT_TEXT); + verify(mBackgroundTimePreference, never()).setHint(anyString()); } private void verifySetPrefToVisible(Preference pref, boolean isVisible) { diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java index c4cbb988ae6..7ad7c491239 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java @@ -67,7 +67,7 @@ public final class BatteryUsageBreakdownControllerTest { @Mock private PreferenceGroup mRootPreferenceGroup; @Mock private Drawable mDrawable; @Mock private BatteryHistEntry mBatteryHistEntry; - @Mock private AnomalyAppItemPreference mAnomalyAppItemPreference; + @Mock private PowerGaugePreference mPowerGaugePreference; private Context mContext; private FakeFeatureFactory mFeatureFactory; @@ -131,13 +131,13 @@ public final class BatteryUsageBreakdownControllerTest { BatteryDiffEntry.sResourceCache.put( "fakeBatteryDiffEntryKey", new BatteryEntry.NameAndIcon("fakeName", /* icon= */ null, /* iconId= */ 1)); - doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).findPreference(PREF_KEY); + doReturn(mPowerGaugePreference).when(mRootPreferenceGroup).findPreference(PREF_KEY); } @Test public void onDestroy_clearPreferenceCacheAndPreferenceGroupRemoveAll() { // Ensures the testing environment is correct. - mBatteryUsageBreakdownController.mPreferenceCache.put(PREF_KEY, mAnomalyAppItemPreference); + mBatteryUsageBreakdownController.mPreferenceCache.put(PREF_KEY, mPowerGaugePreference); assertThat(mBatteryUsageBreakdownController.mPreferenceCache).hasSize(1); mBatteryUsageBreakdownController.onDestroy(); @@ -204,25 +204,25 @@ public final class BatteryUsageBreakdownControllerTest { @Test public void removeAndCacheAllUnusedPreferences_removePref_buildCacheAndRemoveAllPreference() { doReturn(1).when(mRootPreferenceGroup).getPreferenceCount(); - doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).getPreference(0); + doReturn(mPowerGaugePreference).when(mRootPreferenceGroup).getPreference(0); doReturn(PREF_KEY2).when(mBatteryHistEntry).getKey(); - doReturn(PREF_KEY).when(mAnomalyAppItemPreference).getKey(); + doReturn(PREF_KEY).when(mPowerGaugePreference).getKey(); // Ensures the testing data is correct. assertThat(mBatteryUsageBreakdownController.mPreferenceCache).isEmpty(); mBatteryUsageBreakdownController.removeAndCacheAllUnusedPreferences(); assertThat(mBatteryUsageBreakdownController.mPreferenceCache.get(PREF_KEY)) - .isEqualTo(mAnomalyAppItemPreference); - verify(mRootPreferenceGroup).removePreference(mAnomalyAppItemPreference); + .isEqualTo(mPowerGaugePreference); + verify(mRootPreferenceGroup).removePreference(mPowerGaugePreference); } @Test public void removeAndCacheAllUnusedPreferences_keepPref_KeepAllPreference() { doReturn(1).when(mRootPreferenceGroup).getPreferenceCount(); - doReturn(mAnomalyAppItemPreference).when(mRootPreferenceGroup).getPreference(0); + doReturn(mPowerGaugePreference).when(mRootPreferenceGroup).getPreference(0); doReturn(PREF_KEY).when(mBatteryDiffEntry).getKey(); - doReturn(PREF_KEY).when(mAnomalyAppItemPreference).getKey(); + doReturn(PREF_KEY).when(mPowerGaugePreference).getKey(); // Ensures the testing data is correct. assertThat(mBatteryUsageBreakdownController.mPreferenceCache).isEmpty(); @@ -246,11 +246,11 @@ public final class BatteryUsageBreakdownControllerTest { @Test public void handlePreferenceTreeClick_forAppEntry_returnTrue() { mBatteryDiffEntry.mConsumerType = ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY; - doReturn(mBatteryDiffEntry).when(mAnomalyAppItemPreference).getBatteryDiffEntry(); + doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry(); assertThat( mBatteryUsageBreakdownController.handlePreferenceTreeClick( - mAnomalyAppItemPreference)) + mPowerGaugePreference)) .isTrue(); verify(mMetricsFeatureProvider) .action( @@ -264,11 +264,11 @@ public final class BatteryUsageBreakdownControllerTest { @Test public void handlePreferenceTreeClick_forSystemEntry_returnTrue() { mBatteryDiffEntry.mConsumerType = ConvertUtils.CONSUMER_TYPE_UID_BATTERY; - doReturn(mBatteryDiffEntry).when(mAnomalyAppItemPreference).getBatteryDiffEntry(); + doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry(); assertThat( mBatteryUsageBreakdownController.handlePreferenceTreeClick( - mAnomalyAppItemPreference)) + mPowerGaugePreference)) .isTrue(); verify(mMetricsFeatureProvider) .action( diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreferenceTest.java index f64ef495aeb..0bad0a0943c 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreferenceTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PowerGaugePreferenceTest.java @@ -19,19 +19,20 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.graphics.drawable.Drawable; -import android.graphics.drawable.VectorDrawable; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; -import android.widget.TextView; +import android.widget.Space; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; +import com.android.settingslib.widget.SettingsThemeHelper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @@ -48,17 +49,17 @@ public class PowerGaugePreferenceTest { private View mWidgetView; private PreferenceViewHolder mPreferenceViewHolder; + @Mock Drawable mMockIcon; + @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; + mPowerGaugePreference = new PowerGaugePreference(mContext); mRootView = LayoutInflater.from(mContext) - .inflate( - com.android.settingslib.widget.preference.app.R.layout - .preference_app, - null); + .inflate(mPowerGaugePreference.getLayoutResource(), null); mWidgetView = LayoutInflater.from(mContext).inflate(R.layout.preference_widget_summary, null); final LinearLayout widgetFrame = mRootView.findViewById(android.R.id.widget_frame); @@ -66,31 +67,56 @@ public class PowerGaugePreferenceTest { widgetFrame.addView(mWidgetView); mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(mRootView); - mPowerGaugePreference = new PowerGaugePreference(mContext); assertThat(mPowerGaugePreference.getLayoutResource()) - .isEqualTo(com.android.settingslib.widget.preference.app.R.layout.preference_app); + .isEqualTo( + SettingsThemeHelper.isExpressiveTheme(mContext) + ? R.layout.expressive_warning_frame_preference + : R.layout.warning_frame_preference); } @Test - public void testOnBindViewHolder_showAnomaly_bindAnomalyIcon() { - mPowerGaugePreference.shouldShowAnomalyIcon(true); + public void testOnBindViewHolder_showHint_hasHintChip() { + mPowerGaugePreference.setHint("Hint Text"); + mPowerGaugePreference.setIcon(mMockIcon); mPowerGaugePreference.onBindViewHolder(mPreferenceViewHolder); - TextView widgetSummary = (TextView) mPreferenceViewHolder.findViewById(R.id.widget_summary); - final Drawable[] drawables = widgetSummary.getCompoundDrawablesRelative(); + final LinearLayout warningChipFrame = + (LinearLayout) mPreferenceViewHolder.findViewById(R.id.warning_chip_frame); + final Space warningPaddingPlaceHolder = + warningChipFrame.findViewById(R.id.warning_padding_placeholder); - assertThat(drawables[0]).isInstanceOf(VectorDrawable.class); + assertThat(warningChipFrame.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(warningPaddingPlaceHolder.getVisibility()).isEqualTo(View.VISIBLE); } @Test - public void testOnBindViewHolder_notShowAnomaly_bindAnomalyIcon() { - mPowerGaugePreference.shouldShowAnomalyIcon(false); + public void testOnBindViewHolder_emptyHintText_withoutHintChip() { + mPowerGaugePreference.setHint(""); + mPowerGaugePreference.setIcon(mMockIcon); mPowerGaugePreference.onBindViewHolder(mPreferenceViewHolder); - TextView widgetSummary = (TextView) mPreferenceViewHolder.findViewById(R.id.widget_summary); - final Drawable[] drawables = widgetSummary.getCompoundDrawablesRelative(); + final LinearLayout warningChipFrame = + (LinearLayout) mPreferenceViewHolder.findViewById(R.id.warning_chip_frame); + final Space warningPaddingPlaceholder = + warningChipFrame.findViewById(R.id.warning_padding_placeholder); - assertThat(drawables[0]).isNull(); + assertThat(warningChipFrame.getVisibility()).isEqualTo(View.GONE); + assertThat(warningPaddingPlaceholder.getVisibility()).isEqualTo(View.VISIBLE); + } + + @Test + public void testOnBindViewHolder_noAppIconWithHintText_hasChipWithoutPaddingPlaceholder() { + mPowerGaugePreference.setHint("Anomaly Hint Text"); + mPowerGaugePreference.setIcon(null); + mPowerGaugePreference.onBindViewHolder(mPreferenceViewHolder); + + final LinearLayout warningChipFrame = + (LinearLayout) mPreferenceViewHolder.findViewById(R.id.warning_chip_frame); + final Space warningPaddingPlaceHolder = + warningChipFrame.findViewById(R.id.warning_padding_placeholder); + + assertThat(warningChipFrame.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(warningPaddingPlaceHolder.getVisibility()).isEqualTo(View.GONE); } @Test diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardControllerTest.java index 6dca4fc32f4..676f84d7a00 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardControllerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/DndConditionalCardControllerTest.java @@ -102,7 +102,7 @@ public class DndConditionalCardControllerTest { private ZenModeConfig getMutedAllConfig() { final ZenModeConfig config = new ZenModeConfig(); config.applyNotificationPolicy(new NotificationManager.Policy(0, 0, 0)); - config.areChannelsBypassingDnd = false; + config.hasPriorityChannels = false; return config; } } diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java index 0fc915f601f..758168268e2 100644 --- a/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java @@ -26,10 +26,10 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; +import android.app.Dialog; import android.os.Bundle; import android.window.OnBackInvokedDispatcher; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; @@ -92,17 +92,17 @@ public class LocaleDialogFragmentTest { @Test public void onBackInvoked_dialogIsStillDisplaying() { mDialogFragment.setBackDispatcher(mOnBackInvokedDispatcher); - AlertDialog alertDialog = (AlertDialog) mDialogFragment.onCreateDialog(null); - alertDialog.show(); - assertThat(alertDialog).isNotNull(); - assertThat(alertDialog.isShowing()).isTrue(); + Dialog dialog = mDialogFragment.onCreateDialog(null); + dialog.show(); + assertThat(dialog).isNotNull(); + assertThat(dialog.isShowing()).isTrue(); mOnBackInvokedDispatcher.registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()); mDialogFragment.getBackInvokedCallback().onBackInvoked(); - assertThat(alertDialog.isShowing()).isTrue(); + assertThat(dialog.isShowing()).isTrue(); } } diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java index 10115399cfd..4272afe8eba 100644 --- a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java @@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Activity; +import android.app.Dialog; import android.app.IActivityManager; import android.content.Context; import android.content.DialogInterface; @@ -53,10 +54,10 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.preference.Preference; import androidx.test.core.app.ApplicationProvider; import com.android.internal.app.LocaleStore; @@ -78,6 +79,7 @@ import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowDialog; import org.robolectric.shadows.ShadowLooper; import org.robolectric.util.ReflectionHelpers; @@ -87,6 +89,7 @@ import java.util.Locale; @RunWith(RobolectricTestRunner.class) @Config(shadows = { + ShadowDialog.class, ShadowAlertDialogCompat.class, ShadowActivityManager.class, com.android.settings.testutils.shadow.ShadowFragment.class, @@ -143,6 +146,8 @@ public class LocaleListEditorTest { private ImageView mDragHandle; @Mock private NotificationController mNotificationController; + @Mock + private Preference mAddLanguagePreference; @Rule public final CheckFlagsRule mCheckFlagsRule = @@ -166,6 +171,8 @@ public class LocaleListEditorTest { context.getSystemService(Context.USER_SERVICE)); ReflectionHelpers.setField(mLocaleListEditor, "mAdapter", mAdapter); ReflectionHelpers.setField(mLocaleListEditor, "mAddLanguage", mAddLanguage); + ReflectionHelpers.setField(mLocaleListEditor, "mAddLanguagePreference", + mAddLanguagePreference); ReflectionHelpers.setField(mLocaleListEditor, "mFragmentManager", mFragmentManager); ReflectionHelpers.setField(mLocaleListEditor, "mMetricsFeatureProvider", mMetricsFeatureProvider); @@ -178,7 +185,7 @@ public class LocaleListEditorTest { ReflectionHelpers.setField(mLocaleListEditor, "mRemoveMode", false); ReflectionHelpers.setField(mLocaleListEditor, "mShowingRemoveDialog", false); ReflectionHelpers.setField(mLocaleListEditor, "mLocaleAdditionMode", false); - ShadowAlertDialogCompat.reset(); + ShadowDialog.reset(); } @Test @@ -209,14 +216,13 @@ public class LocaleListEditorTest { //launch dialog mLocaleListEditor.showRemoveLocaleWarningDialog(); - final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + final Dialog dialog = ShadowDialog.getLatestDialog(); assertThat(dialog).isNotNull(); - final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog); - - assertThat(shadowDialog.getTitle()).isEqualTo( - mContext.getString(R.string.dlg_remove_locales_error_title)); + TextView dialogTitle = dialog.findViewById(R.id.dialog_with_icon_title); + assertThat(dialogTitle.getText().toString()) + .isEqualTo(mContext.getString(R.string.dlg_remove_locales_error_title)); } @Test @@ -231,14 +237,13 @@ public class LocaleListEditorTest { //launch dialog mLocaleListEditor.showRemoveLocaleWarningDialog(); - final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + final Dialog dialog = ShadowDialog.getLatestDialog(); assertThat(dialog).isNotNull(); - final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog); - - assertThat(shadowDialog.getMessage()).isEqualTo( - mContext.getString(R.string.dlg_remove_locales_message)); + TextView dialogMessage = dialog.findViewById(R.id.dialog_with_icon_message); + assertThat(dialogMessage.getText().toString()) + .isEqualTo(mContext.getString(R.string.dlg_remove_locales_message)); } @Test @@ -253,13 +258,12 @@ public class LocaleListEditorTest { //launch dialog mLocaleListEditor.showRemoveLocaleWarningDialog(); - final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + final Dialog dialog = ShadowDialog.getLatestDialog(); assertThat(dialog).isNotNull(); - final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog); - - assertThat(shadowDialog.getMessage()).isNull(); + TextView dialogMessage = dialog.findViewById(R.id.dialog_with_icon_message); + assertThat(dialogMessage.getText().isEmpty()).isTrue(); } @Test @@ -280,12 +284,12 @@ public class LocaleListEditorTest { //launch the first dialog mLocaleListEditor.showRemoveLocaleWarningDialog(); - final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + final Dialog dialog = ShadowDialog.getLatestDialog(); assertThat(dialog).isNotNull(); // click the remove button - dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); + dialog.findViewById(R.id.button_ok).performClick(); ShadowLooper.idleMainLooper(); assertThat(dialog.isShowing()).isFalse(); diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java index 458000292df..c1811915a90 100644 --- a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java @@ -21,14 +21,12 @@ import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNI import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; -import android.content.DialogInterface; import android.net.ConnectivitySettingsManager; import android.view.LayoutInflater; import android.view.View; @@ -88,31 +86,31 @@ public class PrivateDnsModeDialogPreferenceTest { } @Test - public void testOnCheckedChanged_dnsModeOff_disableEditText() { + public void onCheckedChanged_dnsModeOff_disableHostnameText() { mPreference.onCheckedChanged(null, R.id.private_dns_mode_off); assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_OFF); - assertThat(mPreference.mEditText.isEnabled()).isFalse(); + assertThat(mPreference.mHostnameText.isEnabled()).isFalse(); } @Test - public void testOnCheckedChanged_dnsModeOpportunistic_disableEditText() { + public void onCheckedChanged_dnsModeOpportunistic_disableHostnameText() { mPreference.onCheckedChanged(null, R.id.private_dns_mode_opportunistic); assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC); - assertThat(mPreference.mEditText.isEnabled()).isFalse(); + assertThat(mPreference.mHostnameText.isEnabled()).isFalse(); } @Test - public void testOnCheckedChanged_dnsModeProvider_enableEditText() { + public void onCheckedChanged_dnsModeProvider_enableHostnameText() { mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); - assertThat(mPreference.mEditText.isEnabled()).isTrue(); + assertThat(mPreference.mHostnameText.isEnabled()).isTrue(); } @Test - public void testOnBindDialogView_containsCorrectData() { + public void onBindDialogView_containsCorrectData() { // Don't set settings to the default value ("opportunistic") as that // risks masking failure to read the mode from settings. ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF); @@ -123,57 +121,74 @@ public class PrivateDnsModeDialogPreferenceTest { new LinearLayout(mContext), false); mPreference.onBindDialogView(view); - assertThat(mPreference.mEditText.getText().toString()).isEqualTo(HOST_NAME); + assertThat(mPreference.mHostnameText.getText().toString()).isEqualTo(HOST_NAME); assertThat(mPreference.mRadioGroup.getCheckedRadioButtonId()).isEqualTo( R.id.private_dns_mode_off); } @Test - public void testOnCheckedChanged_switchMode_saveButtonHasCorrectState() { - final String[] INVALID_HOST_NAMES = new String[] { - INVALID_HOST_NAME, - "2001:db8::53", // IPv6 string literal - "192.168.1.1", // IPv4 string literal - }; + public void doSaveButton_changeToOffMode_saveData() { + // Set the default settings to OPPORTUNISTIC + ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OPPORTUNISTIC); - for (String invalid : INVALID_HOST_NAMES) { - // Set invalid hostname - mPreference.mEditText.setText(invalid); - - mPreference.onCheckedChanged(null, R.id.private_dns_mode_off); - assertWithMessage("off: " + invalid).that(mSaveButton.isEnabled()).isTrue(); - - mPreference.onCheckedChanged(null, R.id.private_dns_mode_opportunistic); - assertWithMessage("opportunistic: " + invalid).that(mSaveButton.isEnabled()).isTrue(); - - mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); - assertWithMessage("provider: " + invalid).that(mSaveButton.isEnabled()).isFalse(); - } - } - - @Test - public void testOnClick_positiveButtonClicked_saveData() { - // Set the default settings to OFF - ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF); - - mPreference.mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC; - mPreference.onClick(null, DialogInterface.BUTTON_POSITIVE); + mPreference.mMode = PRIVATE_DNS_MODE_OFF; + mPreference.doSaveButton(); // Change to OPPORTUNISTIC - assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)).isEqualTo( - PRIVATE_DNS_MODE_OPPORTUNISTIC); + assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)) + .isEqualTo(PRIVATE_DNS_MODE_OFF); } @Test - public void testOnClick_negativeButtonClicked_doNothing() { + public void doSaveButton_changeToOpportunisticMode_saveData() { // Set the default settings to OFF ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF); mPreference.mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC; - mPreference.onClick(null, DialogInterface.BUTTON_NEGATIVE); + mPreference.doSaveButton(); - // Still equal to OFF - assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)).isEqualTo( - PRIVATE_DNS_MODE_OFF); + // Change to OPPORTUNISTIC + assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)) + .isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC); + } + + @Test + public void doSaveButton_changeToProviderHostnameMode_saveData() { + // Set the default settings to OFF + ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OFF); + + mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); + mPreference.mHostnameText.setText(HOST_NAME); + mPreference.doSaveButton(); + + // Change to PROVIDER_HOSTNAME + assertThat(ConnectivitySettingsManager.getPrivateDnsMode(mContext)) + .isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + assertThat(ConnectivitySettingsManager.getPrivateDnsHostname(mContext)) + .isEqualTo(HOST_NAME); + } + + @Test + public void doSaveButton_providerHostnameIsEmpty_setHostnameError() { + ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + ConnectivitySettingsManager.setPrivateDnsHostname(mContext, HOST_NAME); + mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); + + mPreference.mHostnameText.setText(""); + mPreference.doSaveButton(); + + assertThat(mPreference.mHostnameLayout.isErrorEnabled()).isTrue(); + } + + @Test + public void doSaveButton_providerHostnameIsInvalid_setHostnameError() { + ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + ConnectivitySettingsManager.setPrivateDnsHostname(mContext, HOST_NAME); + mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); + + mPreference.mHostnameText.setText(INVALID_HOST_NAME); + mPreference.doSaveButton(); + + assertThat(mPreference.mHostnameLayout.isErrorEnabled()).isTrue(); } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java index 42aa498c1dc..f0c2369d0a6 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java @@ -85,7 +85,7 @@ public class ZenModeSetCalendarPreferenceControllerTest { } @Test - @EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI}) + @EnableFlags(Flags.FLAG_MODES_UI) public void updateEventMode_updatesConditionAndTriggerDescription() { ZenMode mode = new TestModeBuilder() .setPackage(SystemZenRules.PACKAGE_ANDROID) diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java index c378e9de427..b446d716b48 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java @@ -80,7 +80,7 @@ public class ZenModeSetSchedulePreferenceControllerTest { } @Test - @EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI}) + @EnableFlags(Flags.FLAG_MODES_UI) public void updateScheduleRule_updatesConditionAndTriggerDescription() { ZenMode mode = new TestModeBuilder() .setPackage(SystemZenRules.PACKAGE_ANDROID) diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java index 63da3c41ea4..120390d39f3 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBackendTest.java @@ -213,11 +213,7 @@ public class ZenModeBackendTest { mBackend.saveConversationSenders(CONVERSATION_SENDERS_NONE); ArgumentCaptor captor = ArgumentCaptor.forClass(Policy.class); - if (android.app.Flags.modesApi()) { - verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true)); - } else { - verify(mNotificationManager).setNotificationPolicy(captor.capture()); - } + verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true)); Policy expected = new Policy( PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, @@ -241,11 +237,7 @@ public class ZenModeBackendTest { mBackend.saveConversationSenders(CONVERSATION_SENDERS_ANYONE); ArgumentCaptor captor = ArgumentCaptor.forClass(Policy.class); - if (android.app.Flags.modesApi()) { - verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true)); - } else { - verify(mNotificationManager).setNotificationPolicy(captor.capture()); - } + verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true)); Policy expected = new Policy(PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, @@ -270,11 +262,7 @@ public class ZenModeBackendTest { mBackend.saveSenders(PRIORITY_CATEGORY_CALLS, PRIORITY_SENDERS_ANY); ArgumentCaptor captor = ArgumentCaptor.forClass(Policy.class); - if (android.app.Flags.modesApi()) { - verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true)); - } else { - verify(mNotificationManager).setNotificationPolicy(captor.capture()); - } + verify(mNotificationManager).setNotificationPolicy(captor.capture(), eq(true)); Policy expected = new Policy(PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_ALARMS, diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java index 05c3603b1ca..ef0b862b412 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java @@ -107,7 +107,7 @@ public class ZenModeEventRuleSettingsTest { } @Test - @EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI}) + @EnableFlags(Flags.FLAG_MODES_UI) public void updateEventRule_updatesConditionAndTriggerDescription() { mFragment.setBackend(mBackend); mFragment.mId = "id"; diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java index 90e44e6e193..bb102c0048f 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java @@ -107,7 +107,7 @@ public class ZenModeScheduleRuleSettingsTest { } @Test - @EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI}) + @EnableFlags(Flags.FLAG_MODES_UI) public void updateScheduleRule_updatesConditionAndTriggerDescription() { mFragment.setBackend(mBackend); mFragment.mId = "id"; diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeSliceBuilderTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeSliceBuilderTest.java index 3f9e4864a0c..ddc3d8095a9 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeSliceBuilderTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeSliceBuilderTest.java @@ -117,11 +117,7 @@ public class ZenModeSliceBuilderTest { ZenModeSliceBuilder.handleUriChange(mContext, intent); - if (android.app.Flags.modesApi()) { - verify(mNm).setZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), any(), any(), eq(true)); - } else { - verify(mNm).setZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), any(), any()); - } + verify(mNm).setZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), any(), any(), eq(true)); } @Test @@ -131,10 +127,6 @@ public class ZenModeSliceBuilderTest { ZenModeSliceBuilder.handleUriChange(mContext, intent); - if (android.app.Flags.modesApi()) { - verify(mNm).setZenMode(eq(ZEN_MODE_OFF), any(), any(), eq(true)); - } else { - verify(mNm).setZenMode(eq(ZEN_MODE_OFF), any(), any()); - } + verify(mNm).setZenMode(eq(ZEN_MODE_OFF), any(), any(), eq(true)); } } diff --git a/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt index 8524ef462fd..ed40a8c87ac 100644 --- a/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt @@ -17,6 +17,7 @@ package com.android.settings.deviceinfo import android.content.Context +import android.os.UserManager import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.telephony.TelephonyManager @@ -25,30 +26,39 @@ import androidx.preference.PreferenceCategory import androidx.preference.PreferenceManager import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.settings.R +import com.android.settings.core.BasePreferenceController +import com.android.settings.network.SubscriptionUtil +import com.android.settingslib.Utils import com.google.common.truth.Truth.assertThat +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.MockitoSession import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy +import org.mockito.kotlin.stub import org.mockito.kotlin.verify import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness @RunWith(AndroidJUnit4::class) class PhoneNumberPreferenceControllerTest { + private lateinit var mockSession: MockitoSession + private val mockUserManager = mock() private val mockTelephonyManager = mock() private val mockSubscriptionManager = mock() private val context: Context = spy(ApplicationProvider.getApplicationContext()) { - on { getSystemService(SubscriptionManager::class.java) } doReturn - mockSubscriptionManager - + on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager + on { getSystemService(UserManager::class.java) } doReturn mockUserManager } private val subscriptionInfo = mock() @@ -61,6 +71,20 @@ class PhoneNumberPreferenceControllerTest { @Before fun setup() { + mockSession = + ExtendedMockito.mockitoSession() + .mockStatic(SubscriptionUtil::class.java) + .mockStatic(Utils::class.java) + .strictness(Strictness.LENIENT) + .startMocking() + + // By default, available + whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) + whenever(Utils.isWifiOnly(context)).thenReturn(false) + mockUserManager.stub { + on { isAdminUser } doReturn true + } + preference.setKey(controller.preferenceKey) preference.isVisible = true preferenceScreen.addPreference(preference) @@ -70,6 +94,11 @@ class PhoneNumberPreferenceControllerTest { doReturn(secondPreference).whenever(controller).createNewPreference(context) } + @After + fun teardown() { + mockSession.finishMocking() + } + @Test fun displayPreference_multiSim_shouldAddSecondPreference() { whenever(mockTelephonyManager.phoneCount).thenReturn(2) @@ -132,4 +161,37 @@ class PhoneNumberPreferenceControllerTest { verify(preference).summary = context.getString(R.string.device_info_not_available) } + + @Test + fun getAvailabilityStatus_simHardwareVisible_userAdmin_notWifiOnly_displayed() { + // Use defaults from setup() + val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE) + } + + @Test + fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notWifiOnly_notDisplayed() { + whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false) + + val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE) + } + + @Test + fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notWifiOnly_notDisplayed() { + mockUserManager.stub { + on { isAdminUser } doReturn false + } + + val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER) + } + + @Test + fun getAvailabilityStatus_simHardwareVisible_userAdmin_wifiOnly_notDisplayed() { + whenever(Utils.isWifiOnly(context)).thenReturn(true) + + val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE) + } } diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt index f56c0c4b351..a46b71033b6 100644 --- a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt @@ -17,6 +17,7 @@ package com.android.settings.network.telephony import android.content.Context +import android.os.UserManager import androidx.lifecycle.testing.TestLifecycleOwner import androidx.preference.Preference import androidx.preference.PreferenceManager @@ -26,6 +27,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.settings.R import com.android.settings.core.BasePreferenceController import com.android.settings.network.SubscriptionUtil +import com.android.settingslib.Utils import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flowOf @@ -37,6 +39,7 @@ import org.junit.runner.RunWith import org.mockito.MockitoSession import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock +import org.mockito.kotlin.spy import org.mockito.kotlin.stub import org.mockito.kotlin.whenever import org.mockito.quality.Strictness @@ -45,9 +48,14 @@ import org.mockito.quality.Strictness class MobileNetworkPhoneNumberPreferenceControllerTest { private lateinit var mockSession: MockitoSession - private val context: Context = ApplicationProvider.getApplicationContext() + private val mockUserManager = mock() private val mockSubscriptionRepository = mock() + private val context: Context = + spy(ApplicationProvider.getApplicationContext()) { + on { getSystemService(UserManager::class.java) } doReturn mockUserManager + } + private val controller = MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository) private val preference = Preference(context).apply { key = TEST_KEY } @@ -58,9 +66,17 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { mockSession = ExtendedMockito.mockitoSession() .mockStatic(SubscriptionUtil::class.java) + .mockStatic(Utils::class.java) .strictness(Strictness.LENIENT) .startMocking() + // By default, available + whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) + whenever(Utils.isWifiOnly(context)).thenReturn(false) + mockUserManager.stub { + on { isAdminUser } doReturn true + } + preferenceScreen.addPreference(preference) controller.init(SUB_ID) controller.displayPreference(preferenceScreen) @@ -73,7 +89,6 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { @Test fun onViewCreated_cannotGetPhoneNumber_displayUnknown() = runBlocking { - whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) mockSubscriptionRepository.stub { on { phoneNumberFlow(SUB_ID) } doReturn flowOf(null) } @@ -86,7 +101,6 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { @Test fun onViewCreated_canGetPhoneNumber_displayPhoneNumber() = runBlocking { - whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) mockSubscriptionRepository.stub { on { phoneNumberFlow(SUB_ID) } doReturn flowOf(PHONE_NUMBER) } @@ -98,11 +112,35 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { } @Test - fun getAvailabilityStatus_notSimHardwareVisible() { + fun getAvailabilityStatus_simHardwareVisible_userAdmin_notWifiOnly_displayed() { + // Use defaults from setup() + val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE) + } + + @Test + fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notWifiOnly_notDisplayed() { whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false) val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE) + } + @Test + fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notWifiOnly_notDisplayed() { + mockUserManager.stub { + on { isAdminUser } doReturn false + } + + val availabilityStatus = controller.availabilityStatus + assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER) + } + + @Test + fun getAvailabilityStatus_simHardwareVisible_userAdmin_wifiOnly_notDisplayed() { + whenever(Utils.isWifiOnly(context)).thenReturn(true) + + val availabilityStatus = controller.availabilityStatus assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE) } diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java index e488792d55b..bcfaa3d78e1 100644 --- a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java @@ -28,14 +28,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; -import android.app.Flags; import android.app.NotificationManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; @@ -50,7 +48,6 @@ import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -188,7 +185,6 @@ public class ApprovalPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_MODES_API) public void disable() { when(mNm.isNotificationPolicyAccessGrantedForPackage(anyString())).thenReturn(false); mController.disable(mCn); diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java index 12af7726a42..623b20947cf 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java @@ -22,6 +22,8 @@ import static com.android.settings.connecteddevice.display.ExternalDisplayPrefer import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SETTINGS_RESOURCE; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.EXTERNAL_DISPLAY_SIZE_SUMMARY_RESOURCE; import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.PREVIOUSLY_SHOWN_LIST_KEY; +import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.displayListDisplayCategoryKey; +import static com.android.settings.connecteddevice.display.ExternalDisplayPreferenceFragment.resolutionRotationPreferenceKey; import static com.android.settings.flags.Flags.FLAG_DISPLAY_SIZE_CONNECTED_DISPLAY_SETTING; import static com.android.settings.flags.Flags.FLAG_DISPLAY_TOPOLOGY_PANE_IN_DISPLAY_LIST; import static com.android.settingslib.widget.FooterPreference.KEY_FOOTER; @@ -79,6 +81,19 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa assertThat(mPreferenceIdFromResource).isEqualTo(EXTERNAL_DISPLAY_SETTINGS_RESOURCE); } + private void assertDisplayList(boolean present, int displayId) { + // In display list fragment, there is a combined resolution/rotation preference key. + var category = mPreferenceScreen.findPreference(displayListDisplayCategoryKey(displayId)); + var pref = mPreferenceScreen.findPreference(resolutionRotationPreferenceKey(displayId)); + if (present) { + assertThat(category).isNotNull(); + assertThat(pref).isNotNull(); + } else { + assertThat(category).isNull(); + assertThat(pref).isNull(); + } + } + @Test @UiThreadTest public void testShowDisplayList() { @@ -89,19 +104,26 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa fragment.onSaveInstanceStateCallback(outState); assertThat(outState.getBoolean(PREVIOUSLY_SHOWN_LIST_KEY)).isFalse(); assertThat(mHandler.getPendingMessages().size()).isEqualTo(1); - PreferenceCategory pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(pref).isNull(); + + // Combined resolution/refresh rate are not available in displays list because the pane is + // disabled (v1 UI). + assertDisplayList(false, EXTERNAL_DISPLAY_ID); + assertDisplayList(false, OVERLAY_DISPLAY_ID); + // Individual resolution preference is not available in displays list. + assertThat(mPreferenceScreen.findPreference( + PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key)) + .isNull(); + verify(mMockedInjector, never()).getAllDisplays(); mHandler.flush(); assertThat(mHandler.getPendingMessages().size()).isEqualTo(0); verify(mMockedInjector).getAllDisplays(); - pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(pref).isNotNull(); - assertThat(pref.getPreferenceCount()).isEqualTo(2); + assertDisplayList(true, EXTERNAL_DISPLAY_ID); + assertDisplayList(true, OVERLAY_DISPLAY_ID); fragment.onSaveInstanceStateCallback(outState); assertThat(outState.getBoolean(PREVIOUSLY_SHOWN_LIST_KEY)).isTrue(); - pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAY_TOPOLOGY.key); + Preference pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAY_TOPOLOGY.key); assertThat(pref).isNull(); pref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key); @@ -122,8 +144,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa pref = mPreferenceScreen.findPreference(PrefBasics.MIRROR.key); assertThat(pref).isNotNull(); - pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(pref).isNull(); + assertDisplayList(false, mDisplays[1].getDisplayId()); PreferenceCategory listPref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key); @@ -148,11 +169,10 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa pref = mPreferenceScreen.findPreference(PrefBasics.MIRROR.key); assertThat(pref).isNull(); - PreferenceCategory listPref = - mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(listPref).isNull(); + assertDisplayList(false, EXTERNAL_DISPLAY_ID); + assertDisplayList(false, OVERLAY_DISPLAY_ID); - listPref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key); + var listPref = mPreferenceScreen.findPreference(PrefBasics.BUILTIN_DISPLAY_LIST.key); assertThat(listPref).isNull(); } @@ -161,19 +181,23 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa public void testLaunchDisplaySettingFromList() { initFragment(); mHandler.flush(); - PreferenceCategory pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(pref).isNotNull(); - var display1Category = (PreferenceCategory) pref.getPreference(0); + assertDisplayList(true, EXTERNAL_DISPLAY_ID); + assertDisplayList(true, OVERLAY_DISPLAY_ID); + PreferenceCategory display1Category = mPreferenceScreen.findPreference( + displayListDisplayCategoryKey(EXTERNAL_DISPLAY_ID)); var display1Pref = (DisplayPreference) display1Category.getPreference(0); - var display2Category = (PreferenceCategory) pref.getPreference(1); + PreferenceCategory display2Category = mPreferenceScreen.findPreference( + displayListDisplayCategoryKey(OVERLAY_DISPLAY_ID)); var display2Pref = (DisplayPreference) display2Category.getPreference(0); - assertThat(display1Pref.getKey()).isEqualTo("display_id_" + 1); + assertThat(display1Pref.getKey()).isEqualTo( + resolutionRotationPreferenceKey(EXTERNAL_DISPLAY_ID)); assertThat("" + display1Category.getTitle()).isEqualTo("HDMI"); assertThat("" + display1Pref.getSummary()).isEqualTo("1920 x 1080"); display1Pref.onPreferenceClick(display1Pref); assertThat(mDisplayIdArg).isEqualTo(1); verify(mMockedMetricsLogger).writePreferenceClickMetric(display1Pref); - assertThat(display2Pref.getKey()).isEqualTo("display_id_" + 2); + assertThat(display2Pref.getKey()).isEqualTo( + resolutionRotationPreferenceKey(OVERLAY_DISPLAY_ID)); assertThat("" + display2Category.getTitle()).isEqualTo("Overlay #1"); assertThat("" + display2Pref.getSummary()).isEqualTo("1240 x 780"); display2Pref.onPreferenceClick(display2Pref); @@ -190,9 +214,12 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa // Only one display available doReturn(new Display[] {mDisplays[1]}).when(mMockedInjector).getAllDisplays(); mHandler.flush(); - PreferenceCategory pref = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(pref).isNotNull(); - assertThat(pref.getPreferenceCount()).isEqualTo(1); + int attachedId = mDisplays[1].getDisplayId(); + assertDisplayList(true, attachedId); + assertThat(mPreferenceScreen.findPreference( + resolutionRotationPreferenceKey(attachedId))) + .isNotNull(); + assertDisplayList(false, mDisplays[2].getDisplayId()); } @Test @@ -205,8 +232,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa // Init initFragment(); mHandler.flush(); - PreferenceCategory list = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(list).isNull(); + assertDisplayList(false, mDisplays[1].getDisplayId()); var pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key); assertThat(pref).isNotNull(); pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key); @@ -227,8 +253,8 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa // Init initFragment(); mHandler.flush(); - PreferenceCategory list = mPreferenceScreen.findPreference(PrefBasics.DISPLAYS_LIST.key); - assertThat(list).isNull(); + assertDisplayList(false, mDisplays[1].getDisplayId()); + assertDisplayList(false, mDisplays[2].getDisplayId()); var pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_RESOLUTION.key); assertThat(pref).isNotNull(); pref = mPreferenceScreen.findPreference(PrefBasics.EXTERNAL_DISPLAY_ROTATION.key); diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java index ea76118c5a2..fcc3daa4efc 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java @@ -49,6 +49,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; public class ExternalDisplayTestBase { + static final int EXTERNAL_DISPLAY_ID = 1; + static final int OVERLAY_DISPLAY_ID = 2; + @Mock ExternalDisplaySettingsConfiguration.Injector mMockedInjector; @Mock @@ -115,7 +118,7 @@ public class ExternalDisplayTestBase { } Display createExternalDisplay() throws RemoteException { - int displayId = 1; + int displayId = EXTERNAL_DISPLAY_ID; var displayInfo = new DisplayInfo(); doReturn(displayInfo).when(mMockedIDisplayManager).getDisplayInfo(displayId); displayInfo.displayId = displayId; @@ -134,7 +137,7 @@ public class ExternalDisplayTestBase { } Display createOverlayDisplay() throws RemoteException { - int displayId = 2; + int displayId = OVERLAY_DISPLAY_ID; var displayInfo = new DisplayInfo(); doReturn(displayInfo).when(mMockedIDisplayManager).getDisplayInfo(displayId); displayInfo.displayId = displayId; diff --git a/tests/unit/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java b/tests/unit/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java index 824954da52d..9415d00e98b 100644 --- a/tests/unit/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java +++ b/tests/unit/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java @@ -35,6 +35,7 @@ import androidx.test.annotation.UiThreadTest; import androidx.test.core.app.ApplicationProvider; import com.android.internal.app.LocaleStore; +import com.android.settings.R; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.ResourcesUtils; @@ -82,11 +83,9 @@ public class LocaleDialogFragmentTest { LocaleDialogFragment.LocaleDialogController.DialogContent dialogContent = controller.getDialogContent(); - assertEquals(ResourcesUtils.getResourcesString( - mContext, "button_label_confirmation_of_system_locale_change"), + assertEquals(R.string.button_label_confirmation_of_system_locale_change, dialogContent.mPositiveButton); - assertEquals(ResourcesUtils.getResourcesString(mContext, "cancel"), - dialogContent.mNegativeButton); + assertEquals(R.string.cancel, dialogContent.mNegativeButton); } @Test @@ -99,9 +98,8 @@ public class LocaleDialogFragmentTest { LocaleDialogFragment.LocaleDialogController.DialogContent dialogContent = controller.getDialogContent(); - assertEquals(ResourcesUtils.getResourcesString(mContext, "okay"), - dialogContent.mPositiveButton); - assertTrue(dialogContent.mNegativeButton.isEmpty()); + assertEquals(R.string.okay, dialogContent.mPositiveButton); + assertTrue(dialogContent.mNegativeButton == 0); } @Test