1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.stylus 18 19 import android.hardware.BatteryState 20 import android.hardware.input.InputManager 21 import android.testing.AndroidTestingRunner 22 import android.view.InputDevice 23 import androidx.test.filters.SmallTest 24 import com.android.systemui.SysuiTestCase 25 import com.android.systemui.flags.FeatureFlags 26 import com.android.systemui.flags.Flags 27 import com.android.systemui.util.mockito.whenever 28 import org.junit.Before 29 import org.junit.Test 30 import org.junit.runner.RunWith 31 import org.mockito.Mock 32 import org.mockito.Mockito.mock 33 import org.mockito.Mockito.times 34 import org.mockito.Mockito.verify 35 import org.mockito.Mockito.verifyNoMoreInteractions 36 import org.mockito.Mockito.verifyZeroInteractions 37 import org.mockito.MockitoAnnotations 38 39 @RunWith(AndroidTestingRunner::class) 40 @SmallTest 41 class StylusUsiPowerStartableTest : SysuiTestCase() { 42 @Mock lateinit var inputManager: InputManager 43 @Mock lateinit var stylusManager: StylusManager 44 @Mock lateinit var stylusDevice: InputDevice 45 @Mock lateinit var externalDevice: InputDevice 46 @Mock lateinit var featureFlags: FeatureFlags 47 @Mock lateinit var stylusUsiPowerUi: StylusUsiPowerUI 48 49 lateinit var startable: StylusUsiPowerStartable 50 51 @Before setUpnull52 fun setUp() { 53 MockitoAnnotations.initMocks(this) 54 55 startable = 56 StylusUsiPowerStartable( 57 stylusManager, 58 inputManager, 59 stylusUsiPowerUi, 60 featureFlags, 61 ) 62 63 whenever(featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)).thenReturn(true) 64 65 whenever(inputManager.getInputDevice(EXTERNAL_DEVICE_ID)).thenReturn(externalDevice) 66 whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice) 67 whenever(inputManager.inputDeviceIds) 68 .thenReturn(intArrayOf(EXTERNAL_DEVICE_ID, STYLUS_DEVICE_ID)) 69 70 whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true) 71 whenever(stylusDevice.isExternal).thenReturn(false) 72 whenever(stylusDevice.id).thenReturn(STYLUS_DEVICE_ID) 73 whenever(externalDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true) 74 whenever(externalDevice.isExternal).thenReturn(true) 75 whenever(externalDevice.id).thenReturn(EXTERNAL_DEVICE_ID) 76 } 77 78 @Test start_hostDeviceDoesNotSupportStylus_doesNotRegisternull79 fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() { 80 whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(EXTERNAL_DEVICE_ID)) 81 82 startable.start() 83 84 verifyZeroInteractions(stylusManager) 85 } 86 87 @Test start_initStylusUsiPowerUinull88 fun start_initStylusUsiPowerUi() { 89 startable.start() 90 91 verify(stylusUsiPowerUi, times(1)).init() 92 } 93 94 @Test start_registersCallbacksnull95 fun start_registersCallbacks() { 96 startable.start() 97 98 verify(stylusManager, times(1)).registerCallback(startable) 99 } 100 101 @Test onStylusAdded_internal_updatesNotificationSuppressionnull102 fun onStylusAdded_internal_updatesNotificationSuppression() { 103 startable.onStylusAdded(STYLUS_DEVICE_ID) 104 105 verify(stylusUsiPowerUi, times(1)).updateSuppression(false) 106 } 107 108 @Test onStylusAdded_external_noopnull109 fun onStylusAdded_external_noop() { 110 startable.onStylusAdded(EXTERNAL_DEVICE_ID) 111 112 verifyZeroInteractions(stylusUsiPowerUi) 113 } 114 115 @Test onStylusUsiBatteryStateChanged_batteryPresentValidCapacity_refreshesNotificationnull116 fun onStylusUsiBatteryStateChanged_batteryPresentValidCapacity_refreshesNotification() { 117 val batteryState = FixedCapacityBatteryState(0.1f) 118 119 startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState) 120 121 verify(stylusUsiPowerUi, times(1)).updateBatteryState(STYLUS_DEVICE_ID, batteryState) 122 } 123 124 @Test onStylusUsiBatteryStateChanged_batteryPresentInvalidCapacity_noopnull125 fun onStylusUsiBatteryStateChanged_batteryPresentInvalidCapacity_noop() { 126 val batteryState = FixedCapacityBatteryState(0f) 127 128 startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState) 129 130 verifyNoMoreInteractions(stylusUsiPowerUi) 131 } 132 133 @Test onStylusUsiBatteryStateChanged_batteryNotPresent_noopnull134 fun onStylusUsiBatteryStateChanged_batteryNotPresent_noop() { 135 val batteryState = mock(BatteryState::class.java) 136 whenever(batteryState.isPresent).thenReturn(false) 137 138 startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState) 139 140 verifyNoMoreInteractions(stylusUsiPowerUi) 141 } 142 143 companion object { 144 private const val EXTERNAL_DEVICE_ID = 0 145 private const val STYLUS_DEVICE_ID = 1 146 } 147 } 148