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:
@@ -312,7 +312,8 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
|||||||
mCachedDevice, lifecycle));
|
mCachedDevice, lifecycle));
|
||||||
controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice,
|
controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice,
|
||||||
lifecycle));
|
lifecycle));
|
||||||
controllers.add(new StylusDevicesController(context, mInputDevice, lifecycle));
|
controllers.add(new StylusDevicesController(context, mInputDevice, mCachedDevice,
|
||||||
|
lifecycle));
|
||||||
controllers.add(new BluetoothDetailsRelatedToolsController(context, this, mCachedDevice,
|
controllers.add(new BluetoothDetailsRelatedToolsController(context, this, mCachedDevice,
|
||||||
lifecycle));
|
lifecycle));
|
||||||
controllers.add(new BluetoothDetailsPairOtherController(context, this, mCachedDevice,
|
controllers.add(new BluetoothDetailsPairOtherController(context, this, mCachedDevice,
|
||||||
|
@@ -17,12 +17,14 @@
|
|||||||
package com.android.settings.connecteddevice.stylus;
|
package com.android.settings.connecteddevice.stylus;
|
||||||
|
|
||||||
import android.app.role.RoleManager;
|
import android.app.role.RoleManager;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
|
|
||||||
@@ -34,6 +36,8 @@ import androidx.preference.PreferenceScreen;
|
|||||||
import androidx.preference.SwitchPreference;
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
import com.android.settings.R;
|
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.AbstractPreferenceController;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
@@ -61,18 +65,23 @@ public class StylusDevicesController extends AbstractPreferenceController implem
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final InputDevice mInputDevice;
|
private final InputDevice mInputDevice;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final CachedBluetoothDevice mCachedBluetoothDevice;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
PreferenceCategory mPreferencesContainer;
|
PreferenceCategory mPreferencesContainer;
|
||||||
|
|
||||||
public StylusDevicesController(Context context, InputDevice inputDevice, Lifecycle lifecycle) {
|
public StylusDevicesController(Context context, InputDevice inputDevice,
|
||||||
|
CachedBluetoothDevice cachedBluetoothDevice, Lifecycle lifecycle) {
|
||||||
super(context);
|
super(context);
|
||||||
mInputDevice = inputDevice;
|
mInputDevice = inputDevice;
|
||||||
|
mCachedBluetoothDevice = cachedBluetoothDevice;
|
||||||
lifecycle.addObserver(this);
|
lifecycle.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
return mInputDevice != null && mInputDevice.supportsSource(InputDevice.SOURCE_STYLUS);
|
return isDeviceStylus(mInputDevice, mCachedBluetoothDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -179,13 +188,11 @@ public class StylusDevicesController extends AbstractPreferenceController implem
|
|||||||
private void refresh() {
|
private void refresh() {
|
||||||
if (!isAvailable()) return;
|
if (!isAvailable()) return;
|
||||||
|
|
||||||
if (mInputDevice.getBluetoothAddress() != null) {
|
Preference notesPref = mPreferencesContainer.findPreference(KEY_DEFAULT_NOTES);
|
||||||
Preference notesPref = mPreferencesContainer.findPreference(KEY_DEFAULT_NOTES);
|
if (notesPref == null) {
|
||||||
if (notesPref == null) {
|
notesPref = createDefaultNotesPreference();
|
||||||
notesPref = createDefaultNotesPreference();
|
if (notesPref != null) {
|
||||||
if (notesPref != null) {
|
mPreferencesContainer.addPreference(notesPref);
|
||||||
mPreferencesContainer.addPreference(notesPref);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,4 +208,32 @@ public class StylusDevicesController extends AbstractPreferenceController implem
|
|||||||
mPreferencesContainer.addPreference(createButtonPressPreference());
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,7 @@ public class StylusUsiDetailsFragment extends DashboardFragment {
|
|||||||
if (mInputDevice != null) {
|
if (mInputDevice != null) {
|
||||||
Lifecycle lifecycle = getSettingsLifecycle();
|
Lifecycle lifecycle = getSettingsLifecycle();
|
||||||
controllers.add(new StylusUsiHeaderController(context, mInputDevice));
|
controllers.add(new StylusUsiHeaderController(context, mInputDevice));
|
||||||
controllers.add(new StylusDevicesController(context, mInputDevice, lifecycle));
|
controllers.add(new StylusDevicesController(context, mInputDevice, null, lifecycle));
|
||||||
}
|
}
|
||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.role.RoleManager;
|
import android.app.role.RoleManager;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
@@ -44,6 +45,7 @@ import androidx.preference.SwitchPreference;
|
|||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -76,6 +78,10 @@ public class StylusDevicesControllerTest {
|
|||||||
private RoleManager mRm;
|
private RoleManager mRm;
|
||||||
@Mock
|
@Mock
|
||||||
private Lifecycle mLifecycle;
|
private Lifecycle mLifecycle;
|
||||||
|
@Mock
|
||||||
|
private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||||
|
@Mock
|
||||||
|
private BluetoothDevice mBluetoothDevice;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -101,24 +107,94 @@ public class StylusDevicesControllerTest {
|
|||||||
any(PackageManager.ApplicationInfoFlags.class))).thenReturn(new ApplicationInfo());
|
any(PackageManager.ApplicationInfoFlags.class))).thenReturn(new ApplicationInfo());
|
||||||
when(mPm.getApplicationLabel(any(ApplicationInfo.class))).thenReturn(NOTES_APP_LABEL);
|
when(mPm.getApplicationLabel(any(ApplicationInfo.class))).thenReturn(NOTES_APP_LABEL);
|
||||||
|
|
||||||
|
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
|
||||||
|
|
||||||
mInputDevice = spy(new InputDevice.Builder()
|
mInputDevice = spy(new InputDevice.Builder()
|
||||||
.setId(1)
|
.setId(1)
|
||||||
.setSources(InputDevice.SOURCE_STYLUS)
|
.setSources(InputDevice.SOURCE_STYLUS)
|
||||||
.build());
|
.build());
|
||||||
when(mInputDevice.getBluetoothAddress()).thenReturn("SOME:ADDRESS");
|
when(mInputDevice.getBluetoothAddress()).thenReturn("SOME:ADDRESS");
|
||||||
|
|
||||||
mController = new StylusDevicesController(mContext, mInputDevice, mLifecycle);
|
mController = new StylusDevicesController(mContext, mInputDevice, null, mLifecycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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(
|
StylusDevicesController controller = new StylusDevicesController(
|
||||||
mContext, null, mLifecycle
|
mContext, null, null, mLifecycle
|
||||||
);
|
);
|
||||||
|
|
||||||
showScreen(controller);
|
showScreen(controller);
|
||||||
|
|
||||||
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(0);
|
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
|
@Test
|
||||||
public void btStylusInputDevice_showsAllPreferences() {
|
public void btStylusInputDevice_showsAllPreferences() {
|
||||||
showScreen(mController);
|
showScreen(mController);
|
||||||
|
Reference in New Issue
Block a user