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");
}