[Battery refactor] Move stylus related functions to BluetoothUtils as util functions.

Test: com.android.settings.bluetooth.BluetoothDeviceDetailsFragment, com.android.settings.connecteddevice.stylus.StylusDevicesControllerTest
Bug: 397847825
Flag: EXEMPT utils function
Change-Id: I6819844cd686fe29b8b1c760c3e4035787a2b903
This commit is contained in:
Ze Li
2025-02-20 15:35:01 +08:00
parent 5703095c5c
commit 6a29b1c779
4 changed files with 14 additions and 109 deletions

View File

@@ -26,7 +26,6 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserManager;
@@ -56,6 +55,7 @@ import com.android.settings.inputmethod.KeyboardSettingsPreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.SlicePreferenceController;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -184,21 +184,6 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
return getSystemService(UserManager.class);
}
@Nullable
@VisibleForTesting
InputDevice getInputDevice(Context context) {
InputManager im = context.getSystemService(InputManager.class);
for (int deviceId : im.getInputDeviceIds()) {
String btAddress = im.getInputDeviceBluetoothAddress(deviceId);
if (btAddress != null && btAddress.equals(mDeviceAddress)) {
return im.getInputDevice(deviceId);
}
}
return null;
}
public static BluetoothDeviceDetailsFragment newInstance(String deviceAddress) {
Bundle args = new Bundle(1);
args.putString(KEY_DEVICE_ADDRESS, deviceAddress);
@@ -217,7 +202,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
if (FeatureFlagUtils.isEnabled(context,
FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES)) {
mInputDevice = getInputDevice(context);
mInputDevice = BluetoothUtils.getInputDevice(context, mDeviceAddress);
}
super.onAttach(context);
@@ -498,7 +483,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
@VisibleForTesting
void setTitleForInputDevice() {
if (StylusDevicesController.isDeviceStylus(mInputDevice, mCachedDevice)) {
if (BluetoothUtils.isDeviceStylus(mInputDevice, mCachedDevice)) {
// This will override the default R.string.device_details_title "Device Details"
// that will show on non-stylus bluetooth devices.
// That title is set via the manifest and also from BluetoothDeviceUpdater.

View File

@@ -18,7 +18,6 @@ package com.android.settings.connecteddevice.stylus;
import android.app.Dialog;
import android.app.role.RoleManager;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -30,7 +29,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -105,7 +103,7 @@ public class StylusDevicesController extends AbstractPreferenceController implem
@Override
public boolean isAvailable() {
return isDeviceStylus(mInputDevice, mCachedBluetoothDevice);
return BluetoothUtils.isDeviceStylus(mInputDevice, mCachedBluetoothDevice);
}
@Nullable
@@ -367,31 +365,4 @@ public class StylusDevicesController extends AbstractPreferenceController implem
createProfileDialogClickCallback(intent, users));
mDialog.show();
}
/**
* 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

@@ -87,6 +87,7 @@ public class BluetoothDeviceDetailsFragmentTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
private static final int TEST_DEVICE_ID = 123;
private BluetoothDeviceDetailsFragment mFragment;
private Context mContext;
@@ -115,10 +116,12 @@ public class BluetoothDeviceDetailsFragmentTest {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mInputManager).when(mContext).getSystemService(InputManager.class);
doReturn(new int[]{TEST_DEVICE_ID}).when(mInputManager).getInputDeviceIds();
doReturn(TEST_ADDRESS).when(mInputManager).getInputDeviceBluetoothAddress(TEST_DEVICE_ID);
doReturn(mCompanionDeviceManager).when(mContext)
.getSystemService(CompanionDeviceManager.class);
when(mCompanionDeviceManager.getAllAssociations()).thenReturn(ImmutableList.of());
removeInputDeviceWithMatchingBluetoothAddress();
FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest();
when(fakeFeatureFactory.mBluetoothFeatureProvider.getDeviceDetailsFragmentFormatter(any(),
any(), any(), eq(mCachedDevice), any())).thenReturn(mFormatter);
@@ -142,10 +145,10 @@ public class BluetoothDeviceDetailsFragmentTest {
public void verifyOnAttachResult_flagEnabledAndInputDeviceSet_returnsInputDevice() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
true);
InputDevice inputDevice = createInputDeviceWithMatchingBluetoothAddress();
InputDevice inputDevice = mock(InputDevice.class);
BluetoothDeviceDetailsFragment fragment = setupFragment();
FragmentActivity activity = mock(FragmentActivity.class);
doReturn(inputDevice).when(fragment).getInputDevice(any());
doReturn(inputDevice).when(mInputManager).getInputDevice(TEST_DEVICE_ID);
doReturn(activity).when(fragment).getActivity();
fragment.onAttach(mContext);
@@ -160,10 +163,10 @@ public class BluetoothDeviceDetailsFragmentTest {
public void verifyOnAttachResult_flagDisabled_returnsNullInputDevice() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
false);
InputDevice inputDevice = createInputDeviceWithMatchingBluetoothAddress();
InputDevice inputDevice = mock(InputDevice.class);
BluetoothDeviceDetailsFragment fragment = setupFragment();
FragmentActivity activity = mock(FragmentActivity.class);
doReturn(inputDevice).when(fragment).getInputDevice(any());
doReturn(inputDevice).when(mInputManager).getInputDevice(TEST_DEVICE_ID);
doReturn(activity).when(fragment).getActivity();
fragment.onAttach(mContext);
@@ -190,7 +193,7 @@ public class BluetoothDeviceDetailsFragmentTest {
true);
InputDevice inputDevice = mock(InputDevice.class);
doReturn(true).when(inputDevice).supportsSource(InputDevice.SOURCE_STYLUS);
doReturn(inputDevice).when(mFragment).getInputDevice(mContext);
doReturn(inputDevice).when(mInputManager).getInputDevice(TEST_DEVICE_ID);
mFragment.onAttach(mContext);
mFragment.setTitleForInputDevice();
@@ -203,7 +206,7 @@ public class BluetoothDeviceDetailsFragmentTest {
public void getTitle_inputDeviceNull_doesNotSetTitle() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
true);
doReturn(null).when(mFragment).getInputDevice(mContext);
doReturn(null).when(mInputManager).getInputDevice(TEST_DEVICE_ID);
mFragment.onAttach(mContext);
mFragment.setTitleForInputDevice();
@@ -268,20 +271,6 @@ public class BluetoothDeviceDetailsFragmentTest {
KEY_HEARING_DEVICE_SETTINGS))).isTrue();
}
private InputDevice createInputDeviceWithMatchingBluetoothAddress() {
doReturn(new int[]{0}).when(mInputManager).getInputDeviceIds();
InputDevice device = mock(InputDevice.class);
doReturn(TEST_ADDRESS).when(mInputManager).getInputDeviceBluetoothAddress(0);
doReturn(device).when(mInputManager).getInputDevice(0);
return device;
}
private InputDevice removeInputDeviceWithMatchingBluetoothAddress() {
doReturn(new int[]{0}).when(mInputManager).getInputDeviceIds();
doReturn(null).when(mInputManager).getInputDeviceBluetoothAddress(0);
return null;
}
private BluetoothDeviceDetailsFragment setupFragment() {
BluetoothDeviceDetailsFragment fragment = spy(
BluetoothDeviceDetailsFragment.newInstance(TEST_ADDRESS));

View File

@@ -189,46 +189,6 @@ public class StylusDevicesControllerTest {
mController = new StylusDevicesController(mContext, mInputDevice, null, mLifecycle);
}
@Test
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(