Merge "[Accessibility] Address UX comments for the contrast screen" into main
diff --git a/aconfig/settings_panel_flag_declarations.aconfig b/aconfig/settings_panel_flag_declarations.aconfig
deleted file mode 100644
index efab83e..0000000
--- a/aconfig/settings_panel_flag_declarations.aconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-package: "com.android.settings.flags"
-container: "system"
-
-flag {
- name: "enable_volume_plus_quick_settings"
- namespace: "pixel_cross_device_control"
- description: "Gates whether to enable VolumePlus quick settings panel."
- bug: "309052662"
-}
diff --git a/aconfig/settings_threadnetwork_flag_declarations.aconfig b/aconfig/settings_threadnetwork_flag_declarations.aconfig
new file mode 100644
index 0000000..70945d3
--- /dev/null
+++ b/aconfig/settings_threadnetwork_flag_declarations.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.settings.flags"
+
+flag {
+ name: "thread_settings_enabled"
+ namespace: "thread_network"
+ description: "Controls whether the Thread Settings UX is displayed"
+ bug: "329384658"
+}
diff --git a/res/layout/homepage_preference.xml b/res/layout/homepage_preference.xml
index f0b1b71..38cb491 100644
--- a/res/layout/homepage_preference.xml
+++ b/res/layout/homepage_preference.xml
@@ -17,6 +17,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -77,7 +78,7 @@
android:layout_gravity="start"
android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorSecondary"
+ android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
android:maxLines="4"
android:hyphenationFrequency="normalFast"
android:lineBreakWordStyle="phrase"
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index a572841..a27fbaa 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -19,7 +19,7 @@
<color name="homepage_accessibility_background">#783BE5</color>
<color name="homepage_support_background">#3F5FBD</color>
<color name="contextual_card_background">@*android:color/material_grey_900</color>
- <color name="search_bar_background">?androidprv:attr/materialColorSurfaceContainerHigh</color>
+ <color name="search_bar_background">?androidprv:attr/materialColorSurfaceBright</color>
<color name="notification_importance_button_unselected">#5F6368</color>
<!-- Palette list preference colors. -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4bbf742..224425b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10479,6 +10479,9 @@
<!-- Summary text for 3-button navigation [CHAR LIMIT=NONE] -->
<string name="legacy_navigation_summary">Go back, Home, and switch apps with buttons at the bottom of your screen.</string>
+ <!-- Accessibility string for gesture nav tutorial button [CHAR_LIMIT=NONE] -->
+ <string name="nav_tutorial_button_description">Start gesture navigation tutorial</string>
+
<!-- Search keywords for System Navigation settings. [CHAR_LIMIT=NONE]-->
<string name="keywords_system_navigation">system navigation, 2 button navigation, 3 button navigation, gesture navigation, swipe</string>
@@ -11997,6 +12000,9 @@
<string name="confirm_format_ext4_text">16K developer option is supported with ext4 filesystem. Device will be wiped and filesystem will be changed to ext4 after confirmation.</string>
<!-- Toast on failure to reformat data to ext4 -->
<string name="format_ext4_failure_toast">Failed to reformat and wipe the data partiton to ext4.</string>
+ <!-- Dialog to OEM unlock the device before using 16K developer option -->
+ <string name="confirm_oem_unlock_for_16k_title">OEM unlock required</string>
+ <string name="confirm_oem_unlock_for_16k_text">Device needs to be OEM unlocked before using 16K developer option. OEM unlock will also require formatting userdata. Please OEM unlock the device and try again.</string>
<!-- DSU Loader. Do not translate. -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 0a28b01..fe2084f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -249,7 +249,7 @@
<item name="android:layout_gravity">center</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">@dimen/search_bar_text_size</item>
- <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
<item name="android:singleLine">true</item>
</style>
diff --git a/res/values/themes_suw.xml b/res/values/themes_suw.xml
index 71d9fcb..9efac28 100644
--- a/res/values/themes_suw.xml
+++ b/res/values/themes_suw.xml
@@ -231,7 +231,7 @@
<style name="SuwAlertDialogThemeCompat" parent="@style/Theme.AppCompat.Dialog.Alert">
<!-- Referenced SudThemeGlifV3 style -->
<item name="android:textAllCaps">false</item>
-
+ <item name="android:colorBackground">@android:color/system_neutral1_900</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<!-- copied from Theme.DeviceDefault.Dialog.Alert -->
<item name="colorAccent">@*android:color/accent_device_default_dark</item>
@@ -243,7 +243,7 @@
<style name="SuwAlertDialogThemeCompat.Light" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
<!-- Referenced SudThemeGlifV3.Light style -->
<item name="android:textAllCaps">false</item>
-
+ <item name="android:colorBackground">@android:color/system_neutral1_50</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
<item name="colorAccent">@*android:color/accent_device_default_light</item>
diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml
index cb1ce44..15d5303 100644
--- a/res/xml/security_lockscreen_settings.xml
+++ b/res/xml/security_lockscreen_settings.xml
@@ -69,9 +69,11 @@
android:summary="@string/lockscreen_trivial_controls_summary"
settings:controller="com.android.settings.display.ControlsTrivialPrivacyPreferenceController"/>
+ <!-- Shortcuts -->
<Preference
android:key="customizable_lock_screen_quick_affordances"
android:title="@string/lockscreen_quick_affordances_title"
+ android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.display.CustomizableLockScreenQuickAffordancesPreferenceController" />
<SwitchPreferenceCompat
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 6e36ee3..c38ebfe 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -1289,7 +1289,8 @@
*/
@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 fe89bf2..35fe6e4 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -175,6 +175,9 @@
// 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 8af284d..41c5d75 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -125,6 +125,9 @@
final List<String> 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 28c5335..4ea2226 100644
--- a/src/com/android/settings/accessibility/ColorAndMotionFragment.java
+++ b/src/com/android/settings/accessibility/ColorAndMotionFragment.java
@@ -74,6 +74,9 @@
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 0b762f3..c797559 100644
--- a/src/com/android/settings/accessibility/HearingDevicePairingFragment.java
+++ b/src/com/android/settings/accessibility/HearingDevicePairingFragment.java
@@ -192,7 +192,7 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 58aa0cc..21800b9 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.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 @@
}
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 6d5f536..ed47007 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -179,6 +179,9 @@
final List<String> 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/applications/credentials/DefaultCombinedPickerPrivate.java b/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java
index 52adc4d..f1aaa53 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPickerPrivate.java
@@ -32,6 +32,8 @@
/** Returns whether the user is handled by this fragment. */
public static boolean isUserHandledByFragment(UserManager userManager) {
- return android.os.Flags.allowPrivateProfile() && userManager.isPrivateProfile();
+ return android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && userManager.isPrivateProfile();
}
}
diff --git a/src/com/android/settings/connecteddevice/threadnetwork/ThreadNetworkPreferenceController.kt b/src/com/android/settings/connecteddevice/threadnetwork/ThreadNetworkPreferenceController.kt
index f5c0a87..1c01750 100644
--- a/src/com/android/settings/connecteddevice/threadnetwork/ThreadNetworkPreferenceController.kt
+++ b/src/com/android/settings/connecteddevice/threadnetwork/ThreadNetworkPreferenceController.kt
@@ -34,9 +34,9 @@
import androidx.lifecycle.LifecycleOwner
import androidx.preference.Preference
import androidx.preference.PreferenceScreen
-import com.android.net.thread.platform.flags.Flags
import com.android.settings.R
import com.android.settings.core.TogglePreferenceController
+import com.android.settings.flags.Flags
import java.util.concurrent.Executor
/** Controller for the "Thread" toggle in "Connected devices > Connection preferences". */
@@ -110,7 +110,7 @@
}
override fun getAvailabilityStatus(): Int {
- return if (!Flags.threadEnabledPlatform()) {
+ return if (!Flags.threadSettingsEnabled()) {
CONDITIONALLY_UNAVAILABLE
} else if (!isThreadSupportedOnDevice) {
UNSUPPORTED_ON_DEVICE
diff --git a/src/com/android/settings/datausage/lib/AppDataUsageRepository.kt b/src/com/android/settings/datausage/lib/AppDataUsageRepository.kt
index 5abde31..0055463 100644
--- a/src/com/android/settings/datausage/lib/AppDataUsageRepository.kt
+++ b/src/com/android/settings/datausage/lib/AppDataUsageRepository.kt
@@ -164,6 +164,7 @@
private fun shouldSkipProfile(userManager : UserManager, userHandle: UserHandle): Boolean {
if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
&& android.multiuser.Flags.handleInterleavedSettingsForPrivateSpace()) {
return (userManager.isQuietModeEnabled(userHandle)
&& userManager.getUserProperties(userHandle).showInQuietMode
diff --git a/src/com/android/settings/development/Enable16KOemUnlockDialog.java b/src/com/android/settings/development/Enable16KOemUnlockDialog.java
new file mode 100644
index 0000000..65690df
--- /dev/null
+++ b/src/com/android/settings/development/Enable16KOemUnlockDialog.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.development;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/** Dialog when user interacts 16K pages developer option and device is not OEM unlocked */
+public class Enable16KOemUnlockDialog extends InstrumentedDialogFragment
+ implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+
+ public static final String TAG = "Enable16KOemUnlockDialog";
+
+ /** This method is used to prompt user to do OEM unlock before using 16k */
+ public static void show(@NonNull Fragment hostFragment) {
+ final FragmentManager manager = hostFragment.getActivity().getSupportFragmentManager();
+ Fragment existingFragment = manager.findFragmentByTag(TAG);
+ if (existingFragment == null) {
+ existingFragment = new Enable16KOemUnlockDialog();
+ }
+
+ if (existingFragment instanceof Enable16KOemUnlockDialog) {
+ existingFragment.setTargetFragment(hostFragment, 0 /* requestCode */);
+ ((Enable16KOemUnlockDialog) existingFragment).show(manager, TAG);
+ }
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DIALOG_ENABLE_16K_PAGES;
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.confirm_oem_unlock_for_16k_title)
+ .setMessage(R.string.confirm_oem_unlock_for_16k_text)
+ .setPositiveButton(android.R.string.ok, this /* onClickListener */)
+ .create();
+ }
+
+ @Override
+ public void onClick(@NonNull DialogInterface dialog, int buttonId) {
+ // Do nothing. OEM unlock has to be done by user
+ }
+
+ @Override
+ public void onDismiss(@NonNull DialogInterface dialog) {
+ super.onDismiss(dialog);
+ }
+}
diff --git a/src/com/android/settings/development/Enable16kPagesPreferenceController.java b/src/com/android/settings/development/Enable16kPagesPreferenceController.java
index 7049e79..bed5c04 100644
--- a/src/com/android/settings/development/Enable16kPagesPreferenceController.java
+++ b/src/com/android/settings/development/Enable16kPagesPreferenceController.java
@@ -28,7 +28,10 @@
import android.os.UpdateEngine;
import android.os.UpdateEngineStable;
import android.os.UpdateEngineStableCallback;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
+import android.service.oemlock.OemLockManager;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
@@ -116,6 +119,12 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
mEnable16k = (Boolean) newValue;
+ // Prompt user to do oem unlock first
+ if (!isDeviceOEMUnlocked()) {
+ Enable16KOemUnlockDialog.show(mFragment);
+ return false;
+ }
+
if (isDataf2fs()) {
EnableExt4WarningDialog.show(mFragment, this);
return false;
@@ -418,4 +427,30 @@
return false;
}
+
+ private boolean isDeviceOEMUnlocked() {
+ // OEM unlock is checked for bootloader, carrier and user. Check all three to ensure
+ // that device is unlocked and it is also allowed by user as well as carrier
+ final OemLockManager oemLockManager = mContext.getSystemService(OemLockManager.class);
+ final UserManager userManager = mContext.getSystemService(UserManager.class);
+ if (oemLockManager == null || userManager == null) {
+ Log.e(TAG, "Required services not found on device to check for OEM unlock state.");
+ return false;
+ }
+
+ // If either of device or carrier is not allowed to unlock, return false
+ if (!oemLockManager.isDeviceOemUnlocked()
+ || !oemLockManager.isOemUnlockAllowedByCarrier()) {
+ Log.e(TAG, "Device is not OEM unlocked or it is not allowed by carrier");
+ return false;
+ }
+
+ final UserHandle userHandle = UserHandle.of(UserHandle.myUserId());
+ if (userManager.hasBaseUserRestriction(UserManager.DISALLOW_FACTORY_RESET, userHandle)) {
+ Log.e(TAG, "Factory reset is not allowed for user.");
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
index 04898dc..fe7db4f 100644
--- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java
+++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
@@ -50,6 +50,8 @@
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 @@
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 @@
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/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index c40212b..c38be94 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -247,6 +247,7 @@
switch (systemNavKey) {
case KEY_SYSTEM_NAV_GESTURAL:
if (isGestureTutorialAvailable()){
+ videoPref.setContentDescription(R.string.nav_tutorial_button_description);
videoPref.setOnPreferenceClickListener(preference -> {
startActivity(mLaunchSandboxIntent);
return true;
diff --git a/src/com/android/settings/location/LocationForPrivateProfilePreferenceController.java b/src/com/android/settings/location/LocationForPrivateProfilePreferenceController.java
index a7be7a5..d68cf72 100644
--- a/src/com/android/settings/location/LocationForPrivateProfilePreferenceController.java
+++ b/src/com/android/settings/location/LocationForPrivateProfilePreferenceController.java
@@ -68,6 +68,7 @@
@Override
public int getAvailabilityStatus() {
if (!android.os.Flags.allowPrivateProfile()
+ || !android.multiuser.Flags.enablePrivateSpaceFeatures()
|| !android.multiuser.Flags.handleInterleavedSettingsForPrivateSpace()
|| !isPrivateProfileAvailable()) {
return CONDITIONALLY_UNAVAILABLE;
diff --git a/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt
index 907bab1..1e635a5 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt
@@ -84,6 +84,13 @@
}
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 8ec313b..e134681 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt
@@ -78,6 +78,13 @@
}
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 65a4b7e..10a8b53 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt
@@ -19,6 +19,7 @@
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 @@
}
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 ac055b0..4736eb7 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt
@@ -19,6 +19,7 @@
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.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 @@
}
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/NetworkSelectRepository.kt b/src/com/android/settings/network/telephony/NetworkSelectRepository.kt
new file mode 100644
index 0000000..1f5fbc2
--- /dev/null
+++ b/src/com/android/settings/network/telephony/NetworkSelectRepository.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony
+
+import android.content.Context
+import android.telephony.AccessNetworkConstants
+import android.telephony.NetworkRegistrationInfo
+import android.telephony.TelephonyManager
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class NetworkSelectRepository(context: Context, subId: Int) {
+ private val telephonyManager =
+ context.getSystemService(TelephonyManager::class.java)!!.createForSubscriptionId(subId)
+
+ data class NetworkRegistrationAndForbiddenInfo(
+ val networkList: List<NetworkRegistrationInfo>,
+ val forbiddenPlmns: List<String>,
+ )
+
+ /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
+ fun launchUpdateNetworkRegistrationInfo(
+ lifecycleOwner: LifecycleOwner,
+ action: (NetworkRegistrationAndForbiddenInfo) -> Unit,
+ ) {
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ withContext(Dispatchers.Default) {
+ getNetworkRegistrationInfo()
+ }?.let(action)
+ }
+ }
+ }
+
+ fun getNetworkRegistrationInfo(): NetworkRegistrationAndForbiddenInfo? {
+ if (telephonyManager.dataState != TelephonyManager.DATA_CONNECTED) return null
+ // Try to get the network registration states
+ val serviceState = telephonyManager.serviceState ?: return null
+ val networkList = serviceState.getNetworkRegistrationInfoListForTransportType(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+ )
+ if (networkList.isEmpty()) return null
+ // Due to the aggregation of cell between carriers, it's possible to get CellIdentity
+ // containing forbidden PLMN.
+ // Getting current network from ServiceState is no longer a good idea.
+ // Add an additional rule to avoid from showing forbidden PLMN to the user.
+ return NetworkRegistrationAndForbiddenInfo(networkList, getForbiddenPlmns())
+ }
+
+ /**
+ * Update forbidden PLMNs from the USIM App
+ */
+ private fun getForbiddenPlmns(): List<String> {
+ return telephonyManager.forbiddenPlmns?.toList() ?: emptyList()
+ }
+}
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index eb89d9e..19bc390 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -24,12 +24,10 @@
import android.os.Message;
import android.os.PersistableBundle;
import android.provider.Settings;
-import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.NetworkRegistrationInfo;
-import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -52,13 +50,11 @@
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanCellInfos;
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanComplete;
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanError;
-import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanResult;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.ThreadUtils;
import kotlin.Unit;
-import kotlin.jvm.functions.Function1;
import java.util.ArrayList;
import java.util.Arrays;
@@ -101,6 +97,8 @@
private NetworkScanRepository mNetworkScanRepository;
private boolean mUpdateScanResult = false;
+ private NetworkSelectRepository mNetworkSelectRepository;
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -138,6 +136,7 @@
mCarrierConfigManager.registerCarrierConfigChangeListener(mNetworkScanExecutor,
mCarrierConfigChangeListener);
mNetworkScanRepository = new NetworkScanRepository(context, mSubId);
+ mNetworkSelectRepository = new NetworkSelectRepository(context, mSubId);
}
@Keep
@@ -202,35 +201,37 @@
mProgressHeader = setPinnedHeaderView(
com.android.settingslib.widget.progressbar.R.layout.progress_header
).findViewById(com.android.settingslib.widget.progressbar.R.id.progress_bar_animation);
- forceUpdateConnectedPreferenceCategory();
+ mNetworkSelectRepository.launchUpdateNetworkRegistrationInfo(
+ getViewLifecycleOwner(),
+ (info) -> {
+ forceUpdateConnectedPreferenceCategory(info);
+ return Unit.INSTANCE;
+ });
launchNetworkScan();
}
private void launchNetworkScan() {
- mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), new Function1<>() {
- @Override
- public Unit invoke(@NonNull NetworkScanResult networkScanResult) {
- if (!mUpdateScanResult) {
- // Not update UI if not in scan mode.
- return Unit.INSTANCE;
- }
- if (networkScanResult instanceof NetworkScanCellInfos networkScanCellInfos) {
- scanResultHandler(networkScanCellInfos.getCellInfos());
- return Unit.INSTANCE;
- }
- if (!isPreferenceScreenEnabled()) {
- clearPreferenceSummary();
- enablePreferenceScreen(true);
- } else if (networkScanResult instanceof NetworkScanComplete
- && mCellInfoList == null) {
- // In case the scan timeout before getting any results
- addMessagePreference(R.string.empty_networks_list);
- } else if (networkScanResult instanceof NetworkScanError) {
- addMessagePreference(R.string.network_query_error);
- }
-
+ mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), (networkScanResult) -> {
+ if (!mUpdateScanResult) {
+ // Not update UI if not in scan mode.
return Unit.INSTANCE;
}
+ if (networkScanResult instanceof NetworkScanCellInfos networkScanCellInfos) {
+ scanResultHandler(networkScanCellInfos.getCellInfos());
+ return Unit.INSTANCE;
+ }
+ if (!isPreferenceScreenEnabled()) {
+ clearPreferenceSummary();
+ enablePreferenceScreen(true);
+ } else if (networkScanResult instanceof NetworkScanComplete
+ && mCellInfoList == null) {
+ // In case the scan timeout before getting any results
+ addMessagePreference(R.string.empty_networks_list);
+ } else if (networkScanResult instanceof NetworkScanError) {
+ addMessagePreference(R.string.network_query_error);
+ }
+
+ return Unit.INSTANCE;
});
}
@@ -238,7 +239,6 @@
public void onStart() {
super.onStart();
- updateForbiddenPlmns();
setProgressBarVisible(true);
mUpdateScanResult = true;
}
@@ -477,45 +477,26 @@
* - If the device has no data, we will remove the connected network operators list from the
* screen.
*/
- private void forceUpdateConnectedPreferenceCategory() {
- if (mTelephonyManager.getDataState() == mTelephonyManager.DATA_CONNECTED) {
- // Try to get the network registration states
- final ServiceState ss = mTelephonyManager.getServiceState();
- if (ss == null) {
- return;
+ private void forceUpdateConnectedPreferenceCategory(
+ NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo info) {
+ for (NetworkRegistrationInfo regInfo : info.getNetworkList()) {
+ final CellIdentity cellIdentity = regInfo.getCellIdentity();
+ if (cellIdentity == null) {
+ continue;
}
- final List<NetworkRegistrationInfo> networkList =
- ss.getNetworkRegistrationInfoListForTransportType(
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (networkList == null || networkList.size() == 0) {
- return;
+ final NetworkOperatorPreference pref = new NetworkOperatorPreference(
+ getPrefContext(), info.getForbiddenPlmns(), mShow4GForLTE);
+ pref.updateCell(null, cellIdentity);
+ if (pref.isForbiddenNetwork()) {
+ continue;
}
- // Due to the aggregation of cell between carriers, it's possible to get CellIdentity
- // containing forbidden PLMN.
- // Getting current network from ServiceState is no longer a good idea.
- // Add an additional rule to avoid from showing forbidden PLMN to the user.
- if (mForbiddenPlmns == null) {
- updateForbiddenPlmns();
- }
- for (NetworkRegistrationInfo regInfo : networkList) {
- final CellIdentity cellIdentity = regInfo.getCellIdentity();
- if (cellIdentity == null) {
- continue;
- }
- final NetworkOperatorPreference pref = new NetworkOperatorPreference(
- getPrefContext(), mForbiddenPlmns, mShow4GForLTE);
- pref.updateCell(null, cellIdentity);
- if (pref.isForbiddenNetwork()) {
- continue;
- }
- pref.setSummary(R.string.network_connected);
- // Update the signal strength icon, since the default signalStrength value
- // would be zero
- // (it would be quite confusing why the connected network has no signal)
- pref.setIcon(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
- mPreferenceCategory.addPreference(pref);
- break;
- }
+ pref.setSummary(R.string.network_connected);
+ // Update the signal strength icon, since the default signalStrength value
+ // would be zero
+ // (it would be quite confusing why the connected network has no signal)
+ pref.setIcon(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
+ mPreferenceCategory.addPreference(pref);
+ break;
}
}
diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.kt
index 0ee1d87..f184092 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.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 @@
}
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 d709574..67a2356 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.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 @@
@VisibleForTesting
var progressDialog: ProgressDialog? = null
- private var subId by notNull<Int>()
+ private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
/**
* Initialization based on given subscription id.
diff --git a/src/com/android/settings/privatespace/PrivateSpaceGaiaEducationFragment.java b/src/com/android/settings/privatespace/PrivateSpaceGaiaEducationFragment.java
index 0fa0483..6c26186 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceGaiaEducationFragment.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceGaiaEducationFragment.java
@@ -46,7 +46,8 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
- if (android.os.Flags.allowPrivateProfile()) {
+ if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()) {
super.onCreate(savedInstanceState);
}
}
diff --git a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
index 3b2d5ec..94e4a88 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 @@
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 9e4cf9f..0b638c4 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.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 @@
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()
@@ -81,6 +80,14 @@
}
@Composable
+fun phoneNumber(subInfo: SubscriptionInfo): State<String?> {
+ val context = LocalContext.current
+ return remember(subInfo) {
+ context.phoneNumberFlow(subInfo)
+ }.collectAsStateWithLifecycle(initialValue = null)
+}
+
+@Composable
private fun AddSim() {
val context = LocalContext.current
if (remember { MobileNetworkUtils.showEuiccSettings(context) }) {
diff --git a/src/com/android/settings/wifi/details2/CertificateDetailsPreferenceController.kt b/src/com/android/settings/wifi/details2/CertificateDetailsPreferenceController.kt
index 4630365..8e1fa23 100644
--- a/src/com/android/settings/wifi/details2/CertificateDetailsPreferenceController.kt
+++ b/src/com/android/settings/wifi/details2/CertificateDetailsPreferenceController.kt
@@ -72,7 +72,6 @@
}
private fun getCertX509(wifiEntry: WifiEntry): Boolean {
- if (certX509 != null ) return true
certificateAliases =
wifiEntry.wifiConfiguration?.enterpriseConfig?.caCertificateAliases?.get(0)
?: return false
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index 05e56ca..624a39a 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.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.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 @@
@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 @@
}
@Test
- public void onCreate_haveRegisterToSpecificUrisAndActions() {
+ @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT)
+ public void onCreate_flagDisabled_haveRegisterToSpecificUrisAndActions() {
setupFragment();
- ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
- Collection<ContentObserver> a11yButtonTargetsObservers =
- shadowContentResolver.getContentObservers(
- Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
- Collection<ContentObserver> 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<BroadcastReceiver> 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();
+ }
+
+ @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<BroadcastReceiver> broadcastReceivers =
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .getRegisteredReceivers()
+ .stream().map(wrapper -> wrapper.broadcastReceiver).toList();
assertThat(broadcastReceivers.stream().anyMatch(
broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isTrue();
}
@@ -350,27 +366,16 @@
mActivityController.pause().stop().destroy();
- ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
- Collection<ContentObserver> a11yButtonTargetsObservers =
- shadowContentResolver.getContentObservers(
- Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
- Collection<ContentObserver> 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<BroadcastReceiver> 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 @@
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? componentName.flattenToString() : "");
}
+
+ private BooleanSubject assertUriObserversContainsClazz(
+ String settingUri, Class<?> clazz) {
+ ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
+ Collection<ContentObserver> 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 e14686e..db82be6 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 @@
}
@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);
@@ -190,6 +190,19 @@
}
@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();
mFragment.mSelectedDeviceList.add(mDevice);
diff --git a/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java
index 2d5905e..832a313 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.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 @@
@Mock
private PreferenceScreen mPreferenceScreen;
+ @Mock
+ private ContentResolver mContentResolver;
+
private Context mContext;
private Resources mResources;
private KeyboardVibrationTogglePreferenceController mController;
@@ -72,6 +76,7 @@
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/MagnificationOneFingerPanningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
index 326a7a0..4501d27 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
@@ -16,7 +16,6 @@
package com.android.settings.accessibility;
-import static com.android.server.accessibility.Flags.enableMagnificationOneFingerPanningGesture;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
@@ -28,7 +27,10 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
-import android.platform.test.flag.junit.SetFlagsRule;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -51,8 +53,9 @@
private static final String ONE_FINGER_PANNING_KEY =
Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
- @Rule public final SetFlagsRule mSetFlagsRule =
- new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
@@ -88,16 +91,16 @@
}
@Test
- public void getAvailabilityStatus_defaultState_disabled() {
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
+ public void getAvailabilityStatus_flagDisabled_disabled() {
int status = mController.getAvailabilityStatus();
assertThat(status).isEqualTo(DISABLED_FOR_USER);
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void getAvailabilityStatus_featureFlagEnabled_enabled() {
- enableFlag();
-
int status = mController.getAvailabilityStatus();
assertThat(status).isEqualTo(AVAILABLE);
@@ -158,9 +161,8 @@
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void performClick_switchDefaultState_shouldReturnTrue() {
- enableFlag();
-
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(true);
@@ -168,13 +170,6 @@
assertThat(mSwitchPreference.isChecked()).isTrue();
}
- private void enableFlag() {
- mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE);
- assertThat(enableMagnificationOneFingerPanningGesture()).isTrue();
- // This ensures that preference change listeners are added correctly.
- mController.displayPreference(mScreen);
- }
-
private String enabledSummary() {
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_on);
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index e963bd0..6fb1c3f 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.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 @@
}
@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 @@
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 3d24fbb..1d85705 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 @@
}
@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<ContentObserver> 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 @@
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 9559043..ee5f72e 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 @@
@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 @@
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);
+ }
}
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
index 3cd2002..9d97fbf 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
@@ -50,7 +50,7 @@
import platform.test.screenshot.DeviceEmulationSpec
import platform.test.screenshot.DisplaySpec
import platform.test.screenshot.FragmentScreenshotTestRule
-import platform.test.screenshot.GoldenImagePathManager
+import platform.test.screenshot.GoldenPathManager
import platform.test.screenshot.matchers.PixelPerfectMatcher
class Injector(step: FingerprintNavigationStep.UiStep) {
@@ -154,7 +154,7 @@
fun BiometricFragmentScreenShotRule() =
FragmentScreenshotTestRule(
DeviceEmulationSpec.forDisplays(Phone).first(),
- GoldenImagePathManager(
+ GoldenPathManager(
InstrumentationRegistry.getInstrumentation().context,
InstrumentationRegistry.getInstrumentation().targetContext.filesDir.absolutePath +
screenshotPath,
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/NetworkSelectRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/NetworkSelectRepositoryTest.kt
new file mode 100644
index 0000000..4137de4
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/NetworkSelectRepositoryTest.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony
+
+import android.content.Context
+import android.telephony.AccessNetworkConstants
+import android.telephony.NetworkRegistrationInfo
+import android.telephony.ServiceState
+import android.telephony.TelephonyManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.network.telephony.scan.NetworkScanRepositoryTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+
+@RunWith(AndroidJUnit4::class)
+class NetworkSelectRepositoryTest {
+
+ private val mockServiceState = mock<ServiceState> {
+ on {
+ getNetworkRegistrationInfoListForTransportType(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+ )
+ } doReturn NetworkRegistrationInfos
+ }
+
+ private val mockTelephonyManager = mock<TelephonyManager> {
+ on { createForSubscriptionId(SUB_ID) } doReturn mock
+ on { dataState } doReturn TelephonyManager.DATA_CONNECTED
+ on { serviceState } doReturn mockServiceState
+ }
+
+ private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+ on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
+ }
+
+ private val repository = NetworkSelectRepository(context, SUB_ID)
+
+ @Test
+ fun getNetworkRegistrationInfo_notConnected_returnNull() {
+ mockTelephonyManager.stub {
+ on { dataState } doReturn TelephonyManager.DATA_DISCONNECTED
+ }
+
+ val info = repository.getNetworkRegistrationInfo()
+
+ assertThat(info).isNull()
+ }
+
+ @Test
+ fun getNetworkRegistrationInfo_nullServiceState_returnNull() {
+ mockTelephonyManager.stub {
+ on { serviceState } doReturn null
+ }
+
+ val info = repository.getNetworkRegistrationInfo()
+
+ assertThat(info).isNull()
+ }
+
+ @Test
+ fun getNetworkRegistrationInfo_emptyNetworkList_returnNull() {
+ mockServiceState.stub {
+ on {
+ getNetworkRegistrationInfoListForTransportType(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+ )
+ } doReturn emptyList()
+ }
+
+ val info = repository.getNetworkRegistrationInfo()
+
+ assertThat(info).isNull()
+ }
+
+ @Test
+ fun getNetworkRegistrationInfo_hasNetworkList_returnInfo() {
+ mockServiceState.stub {
+ on {
+ getNetworkRegistrationInfoListForTransportType(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+ )
+ } doReturn NetworkRegistrationInfos
+ }
+ mockTelephonyManager.stub {
+ on { forbiddenPlmns } doReturn arrayOf(FORBIDDEN_PLMN)
+ }
+
+ val info = repository.getNetworkRegistrationInfo()
+
+ assertThat(info).isEqualTo(
+ NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo(
+ networkList = NetworkRegistrationInfos,
+ forbiddenPlmns = listOf(FORBIDDEN_PLMN),
+ )
+ )
+ }
+
+ private companion object {
+ const val SUB_ID = 1
+ val NetworkRegistrationInfos = listOf(NetworkRegistrationInfo.Builder().build())
+ const val FORBIDDEN_PLMN = "Forbidden PLMN"
+ }
+}
diff --git a/tests/unit/src/com/android/settings/conecteddevice/threadnetwork/ThreadNetworkPreferenceControllerTest.kt b/tests/unit/src/com/android/settings/conecteddevice/threadnetwork/ThreadNetworkPreferenceControllerTest.kt
index 644095d..976096c 100644
--- a/tests/unit/src/com/android/settings/conecteddevice/threadnetwork/ThreadNetworkPreferenceControllerTest.kt
+++ b/tests/unit/src/com/android/settings/conecteddevice/threadnetwork/ThreadNetworkPreferenceControllerTest.kt
@@ -33,13 +33,13 @@
import androidx.preference.SwitchPreference
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.net.thread.platform.flags.Flags
import com.android.settings.R
import com.android.settings.core.BasePreferenceController.AVAILABLE
import com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE
import com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING
import com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE
import com.android.settings.connecteddevice.threadnetwork.ThreadNetworkPreferenceController.BaseThreadNetworkController
+import com.android.settings.flags.Flags
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
@@ -68,7 +68,7 @@
@Before
fun setUp() {
- mSetFlagsRule.enableFlags(Flags.FLAG_THREAD_ENABLED_PLATFORM)
+ mSetFlagsRule.enableFlags(Flags.FLAG_THREAD_SETTINGS_ENABLED)
context = spy(ApplicationProvider.getApplicationContext<Context>())
executor = ContextCompat.getMainExecutor(context)
fakeThreadNetworkController = FakeThreadNetworkController(executor)
@@ -96,7 +96,7 @@
@Test
fun availabilityStatus_flagDisabled_returnsConditionallyUnavailable() {
- mSetFlagsRule.disableFlags(Flags.FLAG_THREAD_ENABLED_PLATFORM)
+ mSetFlagsRule.disableFlags(Flags.FLAG_THREAD_SETTINGS_ENABLED)
assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE)
}