Update dialog UI for bonding loss

Bug: 380801155
Test: atest BluetoothKeyMissingDialogTest
Flag: com.android.settings.flags.enable_bluetooth_key_missing_dialog
Change-Id: I0530d6a590666684578f3e94fc8f0da4fae64c7f
This commit is contained in:
Haijie Hong
2025-03-12 13:32:08 +08:00
parent 8a333df6fa
commit 3ac9b6baaa
4 changed files with 44 additions and 21 deletions

View File

@@ -29,7 +29,6 @@
android:paddingEnd="24dp"> android:paddingEnd="24dp">
<ImageView <ImageView
android:id="@id/preview_placeholder"
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="32dp" android:layout_height="32dp"
android:layout_gravity="center" android:layout_gravity="center"
@@ -41,14 +40,16 @@
android:id="@+id/bluetooth_key_missing_title" android:id="@+id/bluetooth_key_missing_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="16dp"
android:gravity="center" android:gravity="center"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Title" /> android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Title" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="16dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:text="@string/bluetooth_key_missing_message" android:text="@string/bluetooth_key_missing_message"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" /> android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" />

View File

@@ -2073,13 +2073,17 @@
<string name="bluetooth_scan_change">Change</string> <string name="bluetooth_scan_change">Change</string>
<!-- Dialog title when key is missing in a Bluetooth device --> <!-- Dialog title when key is missing in a Bluetooth device -->
<string name="bluetooth_key_missing_title"><xliff:g id="device_name">%1$s</xliff:g> not connected</string> <string name="bluetooth_key_missing_title">Cant connect <xliff:g id="device_name">%1$s</xliff:g></string>
<!-- Dialog content when key is missing in a Bluetooth device --> <!-- Dialog content when key is missing in a Bluetooth device -->
<string name="bluetooth_key_missing_message">For your security, forget this device, then pair it again</string> <string name="bluetooth_key_missing_message">For more details, go to device settings</string>
<!-- Button text to forget device when bluetooth key is missing --> <!-- Button text to forget device when bluetooth key is missing -->
<string name="bluetooth_key_missing_forget">Forget device</string> <string name="bluetooth_key_missing_forget">Forget device</string>
<!-- Button text to cancel when bluetooth key is missing--> <!-- Button text to cancel when bluetooth key is missing-->
<string name="bluetooth_key_missing_cancel">Cancel</string> <string name="bluetooth_key_missing_cancel">Cancel</string>
<!-- Button text to go to device settings when bluetooth key is missing -->
<string name="bluetooth_key_missing_device_settings">Device settings</string>
<!-- Button text to close the bluetooth key missing dialog-->
<string name="bluetooth_key_missing_close">Close</string>
<!-- Title of device details screen [CHAR LIMIT=28]--> <!-- Title of device details screen [CHAR LIMIT=28]-->
<string name="device_details_title">Device details</string> <string name="device_details_title">Device details</string>
@@ -2109,6 +2113,8 @@
<string name="device_details_battery">Battery</string> <string name="device_details_battery">Battery</string>
<!-- Content Description for battery charging icon in device details screen [CHAR LIMIT=NONE]--> <!-- Content Description for battery charging icon in device details screen [CHAR LIMIT=NONE]-->
<string name="device_details_battery_charging">Battery, charging</string> <string name="device_details_battery_charging">Battery, charging</string>
<!-- Title of item to let user know the bluetooth key is missing [CHAR LIMIT=NONE]-->
<string name="device_details_key_missing_title">Try restarting <xliff:g id="device_name">%1$s</xliff:g>. If that doesnt work, forget the device. For your security, only pair it again when you arent in a public space.\n\nIf this device isnt nearby, you dont need to do anything.</string>
<!-- Bluetooth device details. In the confirmation dialog for unpairing a paired device, this is the label on the button that will complete the unpairing action. --> <!-- Bluetooth device details. In the confirmation dialog for unpairing a paired device, this is the label on the button that will complete the unpairing action. -->

View File

