diff --git a/res/values/strings.xml b/res/values/strings.xml index c0917ffcefd..e70f96d973a 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 @@ -10573,7 +10577,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 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(); diff --git a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java index 355a9960d07..0690186b972 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/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) { 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) 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/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"); } } } 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"); }