Merge "Add the way for hiding the "contact sharing" on the pairing dialog" into tm-qpr-dev

This commit is contained in:
SongFerng Wang
2022-09-28 19:45:33 +00:00
committed by Android (Google) Code Review
4 changed files with 234 additions and 17 deletions

View File

@@ -17,8 +17,10 @@ package com.android.settings.bluetooth;
import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.provider.DeviceConfig;
import android.text.Editable; import android.text.Editable;
import android.util.Log; import android.util.Log;
import android.widget.CompoundButton; import android.widget.CompoundButton;
@@ -28,6 +30,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.bluetooth.BluetoothPairingDialogFragment.BluetoothPairingDialogListener; import com.android.settings.bluetooth.BluetoothPairingDialogFragment.BluetoothPairingDialogListener;
import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfile;
@@ -54,7 +57,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
private static final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6; private static final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6;
// Bluetooth dependencies for the connection we are trying to establish // Bluetooth dependencies for the connection we are trying to establish
private LocalBluetoothManager mBluetoothManager; LocalBluetoothManager mBluetoothManager;
private BluetoothDevice mDevice; private BluetoothDevice mDevice;
@VisibleForTesting @VisibleForTesting
int mType; int mType;
@@ -66,6 +69,8 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
private LocalBluetoothProfile mPbapClientProfile; private LocalBluetoothProfile mPbapClientProfile;
private boolean mPbapAllowed; private boolean mPbapAllowed;
private boolean mIsCoordinatedSetMember; private boolean mIsCoordinatedSetMember;
private boolean mIsLeAudio;
private boolean mIsLeContactSharingEnabled;
/** /**
* Creates an instance of a BluetoothPairingController. * Creates an instance of a BluetoothPairingController.
@@ -92,10 +97,26 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
mDeviceName = mBluetoothManager.getCachedDeviceManager().getName(mDevice); mDeviceName = mBluetoothManager.getCachedDeviceManager().getName(mDevice);
mPbapClientProfile = mBluetoothManager.getProfileManager().getPbapClientProfile(); mPbapClientProfile = mBluetoothManager.getProfileManager().getPbapClientProfile();
mPasskeyFormatted = formatKey(mPasskey); mPasskeyFormatted = formatKey(mPasskey);
final CachedBluetoothDevice cachedDevice = final CachedBluetoothDevice cachedDevice =
mBluetoothManager.getCachedDeviceManager().findDevice(mDevice); mBluetoothManager.getCachedDeviceManager().findDevice(mDevice);
mIsCoordinatedSetMember = cachedDevice != null
? cachedDevice.isCoordinatedSetMemberDevice() : false; mIsCoordinatedSetMember = false;
mIsLeAudio = false;
mIsLeContactSharingEnabled = true;
if (cachedDevice != null) {
mIsCoordinatedSetMember = cachedDevice.isCoordinatedSetMemberDevice();
for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
if (profile.getProfileId() == BluetoothProfile.LE_AUDIO) {
mIsLeAudio = true;
}
}
mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true);
Log.d(TAG, "BT_LE_AUDIO_CONTACT_SHARING_ENABLED is " + mIsLeContactSharingEnabled);
}
} }
@Override @Override
@@ -180,6 +201,30 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
return mPbapClientProfile != null && mPbapClientProfile.isProfileReady(); return mPbapClientProfile != null && mPbapClientProfile.isProfileReady();
} }
@VisibleForTesting
boolean isLeAudio() {
return mIsLeAudio;
}
@VisibleForTesting
boolean isLeContactSharingEnabled() {
return mIsLeContactSharingEnabled;
}
/**
* A method whether the device allows to show the le audio's contact sharing.
*
* @return A boolean whether the device allows to show the contact sharing.
*/
public boolean isContactSharingVisible() {
boolean isContactSharingVisible = !isProfileReady();
// If device do not support the ContactSharing of LE audio device, hiding ContactSharing UI
if (isLeAudio() && !isLeContactSharingEnabled()) {
isContactSharingVisible = false;
}
return isContactSharingVisible;
}
/** /**
* A method for querying if the bluetooth device has access to contacts on the device. * A method for querying if the bluetooth device has access to contacts on the device.
* *
@@ -447,4 +492,9 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
public boolean deviceEquals(BluetoothDevice device) { public boolean deviceEquals(BluetoothDevice device) {
return mDevice == device; return mDevice == device;
} }
@VisibleForTesting
void mockPbapClientProfile(LocalBluetoothProfile mockPbapClientProfile) {
mPbapClientProfile = mockPbapClientProfile;
}
} }

View File

@@ -254,8 +254,8 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
mPairingController.getDeviceName())); mPairingController.getDeviceName()));
EditText pairingView = (EditText) view.findViewById(R.id.text); EditText pairingView = (EditText) view.findViewById(R.id.text);
contactSharing.setVisibility(mPairingController.isProfileReady() contactSharing.setVisibility(
? View.GONE : View.VISIBLE); mPairingController.isContactSharingVisible() ? View.VISIBLE : View.GONE);
mPairingController.setContactSharingState(); mPairingController.setContactSharingState();
contactSharing.setOnCheckedChangeListener(mPairingController); contactSharing.setOnCheckedChangeListener(mPairingController);
contactSharing.setChecked(mPairingController.getContactSharingState()); contactSharing.setChecked(mPairingController.getContactSharingState());
@@ -346,7 +346,7 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
mPairingController.getDeviceName())); mPairingController.getDeviceName()));
contactSharing.setVisibility( contactSharing.setVisibility(
mPairingController.isProfileReady() ? View.GONE : View.VISIBLE); mPairingController.isContactSharingVisible() ? View.VISIBLE : View.GONE);
mPairingController.setContactSharingState(); mPairingController.setContactSharingState();
contactSharing.setChecked(mPairingController.getContactSharingState()); contactSharing.setChecked(mPairingController.getContactSharingState());
contactSharing.setOnCheckedChangeListener(mPairingController); contactSharing.setOnCheckedChangeListener(mPairingController);
@@ -363,5 +363,4 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
? View.VISIBLE : View.GONE); ? View.VISIBLE : View.GONE);
return view; return view;
} }
} }

View File

@@ -17,16 +17,28 @@ package com.android.settings.bluetooth;
import static android.bluetooth.BluetoothDevice.PAIRING_VARIANT_CONSENT; import static android.bluetooth.BluetoothDevice.PAIRING_VARIANT_CONSENT;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Parcel; import android.os.Parcel;
import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -36,16 +48,36 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class}) @Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class,
ShadowDeviceConfig.class})
public class BluetoothPairingControllerTest { public class BluetoothPairingControllerTest {
private final BluetoothClass mBluetoothClass = private final BluetoothClass mBluetoothClass =
createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE); createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
@Mock
private CachedBluetoothDeviceManager mCachedDeviceManager;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
@Mock
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
@Mock @Mock
private BluetoothDevice mBluetoothDevice; private BluetoothDevice mBluetoothDevice;
@Mock
private CachedBluetoothDevice mCachedDevice;
@Mock
private LocalBluetoothProfile mLocalBluetoothProfile;
@Mock
private LocalBluetoothProfile mPbapLocalBluetoothProfile;
private Context mContext; private Context mContext;
private BluetoothPairingController mBluetoothPairingController; private BluetoothPairingController mBluetoothPairingController;
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
private BluetoothClass createBtClass(int deviceClass) { private BluetoothClass createBtClass(int deviceClass) {
Parcel p = Parcel.obtain(); Parcel p = Parcel.obtain();
@@ -57,14 +89,32 @@ public class BluetoothPairingControllerTest {
return bluetoothClass; return bluetoothClass;
} }
private BluetoothPairingController createBluetoothPairingController() {
final Intent intent = new Intent();
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
return new BluetoothPairingController(intent, mContext);
}
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application; mContext = RuntimeEnvironment.application;
final Intent intent = new Intent(); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); mShadowBluetoothAdapter.setEnabled(true);
mBluetoothPairingController = new BluetoothPairingController(intent, mContext); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice);
List<LocalBluetoothProfile> localBluetoothProfiles = new ArrayList<>();
mockIsLeAudio(false);
localBluetoothProfiles.add(mLocalBluetoothProfile);
when(mCachedDevice.getProfiles()).thenReturn(localBluetoothProfiles);
when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice);
mBluetoothPairingController = createBluetoothPairingController();
mBluetoothPairingController.mockPbapClientProfile(mPbapLocalBluetoothProfile);
} }
@Test @Test
@@ -108,4 +158,124 @@ public class BluetoothPairingControllerTest {
verify(mBluetoothDevice).setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED); verify(mBluetoothDevice).setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED);
} }
@Test
public void isLeAudio_noLeProfile_returnsFalse() {
mockIsLeAudio(false);
mBluetoothPairingController = createBluetoothPairingController();
assertThat(mBluetoothPairingController.isLeAudio()).isFalse();
}
@Test
public void isLeAudio_isLeProfile_returnsTrue() {
mockIsLeAudio(true);
mBluetoothPairingController = createBluetoothPairingController();
assertThat(mBluetoothPairingController.isLeAudio()).isTrue();
}
@Test
public void isLeContactSharingEnabled_configIsFalse_returnsFalse() {
mockIsLeContactSharingEnabled(false);
mBluetoothPairingController = createBluetoothPairingController();
assertThat(mBluetoothPairingController.isLeContactSharingEnabled()).isFalse();
}
@Test
public void isLeContactSharingEnabled_configIsTrue_returnsTrue() {
mockIsLeContactSharingEnabled(true);
mBluetoothPairingController = createBluetoothPairingController();
assertThat(mBluetoothPairingController.isLeContactSharingEnabled()).isTrue();
}
@Test
public void isContactSharingVisible_profileIsNotReady_returnsTrue() {
// isProfileReady=false, isLeAudio=false, isLeContactSharingEnabled=true
mockIsProfileReady(false);
mockIsLeAudio(false);
mockIsLeContactSharingEnabled(true);
mBluetoothPairingController = createBluetoothPairingController();
mBluetoothPairingController.mockPbapClientProfile(mPbapLocalBluetoothProfile);
assertThat(mBluetoothPairingController.isContactSharingVisible()).isTrue();
}
@Test
public void isContactSharingVisible_profileIsReady_returnsFalse() {
// isProfileReady=true, isLeAudio=false, isLeContactSharingEnabled=true
mockIsProfileReady(true);
mockIsLeAudio(false);
mockIsLeContactSharingEnabled(true);
mBluetoothPairingController = createBluetoothPairingController();
mBluetoothPairingController.mockPbapClientProfile(mPbapLocalBluetoothProfile);
assertThat(mBluetoothPairingController.isContactSharingVisible()).isFalse();
}
@Test
public void isContactSharingVisible_DeviceIsLeAudioAndProfileIsReady_returnsFalse() {
// isProfileReady=true, isLeAudio=true, isLeContactSharingEnabled=true
mockIsProfileReady(true);
mockIsLeAudio(true);
mockIsLeContactSharingEnabled(true);
mBluetoothPairingController = createBluetoothPairingController();
mBluetoothPairingController.mockPbapClientProfile(mPbapLocalBluetoothProfile);
assertThat(mBluetoothPairingController.isContactSharingVisible()).isFalse();
}
@Test
public void isContactSharingVisible_DeviceIsLeAudioAndProfileIsNotReady_returnsTrue() {
// isProfileReady=false, isLeAudio=true, isLeContactSharingEnabled=true
mockIsProfileReady(false);
mockIsLeAudio(true);
mockIsLeContactSharingEnabled(true);
mBluetoothPairingController = createBluetoothPairingController();
mBluetoothPairingController.mockPbapClientProfile(mPbapLocalBluetoothProfile);
assertThat(mBluetoothPairingController.isContactSharingVisible()).isTrue();
}
@Test
public void isContactSharingVisible_DeviceIsLeAndContactSharingIsNotEnabled_returnsFalse() {
// isProfileReady=false, isLeAudio=true, isLeContactSharingEnabled=false
mockIsProfileReady(false);
mockIsLeAudio(true);
mockIsLeContactSharingEnabled(false);
mBluetoothPairingController = createBluetoothPairingController();
mBluetoothPairingController.mockPbapClientProfile(mPbapLocalBluetoothProfile);
assertThat(mBluetoothPairingController.isContactSharingVisible()).isFalse();
}
private void mockIsProfileReady(boolean mockValue) {
when(mPbapLocalBluetoothProfile.isProfileReady()).thenReturn(mockValue);
}
private void mockIsLeAudio(boolean mockValue) {
int profileId = BluetoothProfile.HEADSET;
if (mockValue) {
profileId = BluetoothProfile.LE_AUDIO;
}
when(mLocalBluetoothProfile.getProfileId()).thenReturn(profileId);
}
private void mockIsLeContactSharingEnabled(boolean mockValue) {
android.provider.DeviceConfig.setProperty(
android.provider.DeviceConfig.NAMESPACE_SETTINGS_UI,
SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED,
/* value= */ mockValue ? "true" : "false", true);
}
} }

