Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 025fff5a authored by Ze Li's avatar Ze Li Committed by Android (Google) Code Review
Browse files

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

Merge "[Battery refactor] Move stylus related functions to BluetoothUtils as util functions." into main
parents bbf2e6c7 6a29b1c7
Loading
Loading
Loading
Loading
+3 −18
Original line number Diff line number Diff line
@@ -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.
+1 −30
Original line number Diff line number Diff line
@@ -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;
    }
}
+10 −21
Original line number Diff line number Diff line
@@ -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));
+0 −40
Original line number Diff line number Diff line
@@ -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(