• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.bluetooth.hap;
19 
20 import android.bluetooth.BluetoothDevice;
21 import android.bluetooth.IBluetoothHapClient;
22 
23 import java.math.BigInteger;
24 import java.util.ArrayList;
25 import java.util.List;
26 
27 /**
28  * Stack event sent via a callback from GATT Service client to main service module, or generated
29  * internally by the Hearing Access Profile State Machine.
30  */
31 public class HapClientStackEvent {
32     // Event types for STACK_EVENT message (coming from native HAS client)
33     private static final int EVENT_TYPE_NONE = 0;
34     public static final int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1;
35     public static final int EVENT_TYPE_DEVICE_AVAILABLE = 2;
36     public static final int EVENT_TYPE_DEVICE_FEATURES = 3;
37     public static final int EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED = 4;
38     public static final int EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR = 5;
39     public static final int EVENT_TYPE_ON_PRESET_INFO = 6;
40     public static final int EVENT_TYPE_ON_PRESET_NAME_SET_ERROR = 7;
41     public static final int EVENT_TYPE_ON_PRESET_INFO_ERROR = 8;
42 
43     // Connection state values as defined in bt_has.h
44     static final int CONNECTION_STATE_DISCONNECTED = 0;
45     static final int CONNECTION_STATE_CONNECTING = 1;
46     static final int CONNECTION_STATE_CONNECTED = 2;
47     static final int CONNECTION_STATE_DISCONNECTING = 3;
48 
49     // Possible operation results
50     /* WARNING: Matches status codes defined in bta_has.h */
51     static final int STATUS_NO_ERROR = 0;
52     static final int STATUS_SET_NAME_NOT_ALLOWED = 1;
53     static final int STATUS_OPERATION_NOT_SUPPORTED = 2;
54     static final int STATUS_OPERATION_NOT_POSSIBLE = 3;
55     static final int STATUS_INVALID_PRESET_NAME_LENGTH = 4;
56     static final int STATUS_INVALID_PRESET_INDEX = 5;
57     static final int STATUS_GROUP_OPERATION_NOT_SUPPORTED = 6;
58     static final int STATUS_PROCEDURE_ALREADY_IN_PROGRESS = 7;
59 
60     // Supported features
61     public static final int FEATURE_BIT_NUM_TYPE_MONAURAL =
62             IBluetoothHapClient.FEATURE_BIT_NUM_TYPE_MONAURAL;
63     public static final int FEATURE_BIT_NUM_TYPE_BANDED =
64             IBluetoothHapClient.FEATURE_BIT_NUM_TYPE_BANDED;
65     public static final int FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS =
66             IBluetoothHapClient.FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS;
67     public static final int FEATURE_BIT_NUM_INDEPENDENT_PRESETS =
68             IBluetoothHapClient.FEATURE_BIT_NUM_INDEPENDENT_PRESETS;
69     public static final int FEATURE_BIT_NUM_DYNAMIC_PRESETS =
70             IBluetoothHapClient.FEATURE_BIT_NUM_DYNAMIC_PRESETS;
71     public static final int FEATURE_BIT_NUM_WRITABLE_PRESETS =
72             IBluetoothHapClient.FEATURE_BIT_NUM_WRITABLE_PRESETS;
73 
74     // Preset Info notification reason
75     /* WARNING: Matches status codes defined in bta_has.h */
76     public static final int PRESET_INFO_REASON_ALL_PRESET_INFO = 0;
77     public static final int PRESET_INFO_REASON_PRESET_INFO_UPDATE = 1;
78     public static final int PRESET_INFO_REASON_PRESET_DELETED = 2;
79     public static final int PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED = 3;
80     public static final int PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE = 4;
81 
82     public int type;
83     public BluetoothDevice device;
84     public int valueInt1;
85     public int valueInt2;
86     public int valueInt3;
87     public ArrayList valueList;
88 
HapClientStackEvent(int type)89     HapClientStackEvent(int type) {
90         this.type = type;
91     }
92 
93     @Override
toString()94     public String toString() {
95         // event dump
96         StringBuilder result = new StringBuilder();
97         result.append("HearingAccessStackEvent {type:" + eventTypeToString(type));
98         result.append(", device: " + device);
99         result.append(", value1: " + eventTypeValueInt1ToString(type, valueInt1));
100         result.append(", value2: " + eventTypeValueInt2ToString(type, valueInt2));
101         result.append(", value3: " + eventTypeValueInt3ToString(type, valueInt3));
102         result.append(", list: " + eventTypeValueListToString(type, valueList));
103 
104         result.append("}");
105         return result.toString();
106     }
107 
eventTypeValueListToString(int type, List value)108     private String eventTypeValueListToString(int type, List value) {
109         switch (type) {
110             case EVENT_TYPE_ON_PRESET_INFO:
111                 return "{presets count: " + (value == null ? 0 : value.size()) + "}";
112             default:
113                 return "{list: empty}";
114         }
115     }
116 
eventTypeValueInt1ToString(int type, int value)117     private String eventTypeValueInt1ToString(int type, int value) {
118         switch (type) {
119             case EVENT_TYPE_CONNECTION_STATE_CHANGED:
120                 return "{state: " + connectionStateValueToString(value) + "}";
121             case EVENT_TYPE_DEVICE_AVAILABLE:
122                 return "{features: " + featuresToString(value) + "}";
123             case EVENT_TYPE_DEVICE_FEATURES:
124                 return "{features: " + featuresToString(value) + "}";
125             case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
126                 return "{statusCode: " + statusCodeValueToString(value) + "}";
127             case EVENT_TYPE_ON_PRESET_INFO_ERROR:
128                 return "{statusCode: " + statusCodeValueToString(value) + "}";
129             case EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED:
130                 return "{presetIndex: " + value + "}";
131             case EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR:
132                 return "{statusCode: " + statusCodeValueToString(value) + "}";
133             case EVENT_TYPE_ON_PRESET_INFO:
134             default:
135                 return "{unused: " + value + "}";
136         }
137     }
138 
infoReasonToString(int value)139     private String infoReasonToString(int value) {
140         switch (value) {
141             case PRESET_INFO_REASON_ALL_PRESET_INFO:
142                 return "PRESET_INFO_REASON_ALL_PRESET_INFO";
143             case PRESET_INFO_REASON_PRESET_INFO_UPDATE:
144                 return "PRESET_INFO_REASON_PRESET_INFO_UPDATE";
145             case PRESET_INFO_REASON_PRESET_DELETED:
146                 return "PRESET_INFO_REASON_PRESET_DELETED";
147             case PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
148                 return "PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED";
149             case PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE:
150                 return "PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE";
151             default:
152                 return "UNKNOWN";
153         }
154     }
155 
eventTypeValueInt2ToString(int type, int value)156     private String eventTypeValueInt2ToString(int type, int value) {
157         switch (type) {
158             case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
159                 return "{presetIndex: " + value + "}";
160             case EVENT_TYPE_ON_PRESET_INFO:
161                 return "{info_reason: " + infoReasonToString(value) + "}";
162             case EVENT_TYPE_ON_PRESET_INFO_ERROR:
163                 return "{presetIndex: " + value + "}";
164             case EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED:
165                 return "{groupId: " + value + "}";
166             case EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR:
167                 return "{groupId: " + value + "}";
168             default:
169                 return "{unused: " + value + "}";
170         }
171     }
172 
eventTypeValueInt3ToString(int type, int value)173     private String eventTypeValueInt3ToString(int type, int value) {
174         switch (type) {
175             case EVENT_TYPE_ON_PRESET_INFO:
176             case EVENT_TYPE_ON_PRESET_INFO_ERROR:
177             case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
178                 return "{groupId: " + value + "}";
179             default:
180                 return "{unused: " + value + "}";
181         }
182     }
183 
connectionStateValueToString(int value)184     private String connectionStateValueToString(int value) {
185         switch (value) {
186             case CONNECTION_STATE_DISCONNECTED:
187                 return "CONNECTION_STATE_DISCONNECTED";
188             case CONNECTION_STATE_CONNECTING:
189                 return "CONNECTION_STATE_CONNECTING";
190             case CONNECTION_STATE_CONNECTED:
191                 return "CONNECTION_STATE_CONNECTED";
192             case CONNECTION_STATE_DISCONNECTING:
193                 return "CONNECTION_STATE_DISCONNECTING";
194             default:
195                 return "CONNECTION_STATE_UNKNOWN!";
196         }
197     }
198 
statusCodeValueToString(int value)199     private String statusCodeValueToString(int value) {
200         switch (value) {
201             case STATUS_NO_ERROR:
202                 return "STATUS_NO_ERROR";
203             case STATUS_SET_NAME_NOT_ALLOWED:
204                 return "STATUS_SET_NAME_NOT_ALLOWED";
205             case STATUS_OPERATION_NOT_SUPPORTED:
206                 return "STATUS_OPERATION_NOT_SUPPORTED";
207             case STATUS_OPERATION_NOT_POSSIBLE:
208                 return "STATUS_OPERATION_NOT_POSSIBLE";
209             case STATUS_INVALID_PRESET_NAME_LENGTH:
210                 return "STATUS_INVALID_PRESET_NAME_LENGTH";
211             case STATUS_INVALID_PRESET_INDEX:
212                 return "STATUS_INVALID_PRESET_INDEX";
213             case STATUS_GROUP_OPERATION_NOT_SUPPORTED:
214                 return "STATUS_GROUP_OPERATION_NOT_SUPPORTED";
215             case STATUS_PROCEDURE_ALREADY_IN_PROGRESS:
216                 return "STATUS_PROCEDURE_ALREADY_IN_PROGRESS";
217             default:
218                 return "ERROR_UNKNOWN";
219         }
220     }
221 
featuresToString(int value)222     private String featuresToString(int value) {
223         String features_str = "";
224         if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_TYPE_MONAURAL)) {
225             features_str += "TYPE_MONAURAL";
226         } else if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_TYPE_BANDED)) {
227             features_str += "TYPE_BANDED";
228         } else {
229             features_str += "TYPE_BINAURAL";
230         }
231 
232         if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS)) {
233             features_str += ", SYNCHRONIZATED_PRESETS";
234         }
235         if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_INDEPENDENT_PRESETS)) {
236             features_str += ", INDEPENDENT_PRESETS";
237         }
238         if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_DYNAMIC_PRESETS)) {
239             features_str += ", DYNAMIC_PRESETS";
240         }
241         if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_WRITABLE_PRESETS)) {
242             features_str += ", WRITABLE_PRESETS";
243         }
244 
245         return features_str;
246     }
247 
eventTypeToString(int type)248     private static String eventTypeToString(int type) {
249         switch (type) {
250             case EVENT_TYPE_NONE:
251                 return "EVENT_TYPE_NONE";
252             case EVENT_TYPE_CONNECTION_STATE_CHANGED:
253                 return "EVENT_TYPE_CONNECTION_STATE_CHANGED";
254             case EVENT_TYPE_DEVICE_AVAILABLE:
255                 return "EVENT_TYPE_DEVICE_AVAILABLE";
256             case EVENT_TYPE_DEVICE_FEATURES:
257                 return "EVENT_TYPE_DEVICE_FEATURES";
258             case EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED:
259                 return "EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED";
260             case EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR:
261                 return "EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR";
262             case EVENT_TYPE_ON_PRESET_INFO:
263                 return "EVENT_TYPE_ON_PRESET_INFO";
264             case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
265                 return "EVENT_TYPE_ON_PRESET_NAME_SET_ERROR";
266             case EVENT_TYPE_ON_PRESET_INFO_ERROR:
267                 return "EVENT_TYPE_ON_PRESET_INFO_ERROR";
268             default:
269                 return "EVENT_TYPE_UNKNOWN:" + type;
270         }
271     }
272 }
273