summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt136
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt118
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt289
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt190
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt51
6 files changed, 301 insertions, 535 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
deleted file mode 100644
index 154c6e2e3158..000000000000
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.stylus
-
-import android.content.Context
-import android.hardware.BatteryState
-import android.hardware.input.InputManager
-import android.os.Handler
-import android.util.Log
-import android.view.InputDevice
-import androidx.annotation.VisibleForTesting
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import java.util.concurrent.Executor
-import javax.inject.Inject
-
-/**
- * A listener that detects when a stylus has first been used, by detecting 1) the presence of an
- * internal SOURCE_STYLUS with a battery, or 2) any added SOURCE_STYLUS device with a bluetooth
- * address.
- */
-@SysUISingleton
-class StylusFirstUsageListener
-@Inject
-constructor(
- private val context: Context,
- private val inputManager: InputManager,
- private val stylusManager: StylusManager,
- private val featureFlags: FeatureFlags,
- @Background private val executor: Executor,
- @Background private val handler: Handler,
-) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
-
- // Set must be only accessed from the background handler, which is the same handler that
- // runs the StylusManager callbacks.
- private val internalStylusDeviceIds: MutableSet<Int> = mutableSetOf()
- @VisibleForTesting var hasStarted = false
-
- override fun start() {
- if (true) return // TODO(b/261826950): remove on main
- if (hasStarted) return
- if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
- if (inputManager.isStylusEverUsed(context)) return
- if (!hostDeviceSupportsStylusInput()) return
-
- hasStarted = true
- inputManager.inputDeviceIds.forEach(this::onStylusAdded)
- stylusManager.registerCallback(this)
- stylusManager.startListener()
- }
-
- override fun onStylusAdded(deviceId: Int) {
- if (!hasStarted) return
-
- val device = inputManager.getInputDevice(deviceId) ?: return
- if (device.isExternal || !device.supportsSource(InputDevice.SOURCE_STYLUS)) return
-
- try {
- inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
- internalStylusDeviceIds += deviceId
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to register battery listener for $deviceId ${device.name}.")
- }
- }
-
- override fun onStylusRemoved(deviceId: Int) {
- if (!hasStarted) return
-
- if (!internalStylusDeviceIds.contains(deviceId)) return
- try {
- inputManager.removeInputDeviceBatteryListener(deviceId, this)
- internalStylusDeviceIds.remove(deviceId)
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
- }
- }
-
- override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
- if (!hasStarted) return
-
- onRemoteDeviceFound()
- }
-
- override fun onBatteryStateChanged(
- deviceId: Int,
- eventTimeMillis: Long,
- batteryState: BatteryState
- ) {
- if (!hasStarted) return
-
- if (batteryState.isPresent) {
- onRemoteDeviceFound()
- }
- }
-
- private fun onRemoteDeviceFound() {
- inputManager.setStylusEverUsed(context, true)
- cleanupListeners()
- }
-
- private fun cleanupListeners() {
- stylusManager.unregisterCallback(this)
- handler.post {
- internalStylusDeviceIds.forEach {
- inputManager.removeInputDeviceBatteryListener(it, this)
- }
- }
- }
-
- private fun hostDeviceSupportsStylusInput(): Boolean {
- return inputManager.inputDeviceIds
- .asSequence()
- .mapNotNull { inputManager.getInputDevice(it) }
- .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
- }
-
- companion object {
- private val TAG = StylusFirstUsageListener::class.simpleName.orEmpty()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index 302d6a9ca1b7..235495cfa50d 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -18,6 +18,8 @@ package com.android.systemui.stylus
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.hardware.BatteryState
import android.hardware.input.InputManager
import android.os.Handler
import android.util.ArrayMap
@@ -25,6 +27,8 @@ import android.util.Log
import android.view.InputDevice
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -37,25 +41,37 @@ import javax.inject.Inject
class StylusManager
@Inject
constructor(
+ private val context: Context,
private val inputManager: InputManager,
private val bluetoothAdapter: BluetoothAdapter?,
@Background private val handler: Handler,
@Background private val executor: Executor,
-) : InputManager.InputDeviceListener, BluetoothAdapter.OnMetadataChangedListener {
+ private val featureFlags: FeatureFlags,
+) :
+ InputManager.InputDeviceListener,
+ InputManager.InputDeviceBatteryListener,
+ BluetoothAdapter.OnMetadataChangedListener {
private val stylusCallbacks: CopyOnWriteArrayList<StylusCallback> = CopyOnWriteArrayList()
private val stylusBatteryCallbacks: CopyOnWriteArrayList<StylusBatteryCallback> =
CopyOnWriteArrayList()
// This map should only be accessed on the handler
private val inputDeviceAddressMap: MutableMap<Int, String?> = ArrayMap()
+ // This variable should only be accessed on the handler
+ private var hasStarted: Boolean = false
/**
* Starts listening to InputManager InputDevice events. Will also load the InputManager snapshot
* at time of starting.
*/
fun startListener() {
- addExistingStylusToMap()
- inputManager.registerInputDeviceListener(this, handler)
+ handler.post {
+ if (hasStarted) return@post
+ hasStarted = true
+ addExistingStylusToMap()
+
+ inputManager.registerInputDeviceListener(this, handler)
+ }
}
/** Registers a StylusCallback to listen to stylus events. */
@@ -77,21 +93,30 @@ constructor(
}
override fun onInputDeviceAdded(deviceId: Int) {
+ if (!hasStarted) return
+
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
+ if (!device.isExternal) {
+ registerBatteryListener(deviceId)
+ }
+
// TODO(b/257936830): get address once input api available
val btAddress: String? = null
inputDeviceAddressMap[deviceId] = btAddress
executeStylusCallbacks { cb -> cb.onStylusAdded(deviceId) }
if (btAddress != null) {
+ onStylusUsed()
onStylusBluetoothConnected(btAddress)
executeStylusCallbacks { cb -> cb.onStylusBluetoothConnected(deviceId, btAddress) }
}
}
override fun onInputDeviceChanged(deviceId: Int) {
+ if (!hasStarted) return
+
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
@@ -112,7 +137,10 @@ constructor(
}
override fun onInputDeviceRemoved(deviceId: Int) {
+ if (!hasStarted) return
+
if (!inputDeviceAddressMap.contains(deviceId)) return
+ unregisterBatteryListener(deviceId)
val btAddress: String? = inputDeviceAddressMap[deviceId]
inputDeviceAddressMap.remove(deviceId)
@@ -124,13 +152,14 @@ constructor(
}
override fun onMetadataChanged(device: BluetoothDevice, key: Int, value: ByteArray?) {
- handler.post executeMetadataChanged@{
- if (key != BluetoothDevice.METADATA_MAIN_CHARGING || value == null)
- return@executeMetadataChanged
+ handler.post {
+ if (!hasStarted) return@post
+
+ if (key != BluetoothDevice.METADATA_MAIN_CHARGING || value == null) return@post
val inputDeviceId: Int =
inputDeviceAddressMap.filterValues { it == device.address }.keys.firstOrNull()
- ?: return@executeMetadataChanged
+ ?: return@post
val isCharging = String(value) == "true"
@@ -140,6 +169,24 @@ constructor(
}
}
+ override fun onBatteryStateChanged(
+ deviceId: Int,
+ eventTimeMillis: Long,
+ batteryState: BatteryState
+ ) {
+ handler.post {
+ if (!hasStarted) return@post
+
+ if (batteryState.isPresent) {
+ onStylusUsed()
+ }
+
+ executeStylusBatteryCallbacks { cb ->
+ cb.onStylusUsiBatteryStateChanged(deviceId, eventTimeMillis, batteryState)
+ }
+ }
+ }
+
private fun onStylusBluetoothConnected(btAddress: String) {
val device: BluetoothDevice = bluetoothAdapter?.getRemoteDevice(btAddress) ?: return
try {
@@ -158,6 +205,21 @@ constructor(
}
}
+ /**
+ * An InputDevice that supports [InputDevice.SOURCE_STYLUS] may still be present even when a
+ * physical stylus device has never been used. This method is run when 1) a USI stylus battery
+ * event happens, or 2) a bluetooth stylus is connected, as they are both indicators that a
+ * physical stylus device has actually been used.
+ */
+ private fun onStylusUsed() {
+ if (true) return // TODO(b/261826950): remove on main
+ if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
+ if (inputManager.isStylusEverUsed(context)) return
+
+ inputManager.setStylusEverUsed(context, true)
+ executeStylusCallbacks { cb -> cb.onStylusFirstUsed() }
+ }
+
private fun executeStylusCallbacks(run: (cb: StylusCallback) -> Unit) {
stylusCallbacks.forEach(run)
}
@@ -166,31 +228,69 @@ constructor(
stylusBatteryCallbacks.forEach(run)
}
+ private fun registerBatteryListener(deviceId: Int) {
+ try {
+ inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
+ }
+ }
+
+ private fun unregisterBatteryListener(deviceId: Int) {
+ // If deviceId wasn't registered, the result is a no-op, so an "is registered"
+ // check is not needed.
+ try {
+ inputManager.removeInputDeviceBatteryListener(deviceId, this)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
+ }
+ }
+
private fun addExistingStylusToMap() {
for (deviceId: Int in inputManager.inputDeviceIds) {
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: continue
if (device.supportsSource(InputDevice.SOURCE_STYLUS)) {
// TODO(b/257936830): get address once input api available
inputDeviceAddressMap[deviceId] = null
+
+ if (!device.isExternal) { // TODO(b/263556967): add supportsUsi check once available
+ // For most devices, an active (non-bluetooth) stylus is represented by an
+ // internal InputDevice. This InputDevice will be present in InputManager
+ // before CoreStartables run, and will not be removed.
+ // In many cases, it reports the battery level of the stylus.
+ registerBatteryListener(deviceId)
+ }
}
}
}
- /** Callback interface to receive events from the StylusManager. */
+ /**
+ * Callback interface to receive events from the StylusManager. All callbacks are run on the
+ * same background handler.
+ */
interface StylusCallback {
fun onStylusAdded(deviceId: Int) {}
fun onStylusRemoved(deviceId: Int) {}
fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {}
fun onStylusBluetoothDisconnected(deviceId: Int, btAddress: String) {}
+ fun onStylusFirstUsed() {}
}
- /** Callback interface to receive stylus battery events from the StylusManager. */
+ /**
+ * Callback interface to receive stylus battery events from the StylusManager. All callbacks are
+ * runs on the same background handler.
+ */
interface StylusBatteryCallback {
fun onStylusBluetoothChargingStateChanged(
inputDeviceId: Int,
btDevice: BluetoothDevice,
isCharging: Boolean
) {}
+ fun onStylusUsiBatteryStateChanged(
+ deviceId: Int,
+ eventTimeMillis: Long,
+ batteryState: BatteryState,
+ ) {}
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
index 11233dda165c..14a9161ac291 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
@@ -18,14 +18,11 @@ package com.android.systemui.stylus
import android.hardware.BatteryState
import android.hardware.input.InputManager
-import android.util.Log
import android.view.InputDevice
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
-import java.util.concurrent.Executor
import javax.inject.Inject
/**
@@ -40,16 +37,7 @@ constructor(
private val inputManager: InputManager,
private val stylusUsiPowerUi: StylusUsiPowerUI,
private val featureFlags: FeatureFlags,
- @Background private val executor: Executor,
-) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
-
- override fun onStylusAdded(deviceId: Int) {
- val device = inputManager.getInputDevice(deviceId) ?: return
-
- if (!device.isExternal) {
- registerBatteryListener(deviceId)
- }
- }
+) : CoreStartable, StylusManager.StylusCallback, StylusManager.StylusBatteryCallback {
override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
stylusUsiPowerUi.refresh()
@@ -59,15 +47,7 @@ constructor(
stylusUsiPowerUi.refresh()
}
- override fun onStylusRemoved(deviceId: Int) {
- val device = inputManager.getInputDevice(deviceId) ?: return
-
- if (!device.isExternal) {
- unregisterBatteryListener(deviceId)
- }
- }
-
- override fun onBatteryStateChanged(
+ override fun onStylusUsiBatteryStateChanged(
deviceId: Int,
eventTimeMillis: Long,
batteryState: BatteryState
@@ -77,39 +57,19 @@ constructor(
}
}
- private fun registerBatteryListener(deviceId: Int) {
- try {
- inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
- }
- }
-
- private fun unregisterBatteryListener(deviceId: Int) {
- try {
- inputManager.removeInputDeviceBatteryListener(deviceId, this)
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to unregister battery listener for $deviceId.")
- }
- }
-
override fun start() {
if (!featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)) return
- addBatteryListenerForInternalStyluses()
+ if (!hostDeviceSupportsStylusInput()) return
stylusManager.registerCallback(this)
stylusManager.startListener()
}
- private fun addBatteryListenerForInternalStyluses() {
- // For most devices, an active stylus is represented by an internal InputDevice.
- // This InputDevice will be present in InputManager before CoreStartables run,
- // and will not be removed. In many cases, it reports the battery level of the stylus.
- inputManager.inputDeviceIds
+ private fun hostDeviceSupportsStylusInput(): Boolean {
+ return inputManager.inputDeviceIds
.asSequence()
.mapNotNull { inputManager.getInputDevice(it) }
- .filter { it.supportsSource(InputDevice.SOURCE_STYLUS) }
- .forEach { onStylusAdded(it.id) }
+ .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
deleted file mode 100644
index 8dd088f5760c..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.stylus
-
-import android.content.Context
-import android.hardware.BatteryState
-import android.hardware.input.InputManager
-import android.os.Handler
-import android.testing.AndroidTestingRunner
-import android.view.InputDevice
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.time.FakeSystemClock
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@Ignore("TODO(b/20579491): unignore on main")
-class StylusFirstUsageListenerTest : SysuiTestCase() {
- @Mock lateinit var context: Context
- @Mock lateinit var inputManager: InputManager
- @Mock lateinit var stylusManager: StylusManager
- @Mock lateinit var featureFlags: FeatureFlags
- @Mock lateinit var internalStylusDevice: InputDevice
- @Mock lateinit var otherDevice: InputDevice
- @Mock lateinit var externalStylusDevice: InputDevice
- @Mock lateinit var batteryState: BatteryState
- @Mock lateinit var handler: Handler
-
- private lateinit var stylusListener: StylusFirstUsageListener
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
- whenever(inputManager.isStylusEverUsed(context)).thenReturn(false)
-
- stylusListener =
- StylusFirstUsageListener(
- context,
- inputManager,
- stylusManager,
- featureFlags,
- EXECUTOR,
- handler
- )
- stylusListener.hasStarted = false
-
- whenever(handler.post(any())).thenAnswer {
- (it.arguments[0] as Runnable).run()
- true
- }
-
- whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
- whenever(internalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
- whenever(internalStylusDevice.isExternal).thenReturn(false)
- whenever(externalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
- whenever(externalStylusDevice.isExternal).thenReturn(true)
-
- whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
- whenever(inputManager.getInputDevice(OTHER_DEVICE_ID)).thenReturn(otherDevice)
- whenever(inputManager.getInputDevice(INTERNAL_STYLUS_DEVICE_ID))
- .thenReturn(internalStylusDevice)
- whenever(inputManager.getInputDevice(EXTERNAL_STYLUS_DEVICE_ID))
- .thenReturn(externalStylusDevice)
- }
-
- @Test
- fun start_flagDisabled_doesNotRegister() {
- whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(false)
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun start_toggleHasStarted() {
- stylusListener.start()
-
- assert(stylusListener.hasStarted)
- }
-
- @Test
- fun start_hasStarted_doesNotRegister() {
- stylusListener.hasStarted = true
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- }
-
- @Test
- fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
- whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(OTHER_DEVICE_ID))
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun start_stylusEverUsed_doesNotRegister() {
- whenever(inputManager.inputDeviceIds)
- .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
- whenever(inputManager.isStylusEverUsed(context)).thenReturn(true)
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun start_hostDeviceSupportsStylus_registersListener() {
- whenever(inputManager.inputDeviceIds)
- .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
-
- stylusListener.start()
-
- verify(stylusManager).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun onStylusAdded_hasNotStarted_doesNotRegisterListener() {
- stylusListener.hasStarted = false
-
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- verifyZeroInteractions(inputManager)
- }
-
- @Test
- fun onStylusAdded_internalStylus_registersListener() {
- stylusListener.hasStarted = true
-
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- verify(inputManager, times(1))
- .addInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, EXECUTOR, stylusListener)
- }
-
- @Test
- fun onStylusAdded_externalStylus_doesNotRegisterListener() {
- stylusListener.hasStarted = true
-
- stylusListener.onStylusAdded(EXTERNAL_STYLUS_DEVICE_ID)
-
- verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
- }
-
- @Test
- fun onStylusAdded_otherDevice_doesNotRegisterListener() {
- stylusListener.onStylusAdded(OTHER_DEVICE_ID)
-
- verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
- }
-
- @Test
- fun onStylusRemoved_registeredDevice_unregistersListener() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
- verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- }
-
- @Test
- fun onStylusRemoved_hasNotStarted_doesNotUnregisterListener() {
- stylusListener.hasStarted = false
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
- verifyZeroInteractions(inputManager)
- }
-
- @Test
- fun onStylusRemoved_unregisteredDevice_doesNotUnregisterListener() {
- stylusListener.hasStarted = true
-
- stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
- verifyNoMoreInteractions(inputManager)
- }
-
- @Test
- fun onStylusBluetoothConnected_updateStylusFlagAndUnregisters() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
-
- verify(inputManager).setStylusEverUsed(context, true)
- verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- verify(stylusManager).unregisterCallback(stylusListener)
- }
-
- @Test
- fun onStylusBluetoothConnected_hasNotStarted_doesNoting() {
- stylusListener.hasStarted = false
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
-
- verifyZeroInteractions(inputManager)
- verifyZeroInteractions(stylusManager)
- }
-
- @Test
- fun onBatteryStateChanged_batteryPresent_updateStylusFlagAndUnregisters() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
- whenever(batteryState.isPresent).thenReturn(true)
-
- stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
- verify(inputManager).setStylusEverUsed(context, true)
- verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- verify(stylusManager).unregisterCallback(stylusListener)
- }
-
- @Test
- fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateFlagOrUnregister() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
- whenever(batteryState.isPresent).thenReturn(false)
-
- stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
- verifyZeroInteractions(stylusManager)
- verify(inputManager, never())
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- }
-
- @Test
- fun onBatteryStateChanged_hasNotStarted_doesNothing() {
- stylusListener.hasStarted = false
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
- whenever(batteryState.isPresent).thenReturn(false)
-
- stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
- verifyZeroInteractions(inputManager)
- verifyZeroInteractions(stylusManager)
- }
-
- companion object {
- private const val OTHER_DEVICE_ID = 0
- private const val INTERNAL_STYLUS_DEVICE_ID = 1
- private const val EXTERNAL_STYLUS_DEVICE_ID = 2
- private val EXECUTOR = FakeExecutor(FakeSystemClock())
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
index 984de5b67bf5..6d6e40a90fa6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
@@ -17,12 +17,15 @@ package com.android.systemui.stylus
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
+import android.hardware.BatteryState
import android.hardware.input.InputManager
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.view.InputDevice
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import java.util.concurrent.Executor
@@ -31,30 +34,27 @@ import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@SmallTest
-@Ignore("b/257936830 until bt APIs")
class StylusManagerTest : SysuiTestCase() {
@Mock lateinit var inputManager: InputManager
-
@Mock lateinit var stylusDevice: InputDevice
-
@Mock lateinit var btStylusDevice: InputDevice
-
@Mock lateinit var otherDevice: InputDevice
-
+ @Mock lateinit var batteryState: BatteryState
@Mock lateinit var bluetoothAdapter: BluetoothAdapter
-
@Mock lateinit var bluetoothDevice: BluetoothDevice
-
@Mock lateinit var handler: Handler
+ @Mock lateinit var featureFlags: FeatureFlags
@Mock lateinit var stylusCallback: StylusManager.StylusCallback
@@ -75,11 +75,8 @@ class StylusManagerTest : SysuiTestCase() {
true
}
- stylusManager = StylusManager(inputManager, bluetoothAdapter, handler, EXECUTOR)
-
- stylusManager.registerCallback(stylusCallback)
-
- stylusManager.registerBatteryCallback(stylusBatteryCallback)
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
@@ -92,19 +89,47 @@ class StylusManagerTest : SysuiTestCase() {
whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice)
whenever(inputManager.getInputDevice(BT_STYLUS_DEVICE_ID)).thenReturn(btStylusDevice)
whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(STYLUS_DEVICE_ID))
+ whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(false)
whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(bluetoothDevice)
whenever(bluetoothDevice.address).thenReturn(STYLUS_BT_ADDRESS)
+
+ whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
+
+ stylusManager.startListener()
+ stylusManager.registerCallback(stylusCallback)
+ stylusManager.registerBatteryCallback(stylusBatteryCallback)
+ clearInvocations(inputManager)
}
@Test
- fun startListener_registersInputDeviceListener() {
+ fun startListener_hasNotStarted_registersInputDeviceListener() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
stylusManager.startListener()
verify(inputManager, times(1)).registerInputDeviceListener(any(), any())
}
@Test
+ fun startListener_hasStarted_doesNothing() {
+ stylusManager.startListener()
+
+ verifyZeroInteractions(inputManager)
+ }
+
+ @Test
+ fun onInputDeviceAdded_hasNotStarted_doesNothing() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(stylusCallback)
+ }
+
+ @Test
fun onInputDeviceAdded_multipleRegisteredCallbacks_callsAll() {
stylusManager.registerCallback(otherStylusCallback)
@@ -117,6 +142,26 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ fun onInputDeviceAdded_internalStylus_registersBatteryListener() {
+ whenever(stylusDevice.isExternal).thenReturn(false)
+
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, EXECUTOR, stylusManager)
+ }
+
+ @Test
+ fun onInputDeviceAdded_externalStylus_doesNotRegisterbatteryListener() {
+ whenever(stylusDevice.isExternal).thenReturn(true)
+
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ verify(inputManager, never())
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, EXECUTOR, stylusManager)
+ }
+
+ @Test
fun onInputDeviceAdded_stylus_callsCallbacksOnStylusAdded() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
@@ -125,6 +170,23 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
+ fun onInputDeviceAdded_btStylus_firstUsed_callsCallbacksOnStylusFirstUsed() {
+ stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+ verify(stylusCallback, times(1)).onStylusFirstUsed()
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
+ fun onInputDeviceAdded_btStylus_firstUsed_setsFlag() {
+ stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1)).setStylusEverUsed(mContext, true)
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceAdded_btStylus_callsCallbacksWithAddress() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -143,6 +205,17 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ fun onInputDeviceChanged_hasNotStarted_doesNothing() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
+ stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(stylusCallback)
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_multipleRegisteredCallbacks_callsAll() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
// whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
@@ -157,6 +230,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_stylusNewBtConnection_callsCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
// whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
@@ -168,6 +242,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_stylusLostBtConnection_callsCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
// whenever(btStylusDevice.bluetoothAddress).thenReturn(null)
@@ -179,6 +254,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_btConnection_stylusAlreadyBtConnected_onlyCallsListenersOnce() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -189,6 +265,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_noBtConnection_stylusNeverBtConnected_doesNotCallCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
@@ -198,6 +275,17 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ fun onInputDeviceRemoved_hasNotStarted_doesNothing() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(stylusCallback)
+ }
+
+ @Test
fun onInputDeviceRemoved_multipleRegisteredCallbacks_callsAll() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
stylusManager.registerCallback(otherStylusCallback)
@@ -219,6 +307,17 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ fun onInputDeviceRemoved_unregistersBatteryListener() {
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, stylusManager)
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceRemoved_btStylus_callsCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -232,6 +331,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onStylusBluetoothConnected_registersMetadataListener() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -239,6 +339,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onStylusBluetoothConnected_noBluetoothDevice_doesNotRegisterMetadataListener() {
whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(null)
@@ -248,6 +349,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onStylusBluetoothDisconnected_unregistersMetadataListener() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -257,6 +359,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_multipleRegisteredBatteryCallbacks_executesAll() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
stylusManager.registerBatteryCallback(otherStylusBatteryCallback)
@@ -274,6 +377,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_chargingStateTrue_executesBatteryCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -288,6 +392,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_chargingStateFalse_executesBatteryCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -302,6 +407,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_chargingStateNoDevice_doesNotExecuteBatteryCallbacks() {
stylusManager.onMetadataChanged(
bluetoothDevice,
@@ -313,6 +419,7 @@ class StylusManagerTest : SysuiTestCase() {
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_notChargingState_doesNotExecuteBatteryCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -326,6 +433,63 @@ class StylusManagerTest : SysuiTestCase() {
.onStylusBluetoothChargingStateChanged(any(), any(), any())
}
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryPresent_stylusNeverUsed_updateEverUsedFlag() {
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(inputManager).setStylusEverUsed(mContext, true)
+ }
+
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryPresent_stylusNeverUsed_executesStylusFirstUsed() {
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(stylusCallback, times(1)).onStylusFirstUsed()
+ }
+
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryPresent_stylusUsed_doesNotUpdateEverUsedFlag() {
+ whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(true)
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(inputManager, never()).setStylusEverUsed(mContext, true)
+ }
+
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateEverUsedFlag() {
+ whenever(batteryState.isPresent).thenReturn(false)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(inputManager, never())
+ .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, stylusManager)
+ }
+
+ @Test
+ fun onBatteryStateChanged_hasNotStarted_doesNothing() {
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verifyZeroInteractions(inputManager)
+ }
+
+ @Test
+ fun onBatteryStateChanged_executesBatteryCallbacks() {
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(stylusBatteryCallback, times(1))
+ .onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+ }
+
companion object {
private val EXECUTOR = Executor { r -> r.run() }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
index ff382a3ec19f..117e00dd9b2a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
@@ -25,17 +25,15 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.util.mockito.whenever
-import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.inOrder
import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -60,7 +58,6 @@ class StylusUsiPowerStartableTest : SysuiTestCase() {
inputManager,
stylusUsiPowerUi,
featureFlags,
- DIRECT_EXECUTOR,
)
whenever(featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)).thenReturn(true)
@@ -79,40 +76,12 @@ class StylusUsiPowerStartableTest : SysuiTestCase() {
}
@Test
- fun start_addsBatteryListenerForInternalStylus() {
- startable.start()
-
- verify(inputManager, times(1))
- .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
- }
-
- @Test
- fun onStylusAdded_internalStylus_addsBatteryListener() {
- startable.onStylusAdded(STYLUS_DEVICE_ID)
-
- verify(inputManager, times(1))
- .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
- }
+ fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(EXTERNAL_DEVICE_ID))
- @Test
- fun onStylusAdded_externalStylus_doesNotAddBatteryListener() {
- startable.onStylusAdded(EXTERNAL_DEVICE_ID)
-
- verify(inputManager, never())
- .addInputDeviceBatteryListener(EXTERNAL_DEVICE_ID, DIRECT_EXECUTOR, startable)
- }
+ startable.start()
- @Test
- fun onStylusRemoved_registeredStylus_removesBatteryListener() {
- startable.onStylusAdded(STYLUS_DEVICE_ID)
- startable.onStylusRemoved(STYLUS_DEVICE_ID)
-
- inOrder(inputManager).let {
- it.verify(inputManager, times(1))
- .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
- it.verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, startable)
- }
+ verifyZeroInteractions(stylusManager)
}
@Test
@@ -130,28 +99,26 @@ class StylusUsiPowerStartableTest : SysuiTestCase() {
}
@Test
- fun onBatteryStateChanged_batteryPresent_refreshesNotification() {
+ fun onStylusUsiBatteryStateChanged_batteryPresent_refreshesNotification() {
val batteryState = mock(BatteryState::class.java)
whenever(batteryState.isPresent).thenReturn(true)
- startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+ startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
verify(stylusUsiPowerUi, times(1)).updateBatteryState(batteryState)
}
@Test
- fun onBatteryStateChanged_batteryNotPresent_noop() {
+ fun onStylusUsiBatteryStateChanged_batteryNotPresent_noop() {
val batteryState = mock(BatteryState::class.java)
whenever(batteryState.isPresent).thenReturn(false)
- startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+ startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
verifyNoMoreInteractions(stylusUsiPowerUi)
}
companion object {
- private val DIRECT_EXECUTOR = Executor { r -> r.run() }
-
private const val EXTERNAL_DEVICE_ID = 0
private const val STYLUS_DEVICE_ID = 1
}