View File

@@ -274,13 +274,12 @@ public class BluetoothPairingDialogTest {
} }
@Test @Test
public void dialogShowsContactSharingCheckboxWhenBluetoothProfileNotReady() { public void contactSharingCheckbox_conditionIsReady_showsUi() {
// set the dialog variant to confirmation/consent // set the dialog variant to confirmation/consent
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG); when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
// set a fake device name and pretend the profile has not been set up for it // set a fake device name and pretend the profile has not been set up for it
when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME); when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME);
when(controller.isProfileReady()).thenReturn(false); when(controller.isContactSharingVisible()).thenReturn(true);
// build the fragment // build the fragment
BluetoothPairingDialogFragment frag = makeFragment(); BluetoothPairingDialogFragment frag = makeFragment();
@@ -292,13 +291,12 @@ public class BluetoothPairingDialogTest {
} }
@Test @Test
public void dialogHidesContactSharingCheckboxWhenBluetoothProfileIsReady() { public void contactSharingCheckbox_conditionIsNotReady_doesNotShowUi() {
// set the dialog variant to confirmation/consent // set the dialog variant to confirmation/consent
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG); when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
// set a fake device name and pretend the profile has been set up for it // set a fake device name and pretend the profile has been set up for it
when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME); when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME);
when(controller.isProfileReady()).thenReturn(true); when(controller.isContactSharingVisible()).thenReturn(false);
// build the fragment // build the fragment
BluetoothPairingDialogFragment frag = makeFragment(); BluetoothPairingDialogFragment frag = makeFragment();