Pass CachedBluetoothDevice into StylusDevicesController.

Styluses can now be identified using the newly added DEVICE_TYPE_STYLUS
metadata.

Bug: 251200056
Test: StylusDevicesControllerTest
Change-Id: Ie89f6419cd16ed97299944b35497c6b2ee764dab
This commit is contained in:
Vania Januar
2022-12-20 10:24:10 +00:00
parent 2b347d7f2d
commit 57822a67a8
4 changed files with 126 additions and 14 deletions

View File

@@ -312,7 +312,8 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
mCachedDevice, lifecycle));
controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice,
lifecycle));
controllers.add(new StylusDevicesController(context, mInputDevice, lifecycle));
controllers.add(new StylusDevicesController(context, mInputDevice, mCachedDevice,
lifecycle));
controllers.add(new BluetoothDetailsRelatedToolsController(context, this, mCachedDevice,
lifecycle));
controllers.add(new BluetoothDetailsPairOtherController(context, this, mCachedDevice,

View File

@@ -17,12 +17,14 @@
package com.android.settings.connecteddevice.stylus;
import android.app.role.RoleManager;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Log;
import android.view.InputDevice;
@@ -34,6 +36,8 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -61,18 +65,23 @@ public class StylusDevicesController extends AbstractPreferenceController implem
@Nullable
private final InputDevice mInputDevice;
@Nullable
private final CachedBluetoothDevice mCachedBluetoothDevice;
@VisibleForTesting
PreferenceCategory mPreferencesContainer;
public StylusDevicesController(Context context, InputDevice inputDevice, Lifecycle lifecycle) {
public StylusDevicesController(Context context, InputDevice inputDevice,
CachedBluetoothDevice cachedBluetoothDevice, Lifecycle lifecycle) {
super(context);
mInputDevice = inputDevice;
mCachedBluetoothDevice = cachedBluetoothDevice;
lifecycle.addObserver(this);
}
@Override
public boolean isAvailable() {
return mInputDevice != null && mInputDevice.supportsSource(InputDevice.SOURCE_STYLUS);
return isDeviceStylus(mInputDevice, mCachedBluetoothDevice);
}
@Nullable
@@ -179,7 +188,6 @@ public class StylusDevicesController extends AbstractPreferenceController implem
private void refresh() {
if (!isAvailable()) return;
if (mInputDevice.getBluetoothAddress() != null) {
Preference notesPref = mPreferencesContainer.findPreference(KEY_DEFAULT_NOTES);
if (notesPref == null) {
notesPref = createDefaultNotesPreference();
@@ -187,7 +195,6 @@ public class StylusDevicesController extends AbstractPreferenceController implem
mPreferencesContainer.addPreference(notesPref);
}
}
}
Preference handwritingPref = mPreferencesContainer.findPreference(KEY_HANDWRITING);
// TODO(b/255732419): add proper InputMethodInfo conditional to show or hide
@@ -201,4 +208,32 @@ public class StylusDevicesController extends AbstractPreferenceController implem
mPreferencesContainer.addPreference(createButtonPressPreference());
}
}
/**
* Identifies whether a device is a stylus using the associated {@link InputDevice} or
* {@link CachedBluetoothDevice}.
*
* InputDevices are only available when the device is USI or Bluetooth-connected, whereas
* CachedBluetoothDevices are available for Bluetooth devices when connected or paired,
* so to handle all cases, both are needed.
*
* @param inputDevice The associated input device of the stylus
* @param cachedBluetoothDevice The associated bluetooth device of the stylus
*/
public static boolean isDeviceStylus(@Nullable InputDevice inputDevice,
@Nullable CachedBluetoothDevice cachedBluetoothDevice) {
if (inputDevice != null && inputDevice.supportsSource(InputDevice.SOURCE_STYLUS)) {
return true;
}
if (cachedBluetoothDevice != null) {
BluetoothDevice bluetoothDevice = cachedBluetoothDevice.getDevice();
String deviceType = BluetoothUtils.getStringMetaData(bluetoothDevice,
BluetoothDevice.METADATA_DEVICE_TYPE);
return TextUtils.equals(deviceType, BluetoothDevice.DEVICE_TYPE_STYLUS);
}
return false;
}
}