@@ -30,17 +30,18 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
/** /**
* A dialogFragment used by {@link BluetoothKeyMissingDialog} to create a dialog for the * A dialogFragment used by {@link BluetoothKeyMissingDialog} to create a dialog for the bluetooth
* bluetooth device. * device.
*/ */
public class BluetoothKeyMissingDialogFragment extends InstrumentedDialogFragment public class BluetoothKeyMissingDialogFragment extends InstrumentedDialogFragment
implements OnClickListener { implements OnClickListener {
private static final String TAG = "BTKeyMissingDialogFragment"; private static final String TAG = "BTKeyMissingDialogFrg";
private static final String KEY_CACHED_DEVICE_ADDRESS = "cached_device"; private static final String KEY_CACHED_DEVICE_ADDRESS = "cached_device";
private BluetoothDevice mBluetoothDevice; private BluetoothDevice mBluetoothDevice;
@@ -67,8 +68,8 @@ public class BluetoothKeyMissingDialogFragment extends InstrumentedDialogFragmen
keyMissingTitle.setText( keyMissingTitle.setText(
getString(R.string.bluetooth_key_missing_title, mBluetoothDevice.getName())); getString(R.string.bluetooth_key_missing_title, mBluetoothDevice.getName()));
builder.setView(view); builder.setView(view);
builder.setPositiveButton(getString(R.string.bluetooth_key_missing_forget), this); builder.setPositiveButton(getString(R.string.bluetooth_key_missing_device_settings), this);
builder.setNegativeButton(getString(R.string.bluetooth_key_missing_cancel), this); builder.setNegativeButton(getString(R.string.bluetooth_key_missing_close), this);
AlertDialog dialog = builder.create(); AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false); dialog.setCanceledOnTouchOutside(false);
return dialog; return dialog;
@@ -85,11 +86,18 @@ public class BluetoothKeyMissingDialogFragment extends InstrumentedDialogFragmen
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) { if (which == DialogInterface.BUTTON_POSITIVE) {
Log.i( Log.i(TAG, "Positive button clicked for " + mBluetoothDevice.getAnonymizedAddress());
TAG, Bundle args = new Bundle();
"Positive button clicked, remove bond for " args.putString(
+ mBluetoothDevice.getAnonymizedAddress()); BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS,
mBluetoothDevice.removeBond(); mBluetoothDevice.getAddress());
new SubSettingLauncher(requireContext())
.setDestination(BluetoothDeviceDetailsFragment.class.getName())
.setArguments(args)
.setTitleRes(R.string.device_details_title)
.setSourceMetricsCategory(getMetricsCategory())
.launch();
} else if (which == DialogInterface.BUTTON_NEGATIVE) { } else if (which == DialogInterface.BUTTON_NEGATIVE) {
Log.i(TAG, "Negative button clicked for " + mBluetoothDevice.getAnonymizedAddress()); Log.i(TAG, "Negative button clicked for " + mBluetoothDevice.getAnonymizedAddress());
} }

View File

@@ -17,16 +17,18 @@ package com.android.settings.bluetooth;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper; import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -40,6 +42,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowIntent;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowAlertDialogCompat.class, ShadowBluetoothUtils.class}) @Config(shadows = {ShadowAlertDialogCompat.class, ShadowBluetoothUtils.class})
@@ -71,18 +74,23 @@ public class BluetoothKeyMissingDialogTest {
} }
@Test @Test
public void clickForgetDevice_removeBond() { public void clickDeviceSettings_launchDeviceDetails() {
mFragment.onClick(mFragment.getDialog(), AlertDialog.BUTTON_POSITIVE); mFragment.onClick(mFragment.getDialog(), AlertDialog.BUTTON_POSITIVE);
verify(mBluetoothDevice).removeBond(); Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
ShadowIntent shadowIntent = shadowOf(startedIntent);
assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(BluetoothDeviceDetailsFragment.class.getName());
assertThat(mActivity.isFinishing()).isTrue(); assertThat(mActivity.isFinishing()).isTrue();
} }
@Test @Test
public void clickCancel_notRemoveBond() { public void clickCancel_notLaunchDeviceDetails() {
mFragment.onClick(mFragment.getDialog(), AlertDialog.BUTTON_NEGATIVE); mFragment.onClick(mFragment.getDialog(), AlertDialog.BUTTON_NEGATIVE);
verify(mBluetoothDevice, never()).removeBond(); Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
assertThat(startedIntent).isNull();
assertThat(mActivity.isFinishing()).isTrue(); assertThat(mActivity.isFinishing()).isTrue();
} }
} }