• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package android.hardware.input
17 
18 import android.content.Context
19 import android.content.ContextWrapper
20 import android.content.res.Resources
21 import android.platform.test.annotations.Presubmit
22 import android.view.Display
23 import android.view.DisplayInfo
24 import android.view.InputDevice
25 import androidx.test.core.app.ApplicationProvider
26 import com.android.test.input.MockInputManagerRule
27 import org.junit.Assert.assertEquals
28 import org.junit.Assert.assertNotNull
29 import org.junit.Before
30 import org.junit.Rule
31 import org.junit.Test
32 import org.junit.runner.RunWith
33 import org.mockito.Mockito
34 import org.mockito.Mockito.eq
35 import org.mockito.Mockito.`when`
36 import org.mockito.junit.MockitoJUnitRunner
37 
38 /**
39  * Tests for [InputManager].
40  *
41  * Build/Install/Run: atest InputTests:InputManagerTest
42  */
43 @Presubmit
44 @RunWith(MockitoJUnitRunner::class)
45 class InputManagerTest {
46 
47     companion object {
48         const val DEVICE_ID = 42
49         const val SECOND_DEVICE_ID = 96
50         const val THIRD_DEVICE_ID = 99
51     }
52 
53     @get:Rule val inputManagerRule = MockInputManagerRule()
54 
55     private lateinit var devicesChangedListener: IInputDevicesChangedListener
56     private val deviceGenerationMap = mutableMapOf<Int /*deviceId*/, Int /*generation*/>()
57     private lateinit var context: Context
58     private lateinit var inputManager: InputManager
59 
60     @Before
setUpnull61     fun setUp() {
62         context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
63         inputManager = InputManager(context)
64         `when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager)
65         `when`(inputManagerRule.mock.inputDeviceIds).then { deviceGenerationMap.keys.toIntArray() }
66     }
67 
notifyDeviceChangednull68     private fun notifyDeviceChanged(
69         deviceId: Int,
70         associatedDisplayId: Int,
71         usiVersion: HostUsiVersion?,
72     ) {
73         val generation =
74             deviceGenerationMap[deviceId]?.plus(1)
75                 ?: throw IllegalArgumentException("Device $deviceId was never added!")
76         deviceGenerationMap[deviceId] = generation
77 
78         `when`(inputManagerRule.mock.getInputDevice(deviceId))
79             .thenReturn(createInputDevice(deviceId, associatedDisplayId, usiVersion, generation))
80         val list = deviceGenerationMap.flatMap { listOf(it.key, it.value) }
81         if (::devicesChangedListener.isInitialized) {
82             devicesChangedListener.onInputDevicesChanged(list.toIntArray())
83         }
84     }
85 
addInputDevicenull86     private fun addInputDevice(
87         deviceId: Int,
88         associatedDisplayId: Int,
89         usiVersion: HostUsiVersion?,
90     ) {
91         deviceGenerationMap[deviceId] = 0
92         notifyDeviceChanged(deviceId, associatedDisplayId, usiVersion)
93     }
94 
95     @Test
testUsiVersionDisplayAssociationnull96     fun testUsiVersionDisplayAssociation() {
97         addInputDevice(DEVICE_ID, Display.DEFAULT_DISPLAY, null)
98         addInputDevice(SECOND_DEVICE_ID, Display.INVALID_DISPLAY, HostUsiVersion(9, 8))
99         addInputDevice(THIRD_DEVICE_ID, 42, HostUsiVersion(3, 1))
100 
101         val usiVersion = inputManager.getHostUsiVersion(createDisplay(42))
102         assertNotNull(usiVersion)
103         assertEquals(3, usiVersion!!.majorVersion)
104         assertEquals(1, usiVersion.minorVersion)
105     }
106 
107     @Test
testUsiVersionFallBackToDisplayConfignull108     fun testUsiVersionFallBackToDisplayConfig() {
109         addInputDevice(DEVICE_ID, Display.DEFAULT_DISPLAY, null)
110 
111         `when`(inputManagerRule.mock.getHostUsiVersionFromDisplayConfig(eq(42)))
112             .thenReturn(HostUsiVersion(9, 8))
113         val usiVersion = inputManager.getHostUsiVersion(createDisplay(42))
114         assertEquals(HostUsiVersion(9, 8), usiVersion)
115     }
116 }
117 
createInputDevicenull118 private fun createInputDevice(
119     deviceId: Int,
120     associatedDisplayId: Int,
121     usiVersion: HostUsiVersion? = null,
122     generation: Int = -1,
123 ): InputDevice =
124     InputDevice.Builder()
125         .setId(deviceId)
126         .setName("Device $deviceId")
127         .setDescriptor("descriptor $deviceId")
128         .setAssociatedDisplayId(associatedDisplayId)
129         .setUsiVersion(usiVersion)
130         .setGeneration(generation)
131         .build()
132 
133 private fun createDisplay(displayId: Int): Display {
134     val res: Resources? = null
135     return Display(null /* global */, displayId, DisplayInfo(), res)
136 }
137