diff --git a/res/layout/homepage_preference.xml b/res/layout/homepage_preference.xml index f0b1b71c20c..38cb4910d81 100644 --- a/res/layout/homepage_preference.xml +++ b/res/layout/homepage_preference.xml @@ -17,6 +17,7 @@ #783BE5 #3F5FBD @*android:color/material_grey_900 - ?androidprv:attr/materialColorSurfaceContainerHigh + ?androidprv:attr/materialColorSurfaceBright #5F6368 diff --git a/res/values/styles.xml b/res/values/styles.xml index 0a28b016ca9..fe2084f02ad 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -249,7 +249,7 @@ center @*android:string/config_headlineFontFamily @dimen/search_bar_text_size - ?android:attr/textColorSecondary + ?androidprv:attr/materialColorOnSurfaceVariant true diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 6e36ee36733..c38ebfe0069 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -1289,7 +1289,8 @@ public final class Utils extends com.android.settingslib.Utils { */ @ColorInt public static int getHomepageIconColor(Context context) { - return getColorAttrDefaultColor(context, android.R.attr.textColorPrimary); + return getColorAttrDefaultColor( + context, com.android.internal.R.attr.materialColorOnSurface); } /** diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index fe89bf203b4..35fe6e4e600 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -175,6 +175,9 @@ public class AccessibilitySettings extends DashboardFragment implements // Observe changes from accessibility selection menu shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + if (android.view.accessibility.Flags.a11yQsShortcut()) { + shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); + } shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_STICKY_KEYS); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SLOW_KEYS); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS); diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java index 8af284db15f..41c5d750b69 100644 --- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java +++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java @@ -125,6 +125,9 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted final List shortcutFeatureKeys = new ArrayList<>(); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + if (android.view.accessibility.Flags.a11yQsShortcut()) { + shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); + } mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler()); mSettingsContentObserver.registerKeysToObserverCallback(shortcutFeatureKeys, key -> { updateShortcutPreferenceData(); diff --git a/src/com/android/settings/accessibility/ColorAndMotionFragment.java b/src/com/android/settings/accessibility/ColorAndMotionFragment.java index 28c533532d7..4ea22260c79 100644 --- a/src/com/android/settings/accessibility/ColorAndMotionFragment.java +++ b/src/com/android/settings/accessibility/ColorAndMotionFragment.java @@ -74,6 +74,9 @@ public class ColorAndMotionFragment extends DashboardFragment { mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED); mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); + if (android.view.accessibility.Flags.a11yQsShortcut()) { + mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); + } if (Flags.forceInvertColor()) { mShortcutFeatureKeys.add(ToggleForceInvertPreferenceController.SETTINGS_KEY); } diff --git a/src/com/android/settings/accessibility/HearingDevicePairingFragment.java b/src/com/android/settings/accessibility/HearingDevicePairingFragment.java index 0b762f3b589..c797559c290 100644 --- a/src/com/android/settings/accessibility/HearingDevicePairingFragment.java +++ b/src/com/android/settings/accessibility/HearingDevicePairingFragment.java @@ -192,7 +192,7 @@ public class HearingDevicePairingFragment extends RestrictedDashboardFragment im public void onDeviceBondStateChanged(@NonNull CachedBluetoothDevice cachedDevice, int bondState) { if (DEBUG) { - Log.d(TAG, "onDeviceBondStateChanged: " + cachedDevice.getDevice() + ", state = " + Log.d(TAG, "onDeviceBondStateChanged: " + cachedDevice + ", state = " + bondState); } if (bondState == BluetoothDevice.BOND_BONDED) { @@ -276,13 +276,13 @@ public class HearingDevicePairingFragment extends RestrictedDashboardFragment im } mDevicePreferenceMap.put(cachedDevice, preference); if (DEBUG) { - Log.d(TAG, "Add device. device: " + cachedDevice.getDevice()); + Log.d(TAG, "Add device. device: " + cachedDevice); } } void removeDevice(CachedBluetoothDevice cachedDevice) { if (DEBUG) { - Log.d(TAG, "removeDevice: " + cachedDevice.getDevice()); + Log.d(TAG, "removeDevice: " + cachedDevice); } BluetoothDevicePreference preference = mDevicePreferenceMap.remove(cachedDevice); if (mAvailableHearingDeviceGroup != null && preference != null) { @@ -331,13 +331,13 @@ public class HearingDevicePairingFragment extends RestrictedDashboardFragment im cachedDevice = mCachedDeviceManager.addDevice(device); } else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { if (DEBUG) { - Log.d(TAG, "Skip this device, already bonded: " + cachedDevice.getDevice()); + Log.d(TAG, "Skip this device, already bonded: " + cachedDevice); } return; } if (cachedDevice.getHearingAidInfo() == null) { if (DEBUG) { - Log.d(TAG, "Set hearing aid info on device: " + cachedDevice.getDevice()); + Log.d(TAG, "Set hearing aid info on device: " + cachedDevice); } cachedDevice.setHearingAidInfo(new HearingAidInfo.Builder().build()); } @@ -455,7 +455,7 @@ public class HearingDevicePairingFragment extends RestrictedDashboardFragment im void discoverServices(CachedBluetoothDevice cachedDevice) { if (DEBUG) { - Log.d(TAG, "connectGattToCheckCompatibility, device: " + cachedDevice.getDevice()); + Log.d(TAG, "connectGattToCheckCompatibility, device: " + cachedDevice); } BluetoothGatt gatt = cachedDevice.getDevice().connectGatt(getContext(), false, new BluetoothGattCallback() { @@ -465,7 +465,7 @@ public class HearingDevicePairingFragment extends RestrictedDashboardFragment im super.onConnectionStateChange(gatt, status, newState); if (DEBUG) { Log.d(TAG, "onConnectionStateChange, status: " + status + ", newState: " - + newState + ", device: " + cachedDevice.getDevice()); + + newState + ", device: " + cachedDevice); } if (status == GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) { @@ -481,14 +481,14 @@ public class HearingDevicePairingFragment extends RestrictedDashboardFragment im super.onServicesDiscovered(gatt, status); if (DEBUG) { Log.d(TAG, "onServicesDiscovered, status: " + status + ", device: " - + cachedDevice.getDevice()); + + cachedDevice); } if (status == GATT_SUCCESS) { if (gatt.getService(BluetoothUuid.HEARING_AID.getUuid()) != null || gatt.getService(BluetoothUuid.HAS.getUuid()) != null) { if (DEBUG) { Log.d(TAG, "compatible with Android, device: " - + cachedDevice.getDevice()); + + cachedDevice); } addDevice(cachedDevice); } diff --git a/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java index 58aa0cc45f5..21800b91921 100644 --- a/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java +++ b/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java @@ -22,6 +22,7 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import android.app.settings.SettingsEnums; +import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; @@ -159,8 +160,11 @@ public class KeyboardVibrationTogglePreferenceController extends TogglePreferenc } private boolean updateKeyboardVibrationSetting(boolean enable) { - final boolean success = Settings.System.putInt(mContext.getContentResolver(), - KEYBOARD_VIBRATION_ENABLED, enable ? ON : OFF); + final ContentResolver contentResolver = mContext.getContentResolver(); + final boolean success = Settings.System.putInt(contentResolver, + KEYBOARD_VIBRATION_ENABLED, enable ? ON : OFF); + contentResolver.notifyChange(Settings.System.getUriFor(KEYBOARD_VIBRATION_ENABLED), + null /* observer */, ContentResolver.NOTIFY_NO_DELAY); if (!success) { Log.w(TAG, "Update settings database error!"); } diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index 6d5f5362e25..ed47007fbcf 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -179,6 +179,9 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment final List shortcutFeatureKeys = new ArrayList<>(); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + if (android.view.accessibility.Flags.a11yQsShortcut()) { + shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); + } return shortcutFeatureKeys; } diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java index 04898dc0219..fe7db4f7c3e 100644 --- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java +++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java @@ -50,6 +50,8 @@ public class OneHandedSettingsUtils { Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); static final Uri HARDWARE_SHORTCUT_ENABLED_URI = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); + static final Uri QS_SHORTCUT_ENABLED_URI = + Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_QS_TARGETS); public enum OneHandedTimeout { NEVER(0), SHORT(4), MEDIUM(8), LONG(12); @@ -254,6 +256,16 @@ public class OneHandedSettingsUtils { if (!TextUtils.isEmpty(targetsHW) && targetsHW.contains(ONE_HANDED_MODE_TARGET_NAME)) { return true; } + + if (android.view.accessibility.Flags.a11yQsShortcut()) { + // Checks QS_SHORTCUT_KEY + final String targetsQs = Settings.Secure.getStringForUser(context.getContentResolver(), + Settings.Secure.ACCESSIBILITY_QS_TARGETS, sCurrentUserId); + if (!TextUtils.isEmpty(targetsQs) && targetsQs.contains(ONE_HANDED_MODE_TARGET_NAME)) { + return true; + } + } + return false; } @@ -301,6 +313,9 @@ public class OneHandedSettingsUtils { resolver.registerContentObserver(SHOW_NOTIFICATION_ENABLED_URI, true, this); resolver.registerContentObserver(SOFTWARE_SHORTCUT_ENABLED_URI, true, this); resolver.registerContentObserver(HARDWARE_SHORTCUT_ENABLED_URI, true, this); + if (android.view.accessibility.Flags.a11yQsShortcut()) { + resolver.registerContentObserver(QS_SHORTCUT_ENABLED_URI, true, this); + } } @Override diff --git a/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt index 907bab1217c..1e635a587fe 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt +++ b/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt @@ -84,6 +84,13 @@ open class MobileNetworkEidPreferenceController(context: Context, key: String) : } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { + if (!this::lazyViewModel.isInitialized) { + Log.e( + this.javaClass.simpleName, + "lateinit property lazyViewModel has not been initialized" + ) + return + } preference.isVisible = false val viewModel by lazyViewModel diff --git a/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt index 8ec313b0483..e1346819f7d 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt +++ b/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt @@ -78,6 +78,13 @@ class MobileNetworkImeiPreferenceController(context: Context, key: String) : } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { + if (!this::lazyViewModel.isInitialized) { + Log.e( + this.javaClass.simpleName, + "lateinit property lazyViewModel has not been initialized" + ) + return + } val viewModel by lazyViewModel val coroutineScope = viewLifecycleOwner.lifecycleScope diff --git a/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt index 65a4b7e6dce..10a8b53e5d4 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt +++ b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt @@ -19,6 +19,7 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager +import android.util.Log import androidx.annotation.VisibleForTesting import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -66,6 +67,13 @@ class MobileNetworkPhoneNumberPreferenceController(context: Context, key: String } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { + if (!this::lazyViewModel.isInitialized) { + Log.e( + this.javaClass.simpleName, + "lateinit property lazyViewModel has not been initialized" + ) + return + } val viewModel by lazyViewModel val coroutineScope = viewLifecycleOwner.lifecycleScope diff --git a/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt index ac055b02f06..4736eb7df83 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt +++ b/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt @@ -19,6 +19,7 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager +import android.util.Log import androidx.annotation.VisibleForTesting import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -26,6 +27,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settings.flags.Flags +import com.android.settings.network.SimOnboardingActivity import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle @@ -57,6 +59,14 @@ class MobileNetworkSpnPreferenceController(context: Context, key: String) : } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { + if (!this::lazyViewModel.isInitialized) { + Log.e( + this.javaClass.simpleName, + "lateinit property lazyViewModel has not been initialized" + ) + return + } + val viewModel by lazyViewModel viewModel.subscriptionInfoListFlow diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt index 0ee1d87cd62..f184092821e 100644 --- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt +++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt @@ -22,6 +22,7 @@ import android.telecom.TelecomManager import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.ims.ImsMmTelManager +import android.util.Log import androidx.lifecycle.LifecycleOwner import androidx.preference.Preference import androidx.preference.PreferenceScreen @@ -76,6 +77,13 @@ open class WifiCallingPreferenceController @JvmOverloads constructor( } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { + if(mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID){ + Log.e( + this.javaClass.simpleName, + "mSubId is INVALID_SUBSCRIPTION_ID" + ) + return + } wifiCallingRepositoryFactory(mSubId).wifiCallingReadyFlow() .collectLatestWithLifecycle(viewLifecycleOwner) { isReady -> preference.isVisible = isReady diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.kt b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.kt index d709574997a..67a23563727 100644 --- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.kt +++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.kt @@ -23,6 +23,7 @@ import android.os.PersistableBundle import android.provider.Settings import android.telephony.CarrierConfigManager import android.telephony.ServiceState +import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable @@ -80,7 +81,7 @@ class AutoSelectPreferenceController @JvmOverloads constructor( @VisibleForTesting var progressDialog: ProgressDialog? = null - private var subId by notNull() + private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID /** * Initialization based on given subscription id. diff --git a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt index 3b2d5ec0d80..94e4a88ae5e 100644 --- a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt +++ b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt @@ -16,6 +16,7 @@ package com.android.settings.spa.network +import android.telephony.SubscriptionInfo import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons @@ -63,52 +64,55 @@ fun SimOnboardingLabelSimImpl( cancelAction ), ) { - labelSimBody(onboardingService) + LabelSimBody(onboardingService) } } @Composable -private fun labelSimBody(onboardingService: SimOnboardingService) { +private fun LabelSimBody(onboardingService: SimOnboardingService) { Column(Modifier.padding(SettingsDimension.itemPadding)) { SettingsBody(stringResource(R.string.sim_onboarding_label_sim_msg)) } for (subInfo in onboardingService.getSelectableSubscriptionInfoList()) { - var titleSimName by remember { - mutableStateOf( - onboardingService.getSubscriptionInfoDisplayName(subInfo) - ) - } - var summaryNumber = subInfo.number - // TODO using the SubscriptionUtil.getFormattedPhoneNumber - val alertDialogPresenter = rememberAlertDialogPresenter( - confirmButton = AlertDialogButton( - stringResource(R.string.mobile_network_sim_name_rename) - ) { - onboardingService.addItemForRenaming(subInfo, titleSimName) - }, - dismissButton = AlertDialogButton(stringResource(R.string.cancel)) { - titleSimName = onboardingService.getSubscriptionInfoDisplayName(subInfo) - }, - title = stringResource(R.string.sim_onboarding_label_sim_dialog_title), - text = { - Text(summaryNumber, - modifier = Modifier.padding(bottom = SettingsDimension.itemPaddingVertical)) - SettingsOutlinedTextField( - value = titleSimName, - label = stringResource(R.string.sim_onboarding_label_sim_dialog_label), - enabled = true, - shape = MaterialTheme.shapes.extraLarge - ) { - titleSimName = it - } - }, - ) - Preference(object : PreferenceModel { - override val title = titleSimName - override val summary: () -> String - get() = { summaryNumber } - override val onClick = alertDialogPresenter::open - }) + LabelSimPreference(onboardingService, subInfo) } -} \ No newline at end of file +} + +@Composable +private fun LabelSimPreference( + onboardingService: SimOnboardingService, + subInfo: SubscriptionInfo, +) { + var titleSimName by remember { + mutableStateOf(onboardingService.getSubscriptionInfoDisplayName(subInfo)) + } + val phoneNumber = phoneNumber(subInfo) + val alertDialogPresenter = rememberAlertDialogPresenter( + confirmButton = AlertDialogButton(stringResource(R.string.mobile_network_sim_name_rename)) { + onboardingService.addItemForRenaming(subInfo, titleSimName) + }, + dismissButton = AlertDialogButton(stringResource(R.string.cancel)) { + titleSimName = onboardingService.getSubscriptionInfoDisplayName(subInfo) + }, + title = stringResource(R.string.sim_onboarding_label_sim_dialog_title), + text = { + Text( + phoneNumber.value ?: "", + modifier = Modifier.padding(bottom = SettingsDimension.itemPaddingVertical) + ) + SettingsOutlinedTextField( + value = titleSimName, + label = stringResource(R.string.sim_onboarding_label_sim_dialog_label), + shape = MaterialTheme.shapes.extraLarge + ) { + titleSimName = it + } + }, + ) + Preference(object : PreferenceModel { + override val title = titleSimName + override val summary = { phoneNumber.value ?: "" } + override val onClick = alertDialogPresenter::open + }) +} diff --git a/src/com/android/settings/spa/network/SimsSection.kt b/src/com/android/settings/spa/network/SimsSection.kt index 9e4cf9f4c12..0b638c45ae5 100644 --- a/src/com/android/settings/spa/network/SimsSection.kt +++ b/src/com/android/settings/spa/network/SimsSection.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Add import androidx.compose.runtime.Composable +import androidx.compose.runtime.State import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -58,9 +59,7 @@ private fun SimPreference(subInfo: SubscriptionInfo) { val checked = remember(subInfo.subscriptionId) { context.isSubscriptionEnabledFlow(subInfo.subscriptionId) }.collectAsStateWithLifecycle(initialValue = false) - val phoneNumber = remember(subInfo) { - context.phoneNumberFlow(subInfo) - }.collectAsStateWithLifecycle(initialValue = null) + val phoneNumber = phoneNumber(subInfo) RestrictedTwoTargetSwitchPreference( model = object : SwitchPreferenceModel { override val title = subInfo.displayName.toString() @@ -80,6 +79,14 @@ private fun SimPreference(subInfo: SubscriptionInfo) { } } +@Composable +fun phoneNumber(subInfo: SubscriptionInfo): State { + val context = LocalContext.current + return remember(subInfo) { + context.phoneNumberFlow(subInfo) + }.collectAsStateWithLifecycle(initialValue = null) +} + @Composable private fun AddSim() { val context = LocalContext.current diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java index 05e56ca74a4..624a39ab330 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java @@ -38,8 +38,12 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.database.ContentObserver; import android.os.Build; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.Flags; import androidx.fragment.app.Fragment; import androidx.test.core.app.ApplicationProvider; @@ -59,6 +63,8 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.search.SearchIndexableRaw; import com.android.settingslib.testutils.shadow.ShadowColorDisplayManager; +import com.google.common.truth.BooleanSubject; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -103,6 +109,7 @@ public class AccessibilitySettingsTest { @Rule public final MockitoRule mocks = MockitoJUnit.rule(); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private final Context mContext = ApplicationProvider.getApplicationContext(); @Spy private final AccessibilityServiceInfo mServiceInfo = getMockAccessibilityServiceInfo( @@ -316,30 +323,39 @@ public class AccessibilitySettingsTest { } @Test - public void onCreate_haveRegisterToSpecificUrisAndActions() { + @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + public void onCreate_flagDisabled_haveRegisterToSpecificUrisAndActions() { setupFragment(); - ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver()); - Collection a11yButtonTargetsObservers = - shadowContentResolver.getContentObservers( - Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)); - Collection a11yShortcutTargetServiceObservers = - shadowContentResolver.getContentObservers(Settings.Secure.getUriFor( - Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + AccessibilitySettingsContentObserver.class).isTrue(); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, + AccessibilitySettingsContentObserver.class).isTrue(); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_QS_TARGETS, + AccessibilitySettingsContentObserver.class).isFalse(); + List broadcastReceivers = + shadowOf((Application) ApplicationProvider.getApplicationContext()) + .getRegisteredReceivers() + .stream().map(wrapper -> wrapper.broadcastReceiver).toList(); + assertThat(broadcastReceivers.stream().anyMatch( + broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + public void onCreate_flagEnabled_haveRegisterToSpecificUrisAndActions() { + setupFragment(); + + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + AccessibilitySettingsContentObserver.class).isTrue(); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, + AccessibilitySettingsContentObserver.class).isTrue(); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_QS_TARGETS, + AccessibilitySettingsContentObserver.class).isTrue(); List broadcastReceivers = shadowOf((Application) ApplicationProvider.getApplicationContext()) .getRegisteredReceivers() .stream().map(wrapper -> wrapper.broadcastReceiver).toList(); - assertThat( - a11yButtonTargetsObservers.stream() - .anyMatch(contentObserver -> - contentObserver instanceof AccessibilitySettingsContentObserver)) - .isTrue(); - assertThat( - a11yShortcutTargetServiceObservers.stream() - .anyMatch(contentObserver -> - contentObserver instanceof AccessibilitySettingsContentObserver)) - .isTrue(); assertThat(broadcastReceivers.stream().anyMatch( broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isTrue(); } @@ -350,27 +366,16 @@ public class AccessibilitySettingsTest { mActivityController.pause().stop().destroy(); - ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver()); - Collection a11yButtonTargetsObservers = - shadowContentResolver.getContentObservers( - Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)); - Collection a11yShortcutTargetServiceObservers = - shadowContentResolver.getContentObservers(Settings.Secure.getUriFor( - Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + AccessibilitySettingsContentObserver.class).isFalse(); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, + AccessibilitySettingsContentObserver.class).isFalse(); + assertUriObserversContainsClazz(Settings.Secure.ACCESSIBILITY_QS_TARGETS, + AccessibilitySettingsContentObserver.class).isFalse(); List broadcastReceivers = shadowOf((Application) ApplicationProvider.getApplicationContext()) .getRegisteredReceivers() .stream().map(wrapper -> wrapper.broadcastReceiver).toList(); - assertThat( - a11yButtonTargetsObservers.stream() - .anyMatch(contentObserver -> - contentObserver instanceof AccessibilitySettingsContentObserver)) - .isFalse(); - assertThat( - a11yShortcutTargetServiceObservers.stream() - .anyMatch(contentObserver -> - contentObserver instanceof AccessibilitySettingsContentObserver)) - .isFalse(); assertThat(broadcastReceivers.stream().anyMatch( broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isFalse(); } @@ -491,4 +496,14 @@ public class AccessibilitySettingsTest { Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, enabled ? componentName.flattenToString() : ""); } + + private BooleanSubject assertUriObserversContainsClazz( + String settingUri, Class clazz) { + ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver()); + Collection observers = + shadowContentResolver.getContentObservers( + Settings.Secure.getUriFor(settingUri)); + + return assertThat(observers.stream().anyMatch(clazz::isInstance)); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/HearingDevicePairingFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingDevicePairingFragmentTest.java index e14686e4a18..db82be6db3a 100644 --- a/tests/robotests/src/com/android/settings/accessibility/HearingDevicePairingFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/HearingDevicePairingFragmentTest.java @@ -178,7 +178,7 @@ public class HearingDevicePairingFragmentTest { } @Test - public void handleLeScanResult_isNotAndroidCompatible_() { + public void handleLeScanResult_isNotAndroidCompatible_discoverServices() { ScanResult scanResult = mock(ScanResult.class); doReturn(mDevice).when(scanResult).getDevice(); doReturn(mCachedDevice).when(mCachedDeviceManager).findDevice(mDevice); @@ -189,6 +189,19 @@ public class HearingDevicePairingFragmentTest { verify(mFragment).discoverServices(mCachedDevice); } + @Test + public void handleLeScanResult_alreadyBonded_doNothing() { + ScanResult scanResult = mock(ScanResult.class); + doReturn(mDevice).when(scanResult).getDevice(); + doReturn(mCachedDevice).when(mCachedDeviceManager).findDevice(mDevice); + doReturn(BluetoothDevice.BOND_BONDED).when(mCachedDevice).getBondState(); + + mFragment.handleLeScanResult(scanResult); + + verify(mFragment, never()).addDevice(mCachedDevice); + verify(mFragment, never()).discoverServices(mCachedDevice); + } + @Test public void onProfileConnectionStateChanged_deviceConnected_inSelectedList_finish() { doReturn(true).when(mCachedDevice).isConnected(); diff --git a/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java index 2d5905e8de8..832a3136d96 100644 --- a/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; import android.app.settings.SettingsEnums; +import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.os.vibrator.Flags; @@ -60,6 +61,9 @@ public class KeyboardVibrationTogglePreferenceControllerTest { @Mock private PreferenceScreen mPreferenceScreen; + @Mock + private ContentResolver mContentResolver; + private Context mContext; private Resources mResources; private KeyboardVibrationTogglePreferenceController mController; @@ -72,6 +76,7 @@ public class KeyboardVibrationTogglePreferenceControllerTest { mContext = spy(ApplicationProvider.getApplicationContext()); mResources = spy(mContext.getResources()); when(mContext.getResources()).thenReturn(mResources); + when(mContext.getContentResolver()).thenReturn(mContentResolver); mFeatureFactory = FakeFeatureFactory.setupForTest(); mController = new KeyboardVibrationTogglePreferenceController(mContext, "preferenceKey"); mPreference = new SwitchPreference(mContext); diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java index e963bd01f68..6fb1c3fb08a 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -146,8 +147,9 @@ public class ToggleFeaturePreferenceFragmentTest { } @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) @Config(shadows = {ShadowFragment.class}) - public void onResume_haveRegisterToSpecificUris() { + public void onResume_flagEnabled_haveRegisterToSpecificUris() { mFragment.onAttach(mContext); mFragment.onCreate(Bundle.EMPTY); @@ -162,6 +164,36 @@ public class ToggleFeaturePreferenceFragmentTest { Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)), eq(false), any(AccessibilitySettingsContentObserver.class)); + verify(mContentResolver).registerContentObserver( + eq(Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_QS_TARGETS)), + eq(false), + any(AccessibilitySettingsContentObserver.class)); + } + + @Test + @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + @Config(shadows = {ShadowFragment.class}) + public void onResume_flagDisabled_haveRegisterToSpecificUris() { + mFragment.onAttach(mContext); + mFragment.onCreate(Bundle.EMPTY); + + mFragment.onResume(); + + verify(mContentResolver).registerContentObserver( + eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)), + eq(false), + any(AccessibilitySettingsContentObserver.class)); + verify(mContentResolver).registerContentObserver( + eq(Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)), + eq(false), + any(AccessibilitySettingsContentObserver.class)); + verify(mContentResolver, never()).registerContentObserver( + eq(Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_QS_TARGETS)), + eq(false), + any(AccessibilitySettingsContentObserver.class)); } @Test diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java index 3d24fbb7237..1d85705a9e7 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java @@ -292,7 +292,39 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { } @Test - public void onResume_haveRegisterToSpecificUris() { + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + public void onResume_flagEnabled_haveRegisterToSpecificUris() { + ShadowContentResolver shadowContentResolver = Shadows.shadowOf( + mContext.getContentResolver()); + Uri[] observedUri = new Uri[]{ + Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS), + Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), + Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_QS_TARGETS), + Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED), + Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED) + }; + for (Uri uri : observedUri) { + // verify no observer registered before launching the fragment + assertThat(shadowContentResolver.getContentObservers(uri)).isEmpty(); + } + + mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); + + for (Uri uri : observedUri) { + Collection observers = shadowContentResolver.getContentObservers(uri); + assertThat(observers.size()).isEqualTo(1); + assertThat(observers.stream().findFirst().get()).isInstanceOf( + AccessibilitySettingsContentObserver.class); + } + } + + @Test + @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + public void onResume_flagDisabled_haveRegisterToSpecificUris() { ShadowContentResolver shadowContentResolver = Shadows.shadowOf( mContext.getContentResolver()); Uri[] observedUri = new Uri[]{ @@ -317,6 +349,9 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { assertThat(observers.stream().findFirst().get()).isInstanceOf( AccessibilitySettingsContentObserver.class); } + assertThat(shadowContentResolver.getContentObservers( + Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_QS_TARGETS))).hasSize(0); } @Test diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java index 9559043570c..ee5f72ed2d4 100644 --- a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java +++ b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java @@ -16,13 +16,20 @@ package com.android.settings.gestures; +import static com.android.settings.gestures.OneHandedSettingsUtils.ONE_HANDED_MODE_TARGET_NAME; + import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.UserHandle; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; +import android.view.accessibility.Flags; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -30,7 +37,8 @@ import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class OneHandedSettingsUtilsTest { - + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final int OFF = 0; private static final int ON = 1; @@ -120,4 +128,66 @@ public class OneHandedSettingsUtilsTest { OneHandedSettingsUtils.OneHandedTimeout.LONG.getValue(), mCurrentUserId)) .isEqualTo(12); } + + @Test + public void getShortcutEnabled_a11yButtonVolumeKeysShortcutEnabled_returnTrue() { + setupShortcuts( + /* enableFab= */ true, /* enableVolumeKeys= */ true, /* enableQs=*/ false); + + assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue(); + } + + @Test + public void getShortcutEnabled_a11yButtonShortcutEnabled_returnTrue() { + setupShortcuts( + /* enableFab= */ true, /* enableVolumeKeys= */ false, /* enableQs=*/ false); + + assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue(); + } + + @Test + public void getShortcutEnabled_volumeKeysShortcutEnabled_returnTrue() { + setupShortcuts( + /* enableFab= */ false, /* enableVolumeKeys= */ true, /* enableQs=*/ false); + + assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue(); + } + + @Test + public void getShortcutEnabled_noShortcutsEnabled_returnFalse() { + setupShortcuts( + /* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ false); + + assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isFalse(); + } + + @Test + @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + public void getShortcutEnabled_qsShortcutEnabled_returnTrue() { + setupShortcuts( + /* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true); + + assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue(); + } + + @Test + @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + public void getShortcutEnabled_flagDisabled_qsShortcutEnabled_returnFalse() { + setupShortcuts( + /* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true); + + assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isFalse(); + } + + private void setupShortcuts(boolean enableFab, boolean enableVolumeKeys, boolean enableQs) { + setupShortcut(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, enableFab); + setupShortcut(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, enableVolumeKeys); + setupShortcut(Settings.Secure.ACCESSIBILITY_QS_TARGETS, enableQs); + } + + private void setupShortcut(String shortcutSettingKey, boolean enabled) { + final String targetName = enabled ? ONE_HANDED_MODE_TARGET_NAME : ""; + Settings.Secure.putStringForUser( + mContext.getContentResolver(), shortcutSettingKey, targetName, mCurrentUserId); + } }