diff --git a/res/layout/user_credential.xml b/res/layout/user_credential.xml index adf26800746..b249795db9d 100644 --- a/res/layout/user_credential.xml +++ b/res/layout/user_credential.xml @@ -22,7 +22,6 @@ android:id="@+id/alias" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceMedium" /> Invalid Network Mode %1$d. Ignore. - + Satellite messaging - + Send and receive text messages by satellite. Included with your account. - + Send and receive text messages by satellite. Not included with your account. + + Send and receive text messages by satellite. Contact your carrier for details. Satellite messaging, satellite connectivity @@ -12565,6 +12567,8 @@ You can text anyone, including emergency services. Your phone will reconnect to a mobile network when available. %1$s may take longer and is available only in some areas. Weather and certain structures may affect your satellite connection. Calling by satellite isn\u2019t available. Emergency calls may still connect.\n\nIt may take some time for account changes to show in Settings. Contact %2$s for details. + + %1$s may take longer and is available only in some areas. Weather and certain structures may affect your satellite connection. Calling by satellite isn\u2019t available. Emergency calls may still connect. Texting with emergency services may not be available in all areas.\n\nIt may take some time for account changes to show in Settings. Contact %2$s for details. More about %1$s @@ -14012,6 +14016,12 @@ Can\'t share audio with %1$s Audio sharing only works with headphones that support LE Audio + + Turn off Audio Sharing + + To pair a new device, turn off Audio Sharing first. + + Turn off Connect to a LE audio stream diff --git a/src/com/android/settings/SettingsApplication.java b/src/com/android/settings/SettingsApplication.java index 9c5671f1027..d924519ad72 100644 --- a/src/com/android/settings/SettingsApplication.java +++ b/src/com/android/settings/SettingsApplication.java @@ -38,6 +38,7 @@ import com.android.settings.flags.Flags; import com.android.settings.fuelgauge.BatterySettingsStorage; import com.android.settings.homepage.SettingsHomepageActivity; import com.android.settings.localepicker.LocaleNotificationDataManager; +import com.android.settings.metrics.SettingsMetricsLogger; import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactoryImpl; import com.android.settings.spa.SettingsSpaEnvironment; diff --git a/src/com/android/settings/SettingsPreferenceBindingFactory.kt b/src/com/android/settings/SettingsPreferenceBindingFactory.kt index b0fa4d98d7b..dbc6c60b267 100644 --- a/src/com/android/settings/SettingsPreferenceBindingFactory.kt +++ b/src/com/android/settings/SettingsPreferenceBindingFactory.kt @@ -17,6 +17,9 @@ package com.android.settings import androidx.preference.Preference +import com.android.settings.restriction.PreferenceRestrictionMixin +import com.android.settings.restriction.getRestrictionEnforcedAdmin +import com.android.settings.restriction.hasBaseUserRestriction import com.android.settingslib.RestrictedPreferenceHelperProvider import com.android.settingslib.metadata.PreferenceHierarchyNode import com.android.settingslib.preference.DefaultPreferenceBindingFactory diff --git a/src/com/android/settings/accessibility/ColorAndMotionFragment.java b/src/com/android/settings/accessibility/ColorAndMotionFragment.java index d487d755201..d5686b8a888 100644 --- a/src/com/android/settings/accessibility/ColorAndMotionFragment.java +++ b/src/com/android/settings/accessibility/ColorAndMotionFragment.java @@ -68,9 +68,6 @@ public class ColorAndMotionFragment extends DashboardFragment { mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED); - mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); - mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); - mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler()); mSettingsContentObserver.registerKeysToObserverCallback(mShortcutFeatureKeys, diff --git a/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt b/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt index 0665e96d5b4..ee962827d6e 100644 --- a/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt +++ b/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt @@ -20,9 +20,9 @@ import android.annotation.DrawableRes import android.app.settings.SettingsEnums.ACTION_REMOVE_ANIMATION import android.content.Context import android.provider.Settings -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_REMOVE_ANIMATION +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObserver diff --git a/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt b/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt index 54b1d9588e2..6d1f883de21 100644 --- a/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt +++ b/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt @@ -22,9 +22,9 @@ import android.os.Vibrator import android.provider.Settings import android.widget.CompoundButton import android.widget.CompoundButton.OnCheckedChangeListener -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_VIBRATION_HAPTICS +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.SettingsStore diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/OWNERS b/src/com/android/settings/applications/specialaccess/notificationaccess/OWNERS index 4338198a458..4628f8c5f64 100644 --- a/src/com/android/settings/applications/specialaccess/notificationaccess/OWNERS +++ b/src/com/android/settings/applications/specialaccess/notificationaccess/OWNERS @@ -1,4 +1 @@ -# Default reviewers for this and subdirectories. -beverlyt@google.com -dsandler@android.com -juliacr@google.com \ No newline at end of file +include platform/frameworks/base:/services/core/java/com/android/server/notification/OWNERS \ No newline at end of file diff --git a/src/com/android/settings/applications/specialaccess/zenaccess/OWNERS b/src/com/android/settings/applications/specialaccess/zenaccess/OWNERS index 9b5f41ef32c..4628f8c5f64 100644 --- a/src/com/android/settings/applications/specialaccess/zenaccess/OWNERS +++ b/src/com/android/settings/applications/specialaccess/zenaccess/OWNERS @@ -1,2 +1 @@ -beverlyt@google.com -juliacr@google.com \ No newline at end of file +include platform/frameworks/base:/services/core/java/com/android/server/notification/OWNERS \ No newline at end of file diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index 5d1c4784b98..226876e8533 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -155,6 +155,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + final boolean isExpressiveStyle = BiometricUtils.isExpressiveStyle(getBaseContext()); if (shouldShowSplitScreenDialog()) { BiometricsSplitScreenDialog @@ -213,28 +214,33 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase mFooterBarMixin = layout.getMixin(FooterBarMixin.class); mFooterBarMixin.setPrimaryButton(getPrimaryFooterButton()); mFooterBarMixin.setSecondaryButton(getSecondaryFooterButton(), true /* usePrimaryStyle */); - mFooterBarMixin.getSecondaryButton().setVisibility( - mHasScrolledToBottom ? View.VISIBLE : View.INVISIBLE); + if (!isExpressiveStyle) { + mFooterBarMixin.getSecondaryButton().setVisibility( + mHasScrolledToBottom ? View.VISIBLE : View.INVISIBLE); + } final RequireScrollMixin requireScrollMixin = layout.getMixin(RequireScrollMixin.class); requireScrollMixin.requireScrollWithButton(this, getPrimaryFooterButton(), getMoreButtonTextRes(), this::onNextButtonClick); - requireScrollMixin.setOnRequireScrollStateChangedListener( - scrollNeeded -> { - boolean enrollmentCompleted = checkMaxEnrolled() != 0; - if (!enrollmentCompleted) { - // Update text of primary button from "More" to "Agree". - final int primaryButtonTextRes = scrollNeeded - ? getMoreButtonTextRes() - : getAgreeButtonTextRes(); - getPrimaryFooterButton().setText(this, primaryButtonTextRes); - } + if (!isExpressiveStyle) { + requireScrollMixin.setOnRequireScrollStateChangedListener( + scrollNeeded -> { + boolean enrollmentCompleted = checkMaxEnrolled() != 0; + if (!enrollmentCompleted) { + // Update text of primary button from "More" to "Agree". + final int primaryButtonTextRes = scrollNeeded + ? getMoreButtonTextRes() + : getAgreeButtonTextRes(); + getPrimaryFooterButton().setText(this, primaryButtonTextRes); + } - // Show secondary button once scroll is completed. - getSecondaryFooterButton().setVisibility( - !scrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE); - mHasScrolledToBottom = !scrollNeeded; - }); + // Show secondary button once scroll is completed. + getSecondaryFooterButton().setVisibility( + !scrollNeeded && !enrollmentCompleted ? View.VISIBLE + : View.INVISIBLE); + mHasScrolledToBottom = !scrollNeeded; + }); + } final boolean isScrollNeeded = requireScrollMixin.isScrollingRequired(); final boolean enrollmentCompleted = checkMaxEnrolled() != 0; diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java index e080ef48905..a4fb7358011 100644 --- a/src/com/android/settings/biometrics/BiometricUtils.java +++ b/src/com/android/settings/biometrics/BiometricUtils.java @@ -50,8 +50,10 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.SetupChooseLockGeneric; +import com.android.settingslib.widget.SettingsThemeHelper; import com.google.android.setupcompat.util.WizardManagerHelper; +import com.google.android.setupdesign.util.ThemeHelper; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -530,6 +532,16 @@ public class BiometricUtils { return ssb.toString(); } + /** + * Check if device is using Expressive Style theme. + * @param context that for applying Expressive Style + * @return true if device using Expressive Style theme, otherwise false. + */ + public static boolean isExpressiveStyle(@NonNull Context context) { + return SettingsThemeHelper.isExpressiveTheme(context) + || ThemeHelper.shouldApplyGlifExpressiveStyle(context); + } + private static String capitalize(final String input) { return Character.toUpperCase(input.charAt(0)) + input.substring(1); } diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index e29096126f9..d5f5cb06854 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -48,6 +48,7 @@ import com.android.settings.widget.GearPreference; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.flags.Flags; import com.android.settingslib.utils.ThreadUtils; import java.lang.annotation.Retention; @@ -93,6 +94,7 @@ public final class BluetoothDevicePreference extends GearPreference { private final int mType; private AlertDialog mDisconnectDialog; + @Nullable private AlertDialog mBlockPairingDialog; private String contentDescription = null; private boolean mHideSecondTarget = false; private boolean mIsCallbackRemoved = true; @@ -409,13 +411,24 @@ public final class BluetoothDevicePreference extends GearPreference { SettingsEnums.ACTION_SETTINGS_BLUETOOTH_CONNECT); mCachedDevice.connect(); } else if (bondState == BluetoothDevice.BOND_NONE) { - metricsFeatureProvider.action(context, - SettingsEnums.ACTION_SETTINGS_BLUETOOTH_PAIR); - if (!mCachedDevice.hasHumanReadableName()) { + var unused = ThreadUtils.postOnBackgroundThread(() -> { + if (Flags.enableTemporaryBondDevicesUi() && Utils.shouldBlockPairingInAudioSharing( + mLocalBtManager)) { + // TODO: collect metric + context.getMainExecutor().execute(() -> + mBlockPairingDialog = + Utils.showBlockPairingDialog(context, mBlockPairingDialog, + mLocalBtManager)); + return; + } metricsFeatureProvider.action(context, - SettingsEnums.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES); - } - pair(); + SettingsEnums.ACTION_SETTINGS_BLUETOOTH_PAIR); + if (!mCachedDevice.hasHumanReadableName()) { + metricsFeatureProvider.action(context, + SettingsEnums.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES); + } + context.getMainExecutor().execute(() -> pair()); + }); } } diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java index ea76fafc3a5..7c27386ac20 100644 --- a/src/com/android/settings/bluetooth/Utils.java +++ b/src/com/android/settings/bluetooth/Utils.java @@ -34,6 +34,7 @@ import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; @@ -44,6 +45,7 @@ import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.BluetoothUtils.ErrorListener; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback; @@ -324,4 +326,33 @@ public final class Utils { .map(d -> BluetoothUtils.getGroupId(deviceManager.findDevice(d))).collect( Collectors.toSet()).size() >= 2); } + + /** + * Show block pairing dialog during audio sharing + * @param context The dialog context + * @param dialog The dialog if already exists + * @param localBtManager {@link LocalBluetoothManager} + * @return The block pairing dialog + */ + @Nullable + static AlertDialog showBlockPairingDialog(@NonNull Context context, + @Nullable AlertDialog dialog, @Nullable LocalBluetoothManager localBtManager) { + if (!com.android.settingslib.flags.Flags.enableTemporaryBondDevicesUi()) return null; + if (dialog != null && dialog.isShowing()) return dialog; + if (dialog == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setNegativeButton(android.R.string.cancel, null) + .setTitle(R.string.audio_sharing_block_pairing_dialog_title) + .setMessage(R.string.audio_sharing_block_pairing_dialog_content); + LocalBluetoothLeBroadcast broadcast = localBtManager == null ? null : + localBtManager.getProfileManager().getLeAudioBroadcastProfile(); + if (broadcast != null) { + builder.setPositiveButton(R.string.audio_sharing_turn_off_button_label, + (dlg, which) -> broadcast.stopLatestBroadcast()); + } + dialog = builder.create(); + } + dialog.show(); + return dialog; + } } diff --git a/src/com/android/settings/connecteddevice/BluetoothPreference.kt b/src/com/android/settings/connecteddevice/BluetoothPreference.kt index 6ff41a815a0..0e85f355718 100644 --- a/src/com/android/settings/connecteddevice/BluetoothPreference.kt +++ b/src/com/android/settings/connecteddevice/BluetoothPreference.kt @@ -28,12 +28,12 @@ import android.os.UserManager import android.provider.Settings import android.widget.Toast import androidx.preference.Preference -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_BLUETOOTH +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn import com.android.settings.network.SatelliteWarningDialogActivity +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settings.widget.MainSwitchBarMetadata import com.android.settingslib.WirelessUtils import com.android.settingslib.datastore.AbstractKeyedDataObservable diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java index 2a1f4da2cf8..655fd970a15 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java @@ -44,10 +44,12 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.flags.Flags; import com.android.settingslib.utils.ThreadUtils; import com.google.common.collect.ImmutableList; @@ -225,6 +227,14 @@ public class AudioSharingDialogHandler { mLocalBtManager, groupedDevices, /* filterByInSharing= */ true); AudioSharingStopDialogFragment.DialogEventListener listener = () -> { + if (Flags.adoptPrimaryGroupManagementApi() && mLocalBtManager != null) { + LeAudioProfile profile = + mLocalBtManager.getProfileManager().getLeAudioProfile(); + if (profile != null) { + profile.setBroadcastToUnicastFallbackGroup( + BluetoothCsipSetCoordinator.GROUP_ID_INVALID); + } + } cachedDevice.setActive(); mIsStoppingBroadcast = true; AudioSharingUtils.stopBroadcasting(mLocalBtManager); diff --git a/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt b/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt index 33d756ee811..922d4809d7b 100644 --- a/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt +++ b/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt @@ -18,9 +18,9 @@ package com.android.settings.datausage import android.app.settings.SettingsEnums.ACTION_DATA_SAVER_MODE import android.content.Context -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_DATA_SAVER +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.widget.MainSwitchBarMetadata import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.KeyValueStore diff --git a/src/com/android/settings/display/AdaptiveSleepPreference.kt b/src/com/android/settings/display/AdaptiveSleepPreference.kt index e9efc2f2c37..a38925c5458 100644 --- a/src/com/android/settings/display/AdaptiveSleepPreference.kt +++ b/src/com/android/settings/display/AdaptiveSleepPreference.kt @@ -27,10 +27,10 @@ import android.hardware.SensorPrivacyManager.Sensors.CAMERA import android.os.PowerManager import android.os.UserManager import android.provider.Settings -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_SCREEN_ATTENTION +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.RestrictedSwitchPreference import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObservableDelegate diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt index a8227acd84d..86614eebaa6 100644 --- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt +++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt @@ -23,11 +23,11 @@ import android.os.SystemProperties import android.os.UserHandle import android.os.UserManager import android.provider.Settings.Secure.DOZE_ALWAYS_ON -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_AMBIENT_DISPLAY_ALWAYS_ON import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.KeyValueStore diff --git a/src/com/android/settings/display/AutoBrightnessScreen.kt b/src/com/android/settings/display/AutoBrightnessScreen.kt index 7018f81d767..d486b37e798 100644 --- a/src/com/android/settings/display/AutoBrightnessScreen.kt +++ b/src/com/android/settings/display/AutoBrightnessScreen.kt @@ -23,11 +23,11 @@ import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL import androidx.preference.Preference import androidx.preference.PreferenceScreen -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_ADAPTIVE_BRIGHTNESS import com.android.settings.flags.Flags +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.PrimarySwitchPreferenceBinding import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.HandlerExecutor diff --git a/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt b/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt index 2c228af57fa..2ce643609dc 100644 --- a/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt +++ b/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt @@ -18,10 +18,10 @@ package com.android.settings.display import android.app.settings.SettingsEnums.OPEN_BATTERY_PERCENTAGE import android.content.Context import android.provider.Settings -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.Utils import com.android.settings.contract.KEY_BATTERY_PERCENTAGE +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.SettingsStore diff --git a/src/com/android/settings/display/BrightnessLevelPreference.kt b/src/com/android/settings/display/BrightnessLevelPreference.kt index 8f0b791b60f..3dd544e7c1d 100644 --- a/src/com/android/settings/display/BrightnessLevelPreference.kt +++ b/src/com/android/settings/display/BrightnessLevelPreference.kt @@ -27,12 +27,12 @@ import android.hardware.display.DisplayManager.DisplayListener import android.os.UserManager import android.provider.Settings.System import androidx.preference.Preference -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.Utils import com.android.settings.contract.KEY_BRIGHTNESS_LEVEL import com.android.settings.core.SettingsBaseActivity +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.RestrictedPreference import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.HandlerExecutor diff --git a/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt b/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt index 4d132ddd667..ee538db2d36 100644 --- a/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt +++ b/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt @@ -24,9 +24,9 @@ import com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RAT import com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateAmongAllDisplays import com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay import com.android.server.display.feature.flags.Flags -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_SMOOTH_DISPLAY +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObservableDelegate diff --git a/src/com/android/settings/display/darkmode/DarkModeScreen.kt b/src/com/android/settings/display/darkmode/DarkModeScreen.kt index 86ead6b3fd8..b6208ddda7e 100644 --- a/src/com/android/settings/display/darkmode/DarkModeScreen.kt +++ b/src/com/android/settings/display/darkmode/DarkModeScreen.kt @@ -22,10 +22,10 @@ import android.content.Context import android.os.PowerManager import androidx.preference.Preference import androidx.preference.PreferenceScreen -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_DARK_THEME import com.android.settings.flags.Flags +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.PrimarySwitchPreferenceBinding import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.Permissions diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt b/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt index 0eebaa2343a..5375492c84f 100644 --- a/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt +++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt @@ -20,10 +20,10 @@ import android.app.settings.SettingsEnums.ACTION_BATTERY_LEVEL import android.content.Context import androidx.annotation.VisibleForTesting import androidx.preference.Preference -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_BATTERY_LEVEL import com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpdateType.BATTERY_NOT_PRESENT +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.Utils import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.NoOpKeyedObservable diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt index c98b7ba54a8..67d2b64c9a1 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt @@ -19,11 +19,11 @@ import android.Manifest import android.app.settings.SettingsEnums.ACTION_BATTERY_SAVER import android.content.Context import android.os.PowerManager -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_BATTERY_SAVER import com.android.settings.fuelgauge.BatterySaverReceiver import com.android.settings.fuelgauge.BatterySaverReceiver.BatterySaverListener +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.Permissions diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java index 69fbe6b7e3a..1bd2e05452d 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysController.java @@ -53,13 +53,6 @@ public class KeyboardAccessibilityBounceKeysController extends mPrimaryPreference = screen.findPreference(getPreferenceKey()); } - @Override - public int getAvailabilityStatus() { - return (super.getAvailabilityStatus() == AVAILABLE) - && InputSettings.isAccessibilityBounceKeysFeatureEnabled() ? AVAILABLE - : UNSUPPORTED_ON_DEVICE; - } - @Override public boolean handlePreferenceTreeClick(@NonNull Preference preference) { if (!TextUtils.equals(preference.getKey(), getPreferenceKey()) diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java index f3d74075846..f58778a458b 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java @@ -65,13 +65,6 @@ public class KeyboardAccessibilitySlowKeysController extends return true; } - @Override - public int getAvailabilityStatus() { - return (super.getAvailabilityStatus() == AVAILABLE) - && InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled() ? AVAILABLE - : UNSUPPORTED_ON_DEVICE; - } - @Override protected void onInputSettingUpdated() { if (mPrimarySwitchPreference != null) { diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java index f0dcc9350c6..2c4c7092838 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java @@ -60,13 +60,6 @@ public class KeyboardAccessibilityStickyKeysController extends return true; } - @Override - public int getAvailabilityStatus() { - return (super.getAvailabilityStatus() == AVAILABLE) - && InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled() ? AVAILABLE - : UNSUPPORTED_ON_DEVICE; - } - @Override protected void onInputSettingUpdated() { if (mTwoStatePreference != null) { diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java index 8aa5ac7bb26..5bdb9e7bd7a 100644 --- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java +++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java @@ -169,16 +169,13 @@ public final class PhysicalKeyboardFragment extends DashboardFragment mKeyboardAssistanceCategory.removePreference( findPreference(ACCESSIBILITY_PHYSICAL_KEYBOARD_A11Y)); } - if (!InputSettings.isAccessibilityBounceKeysFeatureEnabled() - || isKeyboardAndTouchpadA11yNewPageEnabled) { + if (isKeyboardAndTouchpadA11yNewPageEnabled) { mKeyboardA11yCategory.removePreference(mAccessibilityBounceKeys); } - if (!InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled() - || isKeyboardAndTouchpadA11yNewPageEnabled) { + if (isKeyboardAndTouchpadA11yNewPageEnabled) { mKeyboardA11yCategory.removePreference(mAccessibilitySlowKeys); } - if (!InputSettings.isAccessibilityStickyKeysFeatureEnabled() - || isKeyboardAndTouchpadA11yNewPageEnabled) { + if (isKeyboardAndTouchpadA11yNewPageEnabled) { mKeyboardA11yCategory.removePreference(mAccessibilityStickyKeys); } if (!InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled() @@ -338,15 +335,12 @@ public final class PhysicalKeyboardFragment extends DashboardFragment mFeatureProvider.registerKeyboardInformationCategory(preferenceScreen); } - if (InputSettings.isAccessibilityBounceKeysFeatureEnabled() - || InputSettings.isAccessibilityStickyKeysFeatureEnabled() - || InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled() - || InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()) { - Objects.requireNonNull(mKeyboardA11yCategory).setOrder(2); - preferenceScreen.addPreference(mKeyboardA11yCategory); - updateAccessibilityBounceKeysSwitch(context); - updateAccessibilitySlowKeysSwitch(context); - updateAccessibilityStickyKeysSwitch(context); + Objects.requireNonNull(mKeyboardA11yCategory).setOrder(2); + preferenceScreen.addPreference(mKeyboardA11yCategory); + updateAccessibilityStickyKeysSwitch(context); + updateAccessibilityBounceKeysSwitch(context); + updateAccessibilitySlowKeysSwitch(context); + if (InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()) { updateAccessibilityMouseKeysSwitch(context); } } @@ -370,27 +364,21 @@ public final class PhysicalKeyboardFragment extends DashboardFragment false, mContentObserver, UserHandle.myUserId()); - if (InputSettings.isAccessibilityBounceKeysFeatureEnabled()) { - contentResolver.registerContentObserver( - sAccessibilityBounceKeysUri, - false, - mContentObserver, - UserHandle.myUserId()); - } - if (InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()) { - contentResolver.registerContentObserver( - sAccessibilitySlowKeysUri, - false, - mContentObserver, - UserHandle.myUserId()); - } - if (InputSettings.isAccessibilityStickyKeysFeatureEnabled()) { - contentResolver.registerContentObserver( - sAccessibilityStickyKeysUri, - false, - mContentObserver, - UserHandle.myUserId()); - } + contentResolver.registerContentObserver( + sAccessibilityBounceKeysUri, + false, + mContentObserver, + UserHandle.myUserId()); + contentResolver.registerContentObserver( + sAccessibilitySlowKeysUri, + false, + mContentObserver, + UserHandle.myUserId()); + contentResolver.registerContentObserver( + sAccessibilityStickyKeysUri, + false, + mContentObserver, + UserHandle.myUserId()); if (InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()) { contentResolver.registerContentObserver( sAccessibilityMouseKeysUri, @@ -413,25 +401,16 @@ public final class PhysicalKeyboardFragment extends DashboardFragment } private void updateAccessibilityBounceKeysSwitch(@NonNull Context context) { - if (!InputSettings.isAccessibilityBounceKeysFeatureEnabled()) { - return; - } Objects.requireNonNull(mAccessibilityBounceKeys).setChecked( InputSettings.isAccessibilityBounceKeysEnabled(context)); } private void updateAccessibilitySlowKeysSwitch(@NonNull Context context) { - if (!InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()) { - return; - } Objects.requireNonNull(mAccessibilitySlowKeys).setChecked( InputSettings.isAccessibilitySlowKeysEnabled(context)); } private void updateAccessibilityStickyKeysSwitch(@NonNull Context context) { - if (!InputSettings.isAccessibilityStickyKeysFeatureEnabled()) { - return; - } Objects.requireNonNull(mAccessibilityStickyKeys).setChecked( InputSettings.isAccessibilityStickyKeysEnabled(context)); } diff --git a/src/com/android/settings/metrics/PreferenceActionMetricsProvider.kt b/src/com/android/settings/metrics/PreferenceActionMetricsProvider.kt new file mode 100644 index 00000000000..f5ccf4d5678 --- /dev/null +++ b/src/com/android/settings/metrics/PreferenceActionMetricsProvider.kt @@ -0,0 +1,24 @@ +/* + * 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.metrics + +/** Provides metrics for preference action. */ +interface PreferenceActionMetricsProvider { + + /** Metrics action id for the preference. */ + val preferenceActionMetrics: Int +} diff --git a/src/com/android/settings/Metrics.kt b/src/com/android/settings/metrics/SettingsMetricsLogger.kt similarity index 88% rename from src/com/android/settings/Metrics.kt rename to src/com/android/settings/metrics/SettingsMetricsLogger.kt index 8dde9d5a60f..b81f0ea5778 100644 --- a/src/com/android/settings/Metrics.kt +++ b/src/com/android/settings/metrics/SettingsMetricsLogger.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings +package com.android.settings.metrics import android.content.Context import com.android.settings.overlay.FeatureFactory @@ -23,13 +23,6 @@ import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceScreenMetadata import com.android.settingslib.metadata.PreferenceUiActionMetricsLogger -/** Provides metrics for preference action. */ -interface PreferenceActionMetricsProvider { - - /** Metrics action id for the preference. */ - val preferenceActionMetrics: Int -} - /** [PreferenceUiActionMetricsLogger] of Settings app. */ class SettingsMetricsLogger @JvmOverloads diff --git a/src/com/android/settings/metrics/SettingsRemoteOpMetricsLogger.kt b/src/com/android/settings/metrics/SettingsRemoteOpMetricsLogger.kt index 8653ef9ff0e..6d82c08ba11 100644 --- a/src/com/android/settings/metrics/SettingsRemoteOpMetricsLogger.kt +++ b/src/com/android/settings/metrics/SettingsRemoteOpMetricsLogger.kt @@ -18,7 +18,6 @@ package com.android.settings.metrics import android.app.settings.SettingsEnums import android.content.Context -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.core.instrumentation.SettingsStatsLog import com.android.settingslib.graph.PreferenceGetterErrorCode import com.android.settingslib.graph.PreferenceSetterResult diff --git a/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt b/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt index 51e0ddd61db..80f1d00146a 100644 --- a/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt +++ b/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt @@ -20,14 +20,13 @@ import android.app.settings.SettingsEnums.ACTION_ADAPTIVE_CONNECTIVITY import android.content.Context import android.net.wifi.WifiManager import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_ADAPTIVE_CONNECTIVITY +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.SettingsSecureStore import com.android.settingslib.datastore.SettingsStore -import com.android.settingslib.datastore.and import com.android.settingslib.metadata.MainSwitchPreference import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.SensitivityLevel diff --git a/src/com/android/settings/network/AirplaneModePreference.kt b/src/com/android/settings/network/AirplaneModePreference.kt index afb70c7f890..3d80f12ce2d 100644 --- a/src/com/android/settings/network/AirplaneModePreference.kt +++ b/src/com/android/settings/network/AirplaneModePreference.kt @@ -30,12 +30,12 @@ import android.telephony.TelephonyManager import androidx.annotation.DrawableRes import androidx.preference.Preference import com.android.settings.AirplaneModeEnabler -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.Utils import com.android.settings.contract.KEY_AIRPLANE_MODE +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.RestrictedSwitchPreference import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.KeyValueStore diff --git a/src/com/android/settings/network/MobileDataPreference.kt b/src/com/android/settings/network/MobileDataPreference.kt index 6cb3da259cf..bb02b799234 100644 --- a/src/com/android/settings/network/MobileDataPreference.kt +++ b/src/com/android/settings/network/MobileDataPreference.kt @@ -20,9 +20,9 @@ import android.Manifest import android.app.settings.SettingsEnums.ACTION_MOBILE_DATA import android.content.Context import android.telephony.SubscriptionManager -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_MOBILE_DATA +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.network.telephony.MobileDataRepository import com.android.settings.network.telephony.SubscriptionRepository import com.android.settingslib.datastore.KeyValueStore diff --git a/src/com/android/settings/network/MobileNetworkListScreen.kt b/src/com/android/settings/network/MobileNetworkListScreen.kt index 592260b151d..48c6b317dfa 100644 --- a/src/com/android/settings/network/MobileNetworkListScreen.kt +++ b/src/com/android/settings/network/MobileNetworkListScreen.kt @@ -22,7 +22,6 @@ import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener import androidx.preference.Preference import androidx.preference.Preference.OnPreferenceClickListener -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.flags.Flags import com.android.settings.network.AirplaneModePreference.Companion.isAirplaneModeOn @@ -30,6 +29,7 @@ import com.android.settings.network.SubscriptionUtil.getUniqueSubscriptionDispla import com.android.settings.network.telephony.SimRepository import com.android.settings.network.telephony.SubscriptionRepository import com.android.settings.network.telephony.euicc.EuiccRepository +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settings.spa.network.getAddSimIntent import com.android.settings.spa.network.startAddSimFlow import com.android.settingslib.RestrictedPreference diff --git a/src/com/android/settings/network/NetworkProviderScreen.kt b/src/com/android/settings/network/NetworkProviderScreen.kt index 198eeec1db7..c7d78f21865 100644 --- a/src/com/android/settings/network/NetworkProviderScreen.kt +++ b/src/com/android/settings/network/NetworkProviderScreen.kt @@ -17,9 +17,9 @@ package com.android.settings.network import android.content.Context import android.os.UserManager -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.flags.Flags +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settings.wifi.WifiSwitchPreference import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.ProvidePreferenceScreen @@ -55,9 +55,8 @@ class NetworkProviderScreen : override fun fragmentClass() = NetworkProviderSettings::class.java - override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) { - +WifiSwitchPreference() - } + override fun getPreferenceHierarchy(context: Context) = + preferenceHierarchy(context, this) { +WifiSwitchPreference() } companion object { const val KEY = "internet_settings" diff --git a/src/com/android/settings/network/SimOnboardingActivity.kt b/src/com/android/settings/network/SimOnboardingActivity.kt index 6d9800b5c5a..5d21c0fb3cd 100644 --- a/src/com/android/settings/network/SimOnboardingActivity.kt +++ b/src/com/android/settings/network/SimOnboardingActivity.kt @@ -122,9 +122,10 @@ class SimOnboardingActivity : SpaBaseDialogActivity() { return } - if (onboardingService.activeSubInfoList.isEmpty()) { + if (onboardingService.activeSubInfoList.isEmpty() + || (!onboardingService.isMultiSimEnabled && !onboardingService.isMultiSimSupported)) { // TODO: refactor and replace the ToggleSubscriptionDialogActivity - Log.d(TAG, "onboardingService.activeSubInfoList is empty" + + Log.d(TAG, "onboardingService.activeSubInfoList is empty or restricted ss mode " + ", start ToggleSubscriptionDialogActivity") this.startActivity(ToggleSubscriptionDialogActivity .getIntent(this.applicationContext, targetSubId, true)) diff --git a/src/com/android/settings/network/telephony/SatelliteSetting.java b/src/com/android/settings/network/telephony/SatelliteSetting.java index 52957d98b30..d4bd212d153 100644 --- a/src/com/android/settings/network/telephony/SatelliteSetting.java +++ b/src/com/android/settings/network/telephony/SatelliteSetting.java @@ -19,7 +19,9 @@ package com.android.settings.network.telephony; import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC; import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL; import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT; +import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; +import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING; import android.app.Activity; @@ -165,8 +167,14 @@ public class SatelliteSetting extends RestrictedDashboardFragment { } private void updateMobilePlan(boolean isSatelliteEligible) { - // Your mobile plan PreferenceCategory prefCategory = findPreference(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN); + if (prefCategory == null || !mConfigBundle.getBoolean( + KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL)) { + prefCategory.setVisible(false); + return; + } + + // Your mobile plan prefCategory.setTitle(getResources().getString(R.string.category_title_your_satellite_plan, mSimOperatorName)); Preference messagingPreference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN); @@ -227,9 +235,11 @@ public class SatelliteSetting extends RestrictedDashboardFragment { // More about satellite messaging FooterPreference footerPreference = findPreference(KEY_FOOTER_PREFERENCE); if (footerPreference != null) { - footerPreference.setSummary( - getResources().getString(R.string.satellite_setting_summary_more_information, - getSubjectString(), mSimOperatorName)); + int summary = mConfigBundle.getBoolean(KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL) + ? R.string.satellite_setting_summary_more_information + : R.string.satellite_setting_summary_more_information_no_emergency_messaging; + footerPreference.setSummary(getResources().getString(summary, + getSubjectString(), mSimOperatorName)); final String[] link = new String[1]; link[0] = readSatelliteMoreInfoString(); @@ -273,7 +283,9 @@ public class SatelliteSetting extends RestrictedDashboardFragment { bundle = carrierConfigManager.getConfigForSubId(subId, KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING, - KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT); + KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, + KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL); if (bundle.isEmpty()) { Log.d(TAG, "SatelliteSettings: getDefaultConfig"); bundle = CarrierConfigManager.getDefaultConfig(); diff --git a/src/com/android/settings/network/telephony/SatelliteSettingPreferenceController.java b/src/com/android/settings/network/telephony/SatelliteSettingPreferenceController.java index e2c6412ba57..fd82e5c77f4 100644 --- a/src/com/android/settings/network/telephony/SatelliteSettingPreferenceController.java +++ b/src/com/android/settings/network/telephony/SatelliteSettingPreferenceController.java @@ -17,9 +17,9 @@ package com.android.settings.network.telephony; import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC; -import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL; import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT; import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL; +import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL; import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA; import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS; @@ -65,9 +65,9 @@ public class SatelliteSettingPreferenceController extends @Nullable private Boolean mIsSatelliteEligible = null; private boolean mIsServiceDataType = false; - private boolean mIsSatelliteSmsAvailableForManualType = false; - private boolean mIsCarrierSatelliteAttachSupported = false; - private boolean mIsCarrierRoamingNtnConnectedTypeManual = false; + @VisibleForTesting + boolean mIsSatelliteSmsAvailableForManualType = false; + private PersistableBundle mCarrierConfigs = new PersistableBundle(); public SatelliteSettingPreferenceController(@NonNull Context context, @NonNull String key) { super(context, key); @@ -95,13 +95,15 @@ public class SatelliteSettingPreferenceController extends return UNSUPPORTED_ON_DEVICE; } - int availabilityStatus = mIsCarrierSatelliteAttachSupported - ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; - if (availabilityStatus == AVAILABLE && mIsCarrierRoamingNtnConnectedTypeManual - && !mIsSatelliteSmsAvailableForManualType) { - availabilityStatus = CONDITIONALLY_UNAVAILABLE; + boolean isSatelliteAttachSupport = mCarrierConfigs.getBoolean( + KEY_SATELLITE_ATTACH_SUPPORTED_BOOL); + + if (isSatelliteAttachSupport && isCarrierRoamingNtnConnectedTypeAuto() + && mIsSatelliteSmsAvailableForManualType) { + return AVAILABLE; } - return availabilityStatus; + + return CONDITIONALLY_UNAVAILABLE; } @Override @@ -128,7 +130,7 @@ public class SatelliteSettingPreferenceController extends @Override public void updateState(@Nullable Preference preference) { super.updateState(preference); - if (preference != null) { + if (preference != null && preference.getKey().equals(getPreferenceKey())) { mCarrierRoamingNtnModeCallback.mPref = preference; updateSummary(preference); } @@ -162,18 +164,7 @@ public class SatelliteSettingPreferenceController extends logd("init(), subId=" + subId); mSubId = subId; mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId); - - final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId); - if (carrierConfig == null) { - logd("init(), no carrier config data"); - return; - } - mIsCarrierSatelliteAttachSupported = carrierConfig.getBoolean( - KEY_SATELLITE_ATTACH_SUPPORTED_BOOL); - mIsCarrierRoamingNtnConnectedTypeManual = - CARRIER_ROAMING_NTN_CONNECT_MANUAL == carrierConfig.getInt( - KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, - CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC); + mCarrierConfigs = mCarrierConfigCache.getConfigForSubId(subId); } private void updateSummary(Preference preference) { @@ -186,11 +177,12 @@ public class SatelliteSettingPreferenceController extends return; } - if (mIsCarrierRoamingNtnConnectedTypeManual) { - preference.setSummary(mIsSatelliteSmsAvailableForManualType - ? R.string.satellite_setting_enabled_summary - : R.string.satellite_setting_disabled_summary); - } else { + if (!mCarrierConfigs.getBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL)) { + preference.setSummary(R.string.satellite_setting_summary_without_entitlement); + return; + } + + if (isCarrierRoamingNtnConnectedTypeAuto()) { try { Set restrictionReason = mSatelliteManager.getAttachRestrictionReasonsForCarrier(mSubId); @@ -207,9 +199,19 @@ public class SatelliteSettingPreferenceController extends loge(ex.toString()); preference.setSummary(R.string.satellite_setting_disabled_summary); } + } else { + preference.setSummary(mIsSatelliteSmsAvailableForManualType + ? R.string.satellite_setting_enabled_summary + : R.string.satellite_setting_disabled_summary); } } + private boolean isCarrierRoamingNtnConnectedTypeAuto() { + return CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC == mCarrierConfigs.getInt( + KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC); + } + @VisibleForTesting class CarrierRoamingNtnModeCallback extends TelephonyCallback implements TelephonyCallback.CarrierRoamingNtnListener { diff --git a/src/com/android/settings/network/tether/TetherScreen.kt b/src/com/android/settings/network/tether/TetherScreen.kt index cd8851326fe..0eedfa50455 100644 --- a/src/com/android/settings/network/tether/TetherScreen.kt +++ b/src/com/android/settings/network/tether/TetherScreen.kt @@ -18,12 +18,12 @@ package com.android.settings.network.tether import android.content.Context import android.net.TetheringManager import android.os.UserManager -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.Settings.TetherSettingsActivity import com.android.settings.datausage.DataSaverMainSwitchPreference import com.android.settings.flags.Flags import com.android.settings.network.TetherPreferenceController +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settings.utils.makeLaunchIntent import com.android.settings.wifi.tether.WifiHotspotSwitchPreference import com.android.settingslib.TetherUtil diff --git a/src/com/android/settings/notification/CallVolumePreference.kt b/src/com/android/settings/notification/CallVolumePreference.kt index a0d7561f7f3..aaa59611fd3 100644 --- a/src/com/android/settings/notification/CallVolumePreference.kt +++ b/src/com/android/settings/notification/CallVolumePreference.kt @@ -27,10 +27,10 @@ import android.media.AudioManager.STREAM_BLUETOOTH_SCO import android.media.AudioManager.STREAM_VOICE_CALL import android.os.UserManager import androidx.preference.Preference -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_CALL_VOLUME +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.datastore.Permissions diff --git a/src/com/android/settings/notification/MediaVolumePreference.kt b/src/com/android/settings/notification/MediaVolumePreference.kt index 8af2353dfdc..9910843edc1 100644 --- a/src/com/android/settings/notification/MediaVolumePreference.kt +++ b/src/com/android/settings/notification/MediaVolumePreference.kt @@ -24,10 +24,10 @@ import android.content.pm.PackageManager.FEATURE_AUTOMOTIVE import android.media.AudioManager.STREAM_MUSIC import android.os.UserManager import androidx.preference.Preference -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_MEDIA_VOLUME +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.datastore.Permissions diff --git a/src/com/android/settings/notification/SeparateRingVolumePreference.kt b/src/com/android/settings/notification/SeparateRingVolumePreference.kt index fba3eb404a7..a3c3b68ea2e 100644 --- a/src/com/android/settings/notification/SeparateRingVolumePreference.kt +++ b/src/com/android/settings/notification/SeparateRingVolumePreference.kt @@ -40,10 +40,10 @@ import android.os.Vibrator import android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS import android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS import androidx.preference.Preference -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_RING_VOLUME +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.datastore.Permissions diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java index 836962875b8..cd16940402e 100644 --- a/src/com/android/settings/notification/VolumeSeekBarPreference.java +++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java @@ -47,7 +47,6 @@ public class VolumeSeekBarPreference extends SeekBarPreference { private final InteractionJankMonitor mJankMonitor = InteractionJankMonitor.getInstance(); - protected SeekBar mSeekBar; private int mStream; private SeekBarVolumizer mVolumizer; @VisibleForTesting @@ -115,17 +114,20 @@ public class VolumeSeekBarPreference extends SeekBarPreference { @Override public void onDetached() { + destroyVolumizer(); + super.onDetached(); + } + + private void destroyVolumizer() { if (mVolumizer != null) { mVolumizer.stop(); mVolumizer = null; } - super.onDetached(); } @Override public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); - mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon); mSuppressionTextView = (TextView) view.findViewById(R.id.suppression_text); mTitle = (TextView) view.findViewById(com.android.internal.R.id.title); @@ -133,15 +135,20 @@ public class VolumeSeekBarPreference extends SeekBarPreference { } protected void onBindViewHolder() { - boolean isEnabled = isEnabled(); - mSeekBar.setEnabled(isEnabled); - if (mVolumizer == null) { - createSeekBarVolumizer(); + if (isEnabled()) { + if (mVolumizer == null) { + createSeekBarVolumizer(); + } + // note that setSeekBar will update enabled state! + mVolumizer.setSeekBar(mSeekBar); + } else { + // destroy volumizer to avoid updateSeekBar reset enabled state + destroyVolumizer(); + mSeekBar.setEnabled(false); } - mVolumizer.setSeekBar(mSeekBar); updateIconView(); updateSuppressionText(); - if (isEnabled && mListener != null) { + if (mListener != null) { mListener.onUpdateMuteState(); } } diff --git a/src/com/android/settings/PreferenceRestrictionMixin.kt b/src/com/android/settings/restriction/PreferenceRestrictionMixin.kt similarity index 98% rename from src/com/android/settings/PreferenceRestrictionMixin.kt rename to src/com/android/settings/restriction/PreferenceRestrictionMixin.kt index 8a3640756fd..432bb6281c6 100644 --- a/src/com/android/settings/PreferenceRestrictionMixin.kt +++ b/src/com/android/settings/restriction/PreferenceRestrictionMixin.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings +package com.android.settings.restriction import android.content.Context import android.os.UserHandle diff --git a/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt b/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt index 4dca003d704..3145383507c 100644 --- a/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt +++ b/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt @@ -17,7 +17,6 @@ package com.android.settings.restriction import android.content.Context -import com.android.settings.PreferenceRestrictionMixin import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.KeyedObserver import com.android.settingslib.metadata.PreferenceChangeReason diff --git a/src/com/android/settings/widget/SeekBarPreference.java b/src/com/android/settings/widget/SeekBarPreference.java index 78f2fa5fe2a..b671a64af4f 100644 --- a/src/com/android/settings/widget/SeekBarPreference.java +++ b/src/com/android/settings/widget/SeekBarPreference.java @@ -33,6 +33,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; +import androidx.annotation.VisibleForTesting; import androidx.core.content.res.TypedArrayUtils; import androidx.preference.PreferenceViewHolder; @@ -59,7 +60,8 @@ public class SeekBarPreference extends RestrictedPreference private int mHapticFeedbackMode = HAPTIC_FEEDBACK_MODE_NONE; private int mDefaultProgress = -1; - private SeekBar mSeekBar; + @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) + public SeekBar mSeekBar; private boolean mShouldBlink; private int mAccessibilityRangeInfoType = AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INT; private CharSequence mOverrideSeekBarStateDescription; diff --git a/src/com/android/settings/wifi/WifiSwitchPreference.kt b/src/com/android/settings/wifi/WifiSwitchPreference.kt index 53445c5701a..0c22fa2ec89 100644 --- a/src/com/android/settings/wifi/WifiSwitchPreference.kt +++ b/src/com/android/settings/wifi/WifiSwitchPreference.kt @@ -30,13 +30,13 @@ import android.provider.Settings import android.widget.Toast import androidx.preference.Preference import androidx.preference.Preference.OnPreferenceChangeListener -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.contract.KEY_WIFI +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn import com.android.settings.network.SatelliteWarningDialogActivity import com.android.settings.overlay.FeatureFactory.Companion.featureFactory +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settings.wifi.utils.isDefaultNetworkWifi import com.android.settings.wifi.utils.isWifiEnabled import com.android.settings.wifi.utils.wifiManager diff --git a/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt b/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt index ccf89d0192a..5362f0eb8d6 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt +++ b/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt @@ -25,9 +25,9 @@ import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.ims.ImsMmTelManager import android.util.Log -import com.android.settings.PreferenceActionMetricsProvider import com.android.settings.R import com.android.settings.contract.KEY_WIFI_CALLING +import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.network.ims.WifiCallingQueryImsState import com.android.settings.network.telephony.wificalling.WifiCallingRepository import com.android.settings.widget.SettingsMainSwitchPreference diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt b/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt index fbe431718ec..ec55f74928e 100644 --- a/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt +++ b/src/com/android/settings/wifi/tether/WifiHotspotSwitchPreference.kt @@ -28,13 +28,13 @@ import android.net.wifi.WifiManager import android.os.UserManager import android.text.BidiFormatter import android.util.Log -import com.android.settings.PreferenceActionMetricsProvider -import com.android.settings.PreferenceRestrictionMixin import com.android.settings.R import com.android.settings.Utils import com.android.settings.contract.KEY_WIFI_HOTSPOT import com.android.settings.core.SubSettingLauncher import com.android.settings.datausage.DataSaverMainSwitchPreference.Companion.KEY as DATA_SAVER_KEY +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settings.restriction.PreferenceRestrictionMixin import com.android.settings.wifi.WifiUtils.canShowWifiHotspot import com.android.settings.wifi.utils.tetheringManager import com.android.settings.wifi.utils.wifiApState diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java index ba90ccf63d0..6a72c7d2e0c 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java @@ -28,11 +28,17 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.graphics.drawable.Drawable; +import android.os.Looper; import android.os.UserManager; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.util.Pair; +import androidx.appcompat.app.AlertDialog; import androidx.test.core.app.ApplicationProvider; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -42,8 +48,13 @@ import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.flags.Flags; +import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -57,7 +68,9 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; @@ -81,6 +94,8 @@ public class BluetoothDevicePreferenceTest { @Rule public final MockitoRule mockito = MockitoJUnit.rule(); + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private CachedBluetoothDevice mCachedBluetoothDevice; @Mock @@ -107,6 +122,7 @@ public class BluetoothDevicePreferenceTest { private CachedBluetoothDeviceManager mDeviceManager; private Context mContext = ApplicationProvider.getApplicationContext(); + private ShadowBluetoothAdapter mShadowBluetoothAdapter; private FakeFeatureFactory mFakeFeatureFactory; private MetricsFeatureProvider mMetricsFeatureProvider; @@ -166,6 +182,7 @@ public class BluetoothDevicePreferenceTest { when(mCachedBluetoothDevice.hasHumanReadableName()).thenReturn(true); mPreference.onClicked(); + Shadows.shadowOf(Looper.getMainLooper()).idle(); verify(mMetricsFeatureProvider) .action(mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR); @@ -182,6 +199,7 @@ public class BluetoothDevicePreferenceTest { when(mCachedBluetoothDevice.hasHumanReadableName()).thenReturn(false); mPreference.onClicked(); + Shadows.shadowOf(Looper.getMainLooper()).idle(); verify(mMetricsFeatureProvider) .action(mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR); @@ -190,6 +208,58 @@ public class BluetoothDevicePreferenceTest { MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES); } + @Test + @EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI}) + public void onClicked_deviceNotBonded_blockPairing() { + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + LocalBluetoothProfileManager profileManager = mock(LocalBluetoothProfileManager.class); + LocalBluetoothLeBroadcast broadcast = mock(LocalBluetoothLeBroadcast.class); + LocalBluetoothLeBroadcastAssistant assistant = mock( + LocalBluetoothLeBroadcastAssistant.class); + when(mLocalBluetoothManager.getProfileManager()).thenReturn(profileManager); + when(profileManager.getLeAudioBroadcastProfile()).thenReturn(broadcast); + when(profileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(assistant); + when(broadcast.isEnabled(null)).thenReturn(true); + when(broadcast.getLatestBroadcastId()).thenReturn(1); + BluetoothDevice device1 = mock(BluetoothDevice.class); + BluetoothDevice device2 = mock(BluetoothDevice.class); + CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class); + CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class); + when(cachedDevice1.getDevice()).thenReturn(device1); + when(cachedDevice2.getDevice()).thenReturn(device2); + when(cachedDevice1.getGroupId()).thenReturn(1); + when(cachedDevice2.getGroupId()).thenReturn(2); + when(mDeviceManager.findDevice(device1)).thenReturn(cachedDevice1); + when(mDeviceManager.findDevice(device2)).thenReturn(cachedDevice2); + when(assistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(device1, device2)); + BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); + when(state.getBroadcastId()).thenReturn(1); + when(assistant.getAllSources(any())).thenReturn(ImmutableList.of(state)); + when(mCachedBluetoothDevice.isConnected()).thenReturn(false); + when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE); + when(mCachedBluetoothDevice.startPairing()).thenReturn(true); + when(mCachedBluetoothDevice.hasHumanReadableName()).thenReturn(true); + + mPreference.onClicked(); + Shadows.shadowOf(Looper.getMainLooper()).idle(); + + AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + assertThat(dialog).isNotNull(); + + ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf(dialog); + assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( + mContext.getString(R.string.audio_sharing_block_pairing_dialog_title)); + + verify(mMetricsFeatureProvider, never()) + .action(mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR); + verify(mCachedBluetoothDevice, never()).startPairing(); + } + @Test public void getSecondTargetResource_shouldBeGearIconLayout() { assertThat(mPreference.getSecondTargetResId()).isEqualTo(R.layout.preference_widget_gear); diff --git a/tests/robotests/testutils/com/android/settings/testutils/MetricsRule.kt b/tests/robotests/testutils/com/android/settings/testutils/MetricsRule.kt index 44fa4bf90c6..d5803b3447f 100644 --- a/tests/robotests/testutils/com/android/settings/testutils/MetricsRule.kt +++ b/tests/robotests/testutils/com/android/settings/testutils/MetricsRule.kt @@ -18,7 +18,7 @@ package com.android.settings.testutils import android.content.Context import androidx.test.core.app.ApplicationProvider -import com.android.settings.SettingsMetricsLogger +import com.android.settings.metrics.SettingsMetricsLogger import com.android.settingslib.core.instrumentation.MetricsFeatureProvider import com.android.settingslib.metadata.PreferenceScreenRegistry import org.junit.rules.TestWatcher diff --git a/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsPreferenceControllerTest.java index 6e650fd883f..8fcb32e493d 100644 --- a/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsPreferenceControllerTest.java @@ -16,10 +16,12 @@ package com.android.settings.network.telephony; +import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC; +import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL; +import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL; import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA; import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS; -import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; @@ -39,6 +41,9 @@ import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; import androidx.preference.Preference; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; +import androidx.test.annotation.UiThreadTest; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -47,7 +52,6 @@ import com.android.settings.R; import com.android.settings.network.CarrierConfigCache; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -56,10 +60,10 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) -@Ignore("b/382664790") +@UiThreadTest public class SatelliteSettingsPreferenceControllerTest { - private static final String KEY = "key"; - private static final int TEST_SUB_ID = 0; + private static final String KEY = "SatelliteSettingsPreferenceControllerTest"; + private static final int TEST_SUB_ID = 5; @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -85,12 +89,13 @@ public class SatelliteSettingsPreferenceControllerTest { when(mContext.getSystemService(SatelliteManager.class)).thenReturn(mSatelliteManager); when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); when(mTelephonyManager.createForSubscriptionId(TEST_SUB_ID)).thenReturn(mTelephonyManager); + when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig); mController = spy(new SatelliteSettingPreferenceController(mContext, KEY)); } @Test @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) - public void getAvailabilityStatus_noSatellite_returnUnsupport() { + public void getAvailabilityStatus_noSatellite_returnUnsupported() { when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null); mController = new SatelliteSettingPreferenceController(mContext, KEY); @@ -102,11 +107,39 @@ public class SatelliteSettingsPreferenceControllerTest { @Test @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) public void getAvailabilityStatus_carrierIsNotSupport_returnUnavailable() { - when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null); mCarrierConfig.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false); - when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig); + int result = mController.getAvailabilityStatus(TEST_SUB_ID); + + assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE); + } + + @Test + @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) + public void getAvailabilityStatus_ntnConnectIsManual_returnUnavailable() { + mCarrierConfig.putBoolean( + CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, + true); + mCarrierConfig.putInt( + CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + CARRIER_ROAMING_NTN_CONNECT_MANUAL); + int result = mController.getAvailabilityStatus(TEST_SUB_ID); + + assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE); + } + + @Test + @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) + public void getAvailabilityStatus_smsNotAvailable_returnUnavailable() { + mCarrierConfig.putBoolean( + CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, + true); + mCarrierConfig.putInt( + CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC); + mController.mCarrierRoamingNtnModeCallback.onCarrierRoamingNtnAvailableServicesChanged( + new int[]{SERVICE_TYPE_SMS}); int result = mController.getAvailabilityStatus(TEST_SUB_ID); @@ -115,22 +148,25 @@ public class SatelliteSettingsPreferenceControllerTest { @Test @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) - public void getAvailabilityStatus_carrierIsSupport_returnAvailable() { - when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null); + public void getAvailabilityStatus_matchAllConditions_returnAvailable() { mCarrierConfig.putBoolean( CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true); - when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig); + mCarrierConfig.putInt( + CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC); + + mController.mCarrierRoamingNtnModeCallback.onCarrierRoamingNtnAvailableServicesChanged( + new int[]{SERVICE_TYPE_SMS}); int result = mController.getAvailabilityStatus(TEST_SUB_ID); - assertThat(result).isEqualTo(AVAILABLE); + assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE); } @Test - @Ignore("avoid post submit failed") @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) - public void getAvailabilityStatus_registerTelephonyCallback_success() { + public void onResume_registerTelephonyCallback_success() { mController.init(TEST_SUB_ID); mController.onResume(null); @@ -138,7 +174,6 @@ public class SatelliteSettingsPreferenceControllerTest { } @Test - @Ignore("avoid post submit failed") @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) public void getAvailabilityStatus_unregisterTelephonyCallback_success() { mController.init(TEST_SUB_ID); @@ -178,4 +213,66 @@ public class SatelliteSettingsPreferenceControllerTest { assertThat(preference.getTitle()).isEqualTo( mContext.getString(R.string.satellite_setting_title)); } + + @Test + @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) + public void getAvailabilityStatus_noEntitlement_showSummaryWithoutEntitlement() { + mCarrierConfig.putBoolean( + KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, + false); + mController.init(TEST_SUB_ID); + Preference preference = new Preference(mContext); + preference.setKey(KEY); + preference.setTitle("test title"); + mController.updateState(preference); + + assertThat(preference.getSummary()).isEqualTo( + mContext.getString(R.string.satellite_setting_summary_without_entitlement)); + } + + @Test + @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) + public void getAvailabilityStatus_smsAvailableForManualType_showSummaryWithAccount() { + mCarrierConfig.putBoolean( + KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, + true); + mCarrierConfig.putInt( + CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + CARRIER_ROAMING_NTN_CONNECT_MANUAL); + mController.init(TEST_SUB_ID); + PreferenceManager preferenceManager = new PreferenceManager(mContext); + PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext); + Preference preference = new Preference(mContext); + preference.setKey(KEY); + preference.setTitle("test title"); + preferenceScreen.addPreference(preference); + mController.mIsSatelliteSmsAvailableForManualType = true; + mController.displayPreference(preferenceScreen); + + assertThat(preference.getSummary()).isEqualTo( + mContext.getString(R.string.satellite_setting_enabled_summary)); + } + + @Test + @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) + public void getAvailabilityStatus_smsAvailableForAutoType_showSummaryWithoutAccount() { + mCarrierConfig.putBoolean( + KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, + true); + mCarrierConfig.putInt( + CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, + CARRIER_ROAMING_NTN_CONNECT_MANUAL); + mController.init(TEST_SUB_ID); + PreferenceManager preferenceManager = new PreferenceManager(mContext); + PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext); + Preference preference = new Preference(mContext); + preference.setKey(KEY); + preference.setTitle("test title"); + preferenceScreen.addPreference(preference); + mController.mIsSatelliteSmsAvailableForManualType = false; + mController.displayPreference(preferenceScreen); + + assertThat(preference.getSummary()).isEqualTo( + mContext.getString(R.string.satellite_setting_disabled_summary)); + } }