-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
HidDeviceProfile.kt
107 lines (92 loc) · 3.66 KB
/
HidDeviceProfile.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Based on HidDeviceProfile.java of WearMouse, which comes with the following copyright notice
// and is licensed under the Apache License, Version 2.0:
// Copyright 2018 Google LLC All Rights Reserved.
package me.henneke.wearauthn.bthid
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothProfile
import android.content.Context
import androidx.annotation.MainThread
/** Wrapper for BluetoothInputHost profile that manages paired HID Host devices. */
abstract class HidDeviceProfile(private val bluetoothAdapter: BluetoothAdapter) {
private var serviceStateListener: ServiceStateListener? = null
private var service: BluetoothProfile? = null
/**
* Get all devices that are in the "Connected" state.
*
* @return Connected devices list.
*/
internal abstract val connectedDevices: List<BluetoothDevice>
protected abstract val profileId: Int
/**
* Initiate the connection to the profile proxy service.
*
* @param context Context that is required to establish the service connection.
* @param listener Callback that will receive the profile proxy object.
*/
@MainThread
internal fun registerServiceListener(context: Context, listener: ServiceStateListener) {
serviceStateListener = listener
bluetoothAdapter.getProfileProxy(context.applicationContext, ServiceListener(), profileId)
}
/** Close the profile service connection. */
internal fun unregisterServiceListener() {
if (service != null) {
bluetoothAdapter.closeProfileProxy(profileId, service)
service = null
}
serviceStateListener = null
}
/**
* Examine the device for current connection status.
*
* @param device Remote Bluetooth device to examine.
* @return A Bluetooth profile connection state.
*/
internal abstract fun getConnectionState(device: BluetoothDevice): Int
/**
* Initiate the connection to the remote HID Host device.
*
* @param device Device to connect to.
*/
internal abstract fun connect(device: BluetoothDevice)
/**
* Close the connection with the remote HID Host device.
*
* @param device Device to disconnect from.
*/
internal abstract fun disconnect(device: BluetoothDevice)
/**
* Get all devices that match one of the specified connection states.
*
* @param states List of states we are interested in.
* @return List of devices that match one of the states.
*/
internal abstract fun getDevicesMatchingConnectionStates(states: IntArray): List<BluetoothDevice>
/** Used to call back when a profile proxy connection state has changed. */
interface ServiceStateListener {
/**
* Callback to receive the new profile proxy object.
*
* @param proxy Profile proxy object or `null` if the service was disconnected.
*/
fun onServiceStateChanged(proxy: BluetoothProfile?)
}
private inner class ServiceListener : BluetoothProfile.ServiceListener {
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
if (serviceStateListener != null) {
service = proxy
onServiceStateChanged(service)
} else {
bluetoothAdapter.closeProfileProxy(profileId, proxy)
}
}
override fun onServiceDisconnected(profile: Int) {
service = null
onServiceStateChanged(null)
}
}
protected open fun onServiceStateChanged(proxy: BluetoothProfile?) {
serviceStateListener?.onServiceStateChanged(proxy)
}
}