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 
17 package com.android.systemui.shared.hardware
18 
19 import android.hardware.input.InputManager
20 import android.view.InputDevice
21 
22 /**
23  * Gets information about all input devices in the system and returns as a lazy [Sequence].
24  *
25  * For performance reasons, it is preferred to operate atop the returned [Sequence] to ensure each
26  * operation is executed on an element-per-element basis yet customizable.
27  *
28  * For example:
29  * ```kotlin
30  * val stylusDevices = inputManager.getInputDeviceSequence().filter {
31  *   it.supportsSource(InputDevice.SOURCE_STYLUS)
32  * }
33  *
34  * val hasInternalStylus = stylusDevices.any { it.isInternal }
35  * val hasExternalStylus = stylusDevices.any { !it.isInternal }
36  * ```
37  *
38  * @return a [Sequence] of [InputDevice].
39  */
InputManagernull40 fun InputManager.getInputDeviceSequence(): Sequence<InputDevice> =
41     inputDeviceIds.asSequence().mapNotNull { getInputDevice(it) }
42 
43 /**
44  * Returns the first [InputDevice] matching the given predicate, or null if no such [InputDevice]
45  * was found.
46  */
findInputDevicenull47 fun InputManager.findInputDevice(predicate: (InputDevice) -> Boolean): InputDevice? =
48     getInputDeviceSequence().find { predicate(it) }
49 
50 /**
51  * Returns true if [any] [InputDevice] matches with [predicate].
52  *
53  * For example:
54  * ```kotlin
55  * val hasStylusSupport = inputManager.hasInputDevice { it.isStylusSupport() }
56  * val hasStylusPen = inputManager.hasInputDevice { it.isStylusPen() }
57  * ```
58  */
hasInputDevicenull59 fun InputManager.hasInputDevice(predicate: (InputDevice) -> Boolean): Boolean =
60     getInputDeviceSequence().any { predicate(it) }
61 
62 /** Returns true if host device has any [InputDevice] where [InputDevice.isInternalStylusSource]. */
<lambda>null63 fun InputManager.hasInternalStylusSource(): Boolean = hasInputDevice { it.isInternalStylusSource }
64 
65 /** Returns true if host device has any [InputDevice] where [InputDevice.isExternalStylusSource]. */
<lambda>null66 fun InputManager.hasExternalStylusSource(): Boolean = hasInputDevice { it.isExternalStylusSource }
67 
68 /** Returns true if host device has any [InputDevice] where [InputDevice.isAnyStylusSource]. */
<lambda>null69 fun InputManager.hasAnyStylusSource(): Boolean = hasInputDevice { it.isAnyStylusSource }
70