From 6f9f3a459419db410504642b4d7e1466ce0592e8 Mon Sep 17 00:00:00 2001 From: Alejandro Nijamkin Date: Mon, 5 Jun 2023 15:50:54 -0700 Subject: [PATCH 1/6] Fixes nav stack issue. By marking the Intent that's being sent to WPP as "launched from settings", the code in CustomizationPickerActivity can correctly conclude that the multi-pane wrapper does not need to be applied to the intent, preventing the odd "disordering" of the back stack in the bug. Fix: 284809020 Test: manually verified, on a large screen device with a multi-pane settings configuration, that going to Display > Lock screen > Shortcuts and then swiping back off the left edge of the display correctly exits settings instead of revealing an incorrect screen like it did in the bug. Test: also manually verified that the long-press on the home screena and on the lock screen paths both open the right tab in WPP in settings correctly. Change-Id: Iac2b4e9fa5bab91b6a5251f1c51b4d21a0824f00 --- .../display/CustomizableLockScreenUtils.java | 15 ++++++++++++++- ...nQuickAffordancesPreferenceControllerTest.java | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/display/CustomizableLockScreenUtils.java b/src/com/android/settings/display/CustomizableLockScreenUtils.java index d945652e880..23444364c6a 100644 --- a/src/com/android/settings/display/CustomizableLockScreenUtils.java +++ b/src/com/android/settings/display/CustomizableLockScreenUtils.java @@ -60,6 +60,12 @@ public final class CustomizableLockScreenUtils { @VisibleForTesting static final String AFFORDANCE_NAME = "affordance_name"; + @VisibleForTesting + static final String WALLPAPER_LAUNCH_SOURCE = "com.android.wallpaper.LAUNCH_SOURCE"; + @VisibleForTesting + static final String LAUNCH_SOURCE_SETTINGS = "app_launched_settings"; + + private CustomizableLockScreenUtils() {} /** @@ -163,7 +169,14 @@ public final class CustomizableLockScreenUtils { * activity. */ public static Intent newIntent() { - return new Intent(Intent.ACTION_SET_WALLPAPER); + final Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER); + // By adding the launch source here, we tell our destination (in this case, the wallpaper + // picker app) that it's been launched from within settings. That way, if we are in a + // multi-pane configuration (for example, for large screens), the wallpaper picker app can + // safely skip redirecting to the multi-pane version of its activity, as it's already opened + // within a multi-pane configuration context. + intent.putExtra(WALLPAPER_LAUNCH_SOURCE, LAUNCH_SOURCE_SETTINGS); + return intent; } private static boolean isWallpaperPickerInstalled(Context context) { diff --git a/tests/robotests/src/com/android/settings/display/CustomizableLockScreenQuickAffordancesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/CustomizableLockScreenQuickAffordancesPreferenceControllerTest.java index e92dbe6cb5e..bf316e9d9bc 100644 --- a/tests/robotests/src/com/android/settings/display/CustomizableLockScreenQuickAffordancesPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/CustomizableLockScreenQuickAffordancesPreferenceControllerTest.java @@ -114,6 +114,9 @@ public class CustomizableLockScreenQuickAffordancesPreferenceControllerTest { assertThat(intentCaptor.getValue().getPackage()).isEqualTo( mContext.getString(R.string.config_wallpaper_picker_package)); assertThat(intentCaptor.getValue().getAction()).isEqualTo(Intent.ACTION_SET_WALLPAPER); + assertThat(intentCaptor.getValue().getStringExtra( + CustomizableLockScreenUtils.WALLPAPER_LAUNCH_SOURCE)).isEqualTo( + CustomizableLockScreenUtils.LAUNCH_SOURCE_SETTINGS); assertThat(intentCaptor.getValue().getStringExtra("destination")) .isEqualTo("quick_affordances"); } From 13cd0526934779489bdd79f83d42bc921fb3dd06 Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Tue, 6 Jun 2023 14:08:44 +0800 Subject: [PATCH 2/6] ForgetDeviceDialogFragment check whether device is null or not Bug: 280687867 Test: build pass Change-Id: I4134569854165f20f6287406d9ed627b2c15c05b --- .../bluetooth/ForgetDeviceDialogFragment.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java b/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java index 1da8672b760..60d63c637df 100644 --- a/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java +++ b/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java @@ -23,6 +23,7 @@ import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; +import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; @@ -63,6 +64,13 @@ public class ForgetDeviceDialogFragment extends InstrumentedDialogFragment { @Override public Dialog onCreateDialog(Bundle inState) { + Context context = getContext(); + mDevice = getDevice(context); + if (mDevice == null) { + Log.e(TAG, "onCreateDialog: Device is null."); + return null; + } + DialogInterface.OnClickListener onConfirm = (dialog, which) -> { mDevice.unpair(); Activity activity = getActivity(); @@ -70,9 +78,6 @@ public class ForgetDeviceDialogFragment extends InstrumentedDialogFragment { activity.finish(); } }; - Context context = getContext(); - mDevice = getDevice(context); - AlertDialog dialog = new AlertDialog.Builder(context) .setPositiveButton(R.string.bluetooth_unpair_dialog_forget_confirm_button, onConfirm) From d41299016e6f7265798fceb839cb856e40651b43 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 6 Jun 2023 21:39:01 +0800 Subject: [PATCH 3/6] Correct typo in the launch via NFC bottom string Bug: 283521954 Test: manual check the string Change-Id: Ia32817ee1735831d0156a84ef7f48af94131dc73 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index a72794dc4b5..9c713f60d64 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10564,7 +10564,7 @@ Allow launch on NFC scan - Allow this app to launch when a NFC tag is scanned.\nIf this permission is on, the app will be available as an option whenever a tag is detected. + Allow this app to launch when an NFC tag is scanned.\nIf this permission is on, the app will be available as an option whenever a tag is detected. Play media to From 5e71aee4cdc86158ff8ee1ddadc50a34c121cc08 Mon Sep 17 00:00:00 2001 From: Wenhui Yang Date: Mon, 5 Jun 2023 21:58:09 +0000 Subject: [PATCH 4/6] Fix face model delete message Add new strings for face model deletion when fingerprint unlock is available. Test: Manual - test on devices and observe the error message is correct. Fixes: 283122570 Change-Id: I0511e58d030b8b63391d8406bfc0447fe33fa9fc --- res/values/strings.xml | 4 ++++ ...tingsRemoveButtonPreferenceController.java | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index c0917ffcefd..bec0448020b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -746,6 +746,10 @@ Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your PIN, pattern, or password to unlock your phone or for authentication in apps. Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your PIN, pattern, or password to unlock your phone. + + Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your fingerprint, PIN, pattern, or password to unlock your phone or for authentication in apps. + + Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your fingerprint, PIN, pattern, or password to unlock your phone. Use Face Unlock to unlock your phone diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java index 7db59584899..1e74ad7c822 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java @@ -21,6 +21,7 @@ import android.app.Dialog; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; +import android.content.pm.PackageManager; import android.hardware.face.Face; import android.hardware.face.FaceManager; import android.os.Bundle; @@ -69,10 +70,22 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final PackageManager pm = getContext().getPackageManager(); + final boolean hasFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT); + final int dialogMessageRes; + + if (hasFingerprint) { + dialogMessageRes = mIsConvenience + ? R.string.security_settings_face_remove_dialog_details_fingerprint_conv + : R.string.security_settings_face_remove_dialog_details_fingerprint; + } else { + dialogMessageRes = mIsConvenience + ? R.string.security_settings_face_settings_remove_dialog_details_convenience + : R.string.security_settings_face_settings_remove_dialog_details; + } + builder.setTitle(R.string.security_settings_face_settings_remove_dialog_title) - .setMessage(mIsConvenience - ? R.string.security_settings_face_settings_remove_dialog_details_convenience - : R.string.security_settings_face_settings_remove_dialog_details) + .setMessage(dialogMessageRes) .setPositiveButton(R.string.delete, mOnClickListener) .setNegativeButton(R.string.cancel, mOnClickListener); AlertDialog dialog = builder.create(); From ea85e3b2fa402ccef41ca2ddd9be645d86125103 Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Tue, 6 Jun 2023 19:45:00 +0800 Subject: [PATCH 5/6] Add the log and moving it into onResume Since user can open two settings app(one is via settings app button and other one is via quick settings) and user can switch them to foreground by the recent page. If user can goto the deviceDetails at Settings_A and then changes the config value at settings_B, then the user goes back Settings_A to check the UI. If config is in the init, the UI can't refresh the UI. Bug: 285086232 Test: build pass. Change-Id: I2284940eddcd02c543522b60f951c0d8d25775fd --- .../BluetoothDetailsProfilesController.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java index aaedebd7634..17304fd13ed 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java @@ -96,12 +96,6 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll protected void init(PreferenceScreen screen) { mProfilesContainer = (PreferenceCategory)screen.findPreference(getPreferenceKey()); mProfilesContainer.setLayoutResource(R.layout.preference_bluetooth_profile_category); - mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, - SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true); - mIsLeAudioToggleEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, - SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, true) - || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, - CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false); // Call refresh here even though it will get called later in onResume, to avoid the // list of switches appearing to "pop" into the page. refresh(); @@ -437,6 +431,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll @Override public void onResume() { + updateLeAudioConfig(); for (CachedBluetoothDevice item : mAllOfCachedDevices) { item.registerCallback(this); } @@ -444,6 +439,20 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll refresh(); } + private void updateLeAudioConfig() { + mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, + SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true); + boolean isLeDeviceDetailEnabled = DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_SETTINGS_UI, + SettingsUIDeviceConfig.BT_LE_AUDIO_DEVICE_DETAIL_ENABLED, true); + boolean isLeEnabledByDefault = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, + CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT, false); + mIsLeAudioToggleEnabled = isLeDeviceDetailEnabled || isLeEnabledByDefault; + Log.d(TAG, "BT_LE_AUDIO_CONTACT_SHARING_ENABLED:" + mIsLeContactSharingEnabled + + ", BT_LE_AUDIO_DEVICE_DETAIL_ENABLED:" + isLeDeviceDetailEnabled + + ", CONFIG_LE_AUDIO_ENABLED_BY_DEFAULT:" + isLeEnabledByDefault); + } + @Override public void onDeviceAttributesChanged() { for (CachedBluetoothDevice item : mAllOfCachedDevices) { From bf7865b27ecc39e47f41707aaf0feb8c45a42c10 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Wed, 7 Jun 2023 16:47:04 +0800 Subject: [PATCH 6/6] [Settings] Fix crash when user enter bluetooth page quickly. - When SliceManager try to pinSlice, process may not have the permssion yet, so in Androix lib it use try/catch to avoid Security exception. However, if SliceManger quickly unpinSlice after pinSlice, process may still not get the permission yet, then due to no security exception, it cause the settings crash. Bug: 283065718 Test: atest passed Test: Manual test passed Change-Id: I2293fca73e65dfaa34237abe57e0c6a3fe0f62bb --- .../BlockingPrefWithSliceController.java | 16 ++++++++++++++-- .../slices/SlicePreferenceController.java | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java index b443047d7e8..93a2747cac0 100644 --- a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java +++ b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java @@ -113,15 +113,27 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im @Override public void onStart() { - if (mLiveData != null) { + if (mLiveData == null) { + return; + } + + try { mLiveData.observeForever(this); + } catch (SecurityException e) { + Log.w(TAG, "observeForever - no permission"); } } @Override public void onStop() { - if (mLiveData != null) { + if (mLiveData == null) { + return; + } + + try { mLiveData.removeObserver(this); + } catch (SecurityException e) { + Log.w(TAG, "removeObserver - no permission"); } } diff --git a/src/com/android/settings/slices/SlicePreferenceController.java b/src/com/android/settings/slices/SlicePreferenceController.java index eb10bd42be1..9a88b5626dc 100644 --- a/src/com/android/settings/slices/SlicePreferenceController.java +++ b/src/com/android/settings/slices/SlicePreferenceController.java @@ -44,7 +44,6 @@ public class SlicePreferenceController extends BasePreferenceController implemen LiveData mLiveData; @VisibleForTesting SlicePreference mSlicePreference; - private boolean mIsObservering = false; private Uri mUri; public SlicePreferenceController(Context context, String preferenceKey) { @@ -74,9 +73,14 @@ public class SlicePreferenceController extends BasePreferenceController implemen @Override public void onStart() { - if (mLiveData != null && !mIsObservering) { - mIsObservering = true; + if (mLiveData == null) { + return; + } + + try { mLiveData.observeForever(this); + } catch (SecurityException e) { + Log.w(TAG, "observeForever - no permission"); } } @@ -91,9 +95,14 @@ public class SlicePreferenceController extends BasePreferenceController implemen } private void removeLiveDataObserver() { - if (mLiveData != null && mIsObservering && mLiveData.hasActiveObservers()) { - mIsObservering = false; + if (mLiveData == null) { + return; + } + + try { mLiveData.removeObserver(this); + } catch (SecurityException e) { + Log.w(TAG, "removeLiveDataObserver - no permission"); } } }