View File

@@ -77,7 +77,7 @@ public class StylusUsiDetailsFragment extends DashboardFragment {
if (mInputDevice != null) {
Lifecycle lifecycle = getSettingsLifecycle();
controllers.add(new StylusUsiHeaderController(context, mInputDevice));
controllers.add(new StylusDevicesController(context, mInputDevice, lifecycle));
controllers.add(new StylusDevicesController(context, mInputDevice, null, lifecycle));
}
return controllers;
}

View File

@@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.role.RoleManager;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -44,6 +45,7 @@ import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -76,6 +78,10 @@ public class StylusDevicesControllerTest {
private RoleManager mRm;
@Mock
private Lifecycle mLifecycle;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
@Mock
private BluetoothDevice mBluetoothDevice;
@Before
@@ -101,24 +107,94 @@ public class StylusDevicesControllerTest {
any(PackageManager.ApplicationInfoFlags.class))).thenReturn(new ApplicationInfo());
when(mPm.getApplicationLabel(any(ApplicationInfo.class))).thenReturn(NOTES_APP_LABEL);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mInputDevice = spy(new InputDevice.Builder()
.setId(1)
.setSources(InputDevice.SOURCE_STYLUS)
.build());
when(mInputDevice.getBluetoothAddress()).thenReturn("SOME:ADDRESS");
mController = new StylusDevicesController(mContext, mInputDevice, mLifecycle);
mController = new StylusDevicesController(mContext, mInputDevice, null, mLifecycle);
}
@Test
public void noInputDevice_noPreference() {
public void isDeviceStylus_noDevices_false() {
assertThat(StylusDevicesController.isDeviceStylus(null, null)).isFalse();
}
@Test
public void isDeviceStylus_nonStylusInputDevice_false() {
InputDevice inputDevice = new InputDevice.Builder()
.setSources(InputDevice.SOURCE_DPAD)
.build();
assertThat(StylusDevicesController.isDeviceStylus(inputDevice, null)).isFalse();
}
@Test
public void isDeviceStylus_stylusInputDevice_true() {
InputDevice inputDevice = new InputDevice.Builder()
.setSources(InputDevice.SOURCE_STYLUS)
.build();
assertThat(StylusDevicesController.isDeviceStylus(inputDevice, null)).isTrue();
}
@Test
public void isDeviceStylus_nonStylusBluetoothDevice_false() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
assertThat(StylusDevicesController.isDeviceStylus(null, mCachedBluetoothDevice)).isFalse();
}
@Test
public void isDeviceStylus_stylusBluetoothDevice_true() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
BluetoothDevice.DEVICE_TYPE_STYLUS.getBytes());
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
assertThat(StylusDevicesController.isDeviceStylus(null, mCachedBluetoothDevice)).isTrue();
}
@Test
public void noInputDevice_noBluetoothDevice_noPreference() {
StylusDevicesController controller = new StylusDevicesController(
mContext, null, mLifecycle
mContext, null, null, mLifecycle
);
showScreen(controller);
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(0);
}
@Test
public void noInputDevice_nonStylusBluetoothDevice_noPreference() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
StylusDevicesController controller = new StylusDevicesController(
mContext, null, mCachedBluetoothDevice, mLifecycle
);
showScreen(controller);
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(0);
}
@Test
public void noInputDevice_stylusBluetoothDevice_showsPreference() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
BluetoothDevice.DEVICE_TYPE_STYLUS.getBytes());
StylusDevicesController controller = new StylusDevicesController(
mContext, null, mCachedBluetoothDevice, mLifecycle
);
showScreen(controller);
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(3);
}
@Test
public void btStylusInputDevice_showsAllPreferences() {
showScreen(mController);