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

Commit 9f4aa9cc authored by Zhengping Jiang's avatar Zhengping Jiang
Browse files

Check Bluetooth HID connection status changed before wake up

Only wake up device if the connection state changes to connected from
a different state.

Allow bluetooth wake up if bluetooth.power.suspend.hid_wake_up.enabled
is true.

Bug: 440645135
Test: m -j
Test: atest PhoneWindowManagerTests
Flag: com.android.hardware.input.bluetooth_wakeup_state_check
Change-Id: Icd4d4bea428313d88ee736d7734c1c9b8c7f6e61
parent 8136c6cf
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -269,3 +269,10 @@ flag {
  description: "Enables new keyboard shortcuts to adjust keyboard backlight"
  bug: "401626732"
}

flag {
    name: "bluetooth_wakeup_state_check"
    namespace: "desktop_pnp"
    description: "Check Bluetooth HID profile connection state is changed before waking up the device."
    bug: "440645135"
}
+17 −2
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;

import static com.android.hardware.input.Flags.bluetoothWakeupStateCheck;
import static com.android.hardware.input.Flags.enableNew25q2Keycodes;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN;
@@ -5269,10 +5270,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    BroadcastReceiver mBluetoothHidReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (bluetoothWakeupStateCheck() && !SystemProperties.getBoolean(
                    "bluetooth.power.suspend.hid_wake_up.enabled", false)) {
                Slog.d(TAG, "Bluetooth HID wake up disabled.");
                return;
            }
            if (ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
                Integer state = (Integer) intent.getExtra(BluetoothProfile.EXTRA_STATE);
                Integer newState = (Integer) intent.getExtra(BluetoothProfile.EXTRA_STATE);
                Integer prevState = (Integer) intent.getExtra(
                        BluetoothProfile.EXTRA_PREVIOUS_STATE);
                final boolean interactive = mDefaultDisplayPolicy.isAwake();
                if (state != null && !interactive && state == STATE_CONNECTED) {
                if (bluetoothWakeupStateCheck()
                        && (newState == null || prevState == null || prevState.equals(newState))) {
                    if (DEBUG_WAKEUP) {
                        Slog.w(TAG, "Bluetooth connection state does not change: " + intent);
                    }
                    return;
                }
                if (newState != null && !interactive && newState.equals(STATE_CONNECTED)) {
                    mWindowWakeUpPolicy.wakeUpFromBluetooth();
                }
            }
+19 −2
Original line number Diff line number Diff line
@@ -23,15 +23,17 @@ import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerGlobal.ADD_OKAY;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH;
import static com.android.hardware.input.Flags.FLAG_BLUETOOTH_WAKEUP_STATE_CHECK;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
@@ -68,6 +70,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.SystemProperties;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
@@ -81,6 +84,7 @@ import android.testing.TestableContext;

import androidx.test.filters.SmallTest;

import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.internal.util.test.LocalServiceKeeperRule;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemServiceManager;
@@ -103,6 +107,7 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.quality.Strictness;

import java.util.List;

@@ -166,10 +171,16 @@ public class PhoneWindowManagerTests {

    private static final int INTERCEPT_SYSTEM_KEY_NOT_CONSUMED_DELAY = 0;

    private StaticMockitoSession mMockitoSession;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
        mMockitoSession = mockitoSession()
                .mockStatic(SystemProperties.class)
                .strictness(Strictness.LENIENT)
                .startMocking();

        mOffsettableClock = new OffsettableClock.Stopped();

@@ -205,6 +216,7 @@ public class PhoneWindowManagerTests {
    public void tearDown() {
        reset(ActivityManager.getService());
        reset(mContext);
        mMockitoSession.finishMocking();
    }

    @Test
@@ -595,12 +607,17 @@ public class PhoneWindowManagerTests {
    }

    @Test
    @EnableFlags(FLAG_BLUETOOTH_WAKEUP_STATE_CHECK)
    public void testBluetoothHidConnectionBroadcastCanWakeup() {
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC)).thenReturn(true);
        doReturn(true).when(() -> SystemProperties.getBoolean(
                                eq("bluetooth.power.suspend.hid_wake_up.enabled"), eq(false)));

        initNonSpyPhoneWindowManager();

        final Intent intent = new Intent(ACTION_CONNECTION_STATE_CHANGED);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
        ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
        verify(mContext).registerReceiver(captor.capture(), argThat(intentFilter ->