1 /*
2  * Copyright 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 #include "metrics/chromeos/metrics_event.h"
17 
18 #include <android-base/parseint.h>
19 #include <base/files/file_path.h>
20 #include <base/files/file_util.h>
21 #include <base/strings/pattern.h>
22 #include <base/strings/string_number_conversions.h>
23 #include <base/strings/string_util.h>
24 #include <base/strings/stringprintf.h>
25 
26 #include <map>
27 #include <utility>
28 
29 #include "hci/hci_packets.h"
30 #include "include/hardware/bluetooth.h"
31 #include "include/hardware/bt_av.h"
32 #include "include/hardware/bt_hf.h"
33 #include "include/hardware/bt_hh.h"
34 #include "stack/include/hci_error_code.h"
35 
36 extern int GetAdapterIndex();
37 
38 namespace bluetooth {
39 namespace metrics {
40 
41 namespace {
42 // these consts path below are for getting the chipset info
43 constexpr char kChipsetInfoWlanDirPath[] = "/sys/class/net/wlan0/device";
44 constexpr char kChipsetInfoMlanDirPath[] = "/sys/class/net/mlan0/device";
45 constexpr char kChipsetInfoModaliasPath[] = "/sys/class/bluetooth/hci%d/device/modalias";
46 constexpr char kChipInfoModuleDirPath[] = "/sys/class/bluetooth/hci%d/device/driver/module";
47 }  // namespace
48 
49 // topshim::btif::BtBondState is a copy of hardware/bluetooth.h:bt_bond_state_t
50 typedef bt_bond_state_t BtBondState;
51 // topshim::btif::BtAclState is a copy of hardware/bluetooth.h:bt_acl_state_t
52 typedef bt_acl_state_t BtAclState;
53 // topshim::btif::BtConnectionDirection is a copy of hardware/bluetooth.h:bt_conn_direction_t
54 typedef bt_conn_direction_t BtConnectionDirection;
55 // topshim::btif::BtStatus is a copy of hardware/bluetooth.h:bt_status_t
56 typedef bt_status_t BtStatus;
57 // topshim::profile::a2dp::BtavConnectionState is a copy of hardware/bt_av.h:btav_connection_state_t
58 typedef btav_connection_state_t BtavConnectionState;
59 // topshim::profile::hid_host::BthhConnectionState is a copy of
60 // hardware/bt_hh.h:bthh_connection_state_t
61 typedef bthh_connection_state_t BthhConnectionState;
62 // topshim::profile::hid_host::BthfConnectionState is a copy of
63 // hardware/bt_hh.h:bthf_connection_state_t
64 typedef headset::bthf_connection_state_t BthfConnectionState;
65 
66 // A copy of topshim::btif::BtDeviceType
67 enum class BtDeviceType {
68   Unknown = 0,
69   Bredr,
70   Ble,
71   Dual,
72 };
73 
74 // A normalized connection state ENUM definition all profiles
75 enum class ProfilesConnectionState {
76   DISCONNECTED = 0,
77   CONNECTING,
78   CONNECTED,
79   DISCONNECTING,
80   UNKNOWN,
81 };
82 
83 // ENUM definition for Bluetooth profiles in sync with ::uuid::Profiles
84 enum class ProfilesFloss {
85   A2dpSink = 0,
86   A2dpSource,
87   AdvAudioDist,
88   Bas,
89   Dis,
90   Hsp,
91   HspAg,
92   Hfp,
93   HfpAg,
94   AvrcpController,
95   AvrcpTarget,
96   ObexObjectPush,
97   Hid,
98   Hogp,
99   Panu,
100   Nap,
101   Bnep,
102   PbapPce,
103   PbapPse,
104   Map,
105   Mns,
106   Mas,
107   Sap,
108   HearingAid,
109   LeAudio,
110   Dip,
111   VolumeControl,
112   GenericMediaControl,
113   MediaControl,
114   CoordinatedSet,
115 };
116 
StatusToPairingState(uint32_t status)117 static PairingState StatusToPairingState(uint32_t status) {
118   switch ((BtStatus)status) {
119     case BtStatus::BT_STATUS_SUCCESS:
120       return PairingState::PAIR_SUCCEED;
121     case BtStatus::BT_STATUS_FAIL:
122       return PairingState::PAIR_FAIL_FAILED;
123     case BtStatus::BT_STATUS_NOMEM:
124       return PairingState::PAIR_FAIL_NO_RESOURCES;
125     case BtStatus::BT_STATUS_BUSY:
126       return PairingState::PAIR_FAIL_BUSY;
127     case BtStatus::BT_STATUS_UNSUPPORTED:
128       return PairingState::PAIR_FAIL_NOT_SUPPORTED;
129     case BtStatus::BT_STATUS_PARM_INVALID:
130       return PairingState::PAIR_FAIL_INVALID_PARAMS;
131     case BtStatus::BT_STATUS_AUTH_FAILURE:
132       return PairingState::PAIR_FAIL_AUTH_FAILED;
133     case BtStatus::BT_STATUS_RMT_DEV_DOWN:
134       return PairingState::PAIR_FAIL_ESTABLISH_CONN;
135     case BtStatus::BT_STATUS_AUTH_REJECTED:
136       return PairingState::PAIR_FAIL_AUTH_FAILED;
137     case BtStatus::BT_STATUS_NOT_READY:
138     case BtStatus::BT_STATUS_DONE:
139     case BtStatus::BT_STATUS_UNHANDLED:
140     default:
141       return PairingState::PAIR_FAIL_UNKNOWN;
142   }
143 }
144 
FailReasonToPairingState(int32_t fail_reason)145 static PairingState FailReasonToPairingState(int32_t fail_reason) {
146   switch ((hci::ErrorCode)fail_reason) {
147     case hci::ErrorCode::SUCCESS:
148       return PairingState::PAIR_SUCCEED;
149     case hci::ErrorCode::UNKNOWN_HCI_COMMAND:
150       return PairingState::PAIR_FAIL_UNKNOWN_COMMAND;
151     case hci::ErrorCode::UNKNOWN_CONNECTION:
152       return PairingState::PAIR_FAIL_INVALID_PARAMS;
153     case hci::ErrorCode::HARDWARE_FAILURE:
154       return PairingState::PAIR_FAIL_FAILED;
155     case hci::ErrorCode::PAGE_TIMEOUT:
156       return PairingState::PAIR_FAIL_ESTABLISH_CONN;
157     case hci::ErrorCode::AUTHENTICATION_FAILURE:
158       return PairingState::PAIR_FAIL_AUTH_FAILED;
159     case hci::ErrorCode::PIN_OR_KEY_MISSING:
160       return PairingState::PAIR_FAIL_AUTH_FAILED;
161     case hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED:
162       return PairingState::PAIR_FAIL_NO_RESOURCES;
163     case hci::ErrorCode::CONNECTION_TIMEOUT:
164       return PairingState::PAIR_FAIL_ESTABLISH_CONN;
165     case hci::ErrorCode::CONNECTION_LIMIT_EXCEEDED:
166       return PairingState::PAIR_FAIL_NO_RESOURCES;
167     case hci::ErrorCode::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED:
168       return PairingState::PAIR_FAIL_NO_RESOURCES;
169     case hci::ErrorCode::CONNECTION_ALREADY_EXISTS:
170       return PairingState::PAIR_FAIL_ALREADY_PAIRED;
171     case hci::ErrorCode::COMMAND_DISALLOWED:
172       return PairingState::PAIR_FAIL_FAILED;
173     case hci::ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES:
174       return PairingState::PAIR_FAIL_NO_RESOURCES;
175     case hci::ErrorCode::CONNECTION_REJECTED_SECURITY_REASONS:
176       return PairingState::PAIR_FAIL_AUTH_FAILED;
177     case hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR:
178       return PairingState::PAIR_FAIL_INVALID_PARAMS;
179     case hci::ErrorCode::CONNECTION_ACCEPT_TIMEOUT:
180       return PairingState::PAIR_FAIL_ESTABLISH_CONN;
181     case hci::ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE:
182       return PairingState::PAIR_FAIL_NOT_SUPPORTED;
183     case hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS:
184       return PairingState::PAIR_FAIL_INVALID_PARAMS;
185     case hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION:
186       return PairingState::PAIR_FAIL_DISCONNECTED;
187     case hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES:
188       return PairingState::PAIR_FAIL_DISCONNECTED;
189     case hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF:
190       return PairingState::PAIR_FAIL_DISCONNECTED;
191     case hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST:
192       return PairingState::PAIR_FAIL_DISCONNECTED;
193     case hci::ErrorCode::REPEATED_ATTEMPTS:
194       return PairingState::PAIR_FAIL_BUSY;
195     case hci::ErrorCode::PAIRING_NOT_ALLOWED:
196       return PairingState::PAIR_FAIL_FAILED;
197     case hci::ErrorCode::UNKNOWN_LMP_PDU:
198       return PairingState::PAIR_FAIL_FAILED;
199     case hci::ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE:
200       return PairingState::PAIR_FAIL_NOT_SUPPORTED;
201     case hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS:
202       return PairingState::PAIR_FAIL_INVALID_PARAMS;
203     case hci::ErrorCode::UNSPECIFIED_ERROR:
204       return PairingState::PAIR_FAIL_UNKNOWN;
205     case hci::ErrorCode::UNSUPPORTED_LMP_OR_LL_PARAMETER:
206       return PairingState::PAIR_FAIL_NOT_SUPPORTED;
207     case hci::ErrorCode::ROLE_CHANGE_NOT_ALLOWED:
208       return PairingState::PAIR_FAIL_FAILED;
209     case hci::ErrorCode::TRANSACTION_RESPONSE_TIMEOUT:
210       return PairingState::PAIR_FAIL_TIMEOUT;
211     case hci::ErrorCode::LINK_LAYER_COLLISION:
212       return PairingState::PAIR_FAIL_FAILED;
213     case hci::ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE:
214       return PairingState::PAIR_FAIL_AUTH_FAILED;
215     case hci::ErrorCode::ROLE_SWITCH_FAILED:
216       return PairingState::PAIR_FAIL_FAILED;
217     case hci::ErrorCode::HOST_BUSY_PAIRING:
218       return PairingState::PAIR_FAIL_BUSY;
219     case hci::ErrorCode::CONTROLLER_BUSY:
220       return PairingState::PAIR_FAIL_BUSY;
221     case hci::ErrorCode::CONNECTION_FAILED_ESTABLISHMENT:
222       return PairingState::PAIR_FAIL_ESTABLISH_CONN;
223     case hci::ErrorCode::LIMIT_REACHED:
224       return PairingState::PAIR_FAIL_NO_RESOURCES;
225     case hci::ErrorCode::PACKET_TOO_LONG:
226       return PairingState::PAIR_FAIL_INVALID_PARAMS;
227     case hci::ErrorCode::SCO_OFFSET_REJECTED:
228     case hci::ErrorCode::SCO_INTERVAL_REJECTED:
229     case hci::ErrorCode::SCO_AIR_MODE_REJECTED:
230     case hci::ErrorCode::ADVERTISING_TIMEOUT:
231     case hci::ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER:
232     case hci::ErrorCode::STATUS_UNKNOWN:
233       return PairingState::PAIR_FAIL_UNKNOWN;
234     default:
235       return PairingState::PAIR_FAIL_UNKNOWN;
236   }
237 }
238 
ToAdapterState(uint32_t state)239 AdapterState ToAdapterState(uint32_t state) {
240   return state == 1 ? AdapterState::ON : AdapterState::OFF;
241 }
242 
ToSuspendIdState(uint32_t state)243 SuspendIdState ToSuspendIdState(uint32_t state) {
244   return state == 1 ? SuspendIdState::Recorded : SuspendIdState::NoRecord;
245 }
246 
ToPairingDeviceType(std::string addr,uint32_t device_type)247 ConnectionType ToPairingDeviceType(std::string addr, uint32_t device_type) {
248   // A map stores the pending ConnectionType used to match a pairing event with unknown type.
249   // map<address, type>
250   static std::map<std::string, ConnectionType> pending_type;
251 
252   switch ((BtDeviceType)device_type) {
253     case BtDeviceType::Ble:
254       pending_type[addr] = ConnectionType::CONN_TYPE_LE;
255       return ConnectionType::CONN_TYPE_LE;
256     case BtDeviceType::Bredr:
257       pending_type[addr] = ConnectionType::CONN_TYPE_BREDR;
258       return ConnectionType::CONN_TYPE_BREDR;
259     case BtDeviceType::Dual:
260     case BtDeviceType::Unknown:
261       if (pending_type.find(addr) != pending_type.end()) {
262         return pending_type[addr];
263       } else {
264         return ConnectionType::CONN_TYPE_UNKNOWN;
265       }
266   }
267 }
268 
ToPairingState(uint32_t status,uint32_t bond_state,int32_t fail_reason)269 PairingState ToPairingState(uint32_t status, uint32_t bond_state, int32_t fail_reason) {
270   PairingState pairing_state = PairingState::PAIR_FAIL_UNKNOWN;
271 
272   // The Bonding is a transitional state during the pairing process. Ignore it by returning the
273   // starting again.
274   if ((BtBondState)bond_state == BtBondState::BT_BOND_STATE_BONDING) {
275     return PairingState::PAIR_STARTING;
276   }
277 
278   if ((BtStatus)status == BtStatus::BT_STATUS_SUCCESS &&
279       (hci::ErrorCode)fail_reason == hci::ErrorCode::SUCCESS) {
280     if ((BtBondState)bond_state == BtBondState::BT_BOND_STATE_BONDED) {
281       return PairingState::PAIR_SUCCEED;
282     } else {  // must be BtBondState::BT_BOND_STATE_NONE as BT_BOND_STATE_BONDING case has been
283               // checked early
284       // This implies the event is from forgetting a device. Return an absurd value to let caller
285       // know.
286       return PairingState::PAIR_FAIL_END;
287     }
288   }
289 
290   // TODO(b/287392029): Translate cases of bond cancelled into PairingState:PAIR_FAIL_CANCELLED
291 
292   // When both status and fail reason are provided and disagree with each other, overwrite status
293   // with the fail reason as fail reason is generated closer to the HCI and provides a more accurate
294   // description.
295   if (status) {
296     pairing_state = StatusToPairingState(status);
297   }
298   if (fail_reason) {
299     pairing_state = FailReasonToPairingState(fail_reason);
300   }
301 
302   return pairing_state;
303 }
304 
StatusToProfileConnectionState(uint32_t status,StateChangeType type)305 int64_t StatusToProfileConnectionState(uint32_t status, StateChangeType type) {
306   int64_t state;
307   if (StateChangeType::STATE_CHANGE_TYPE_CONNECT == type) {
308     switch ((BtStatus)status) {
309       case BtStatus::BT_STATUS_SUCCESS:
310         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_SUCCEED;
311         break;
312       case BtStatus::BT_STATUS_BUSY:
313         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_BUSY_CONNECTING;
314         break;
315       case BtStatus::BT_STATUS_DONE:
316         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_ALREADY_CONNECTED;
317         break;
318       case BtStatus::BT_STATUS_UNSUPPORTED:
319         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_PROFILE_NOT_SUPPORTED;
320         break;
321       case BtStatus::BT_STATUS_PARM_INVALID:
322         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_UNKNOWN_ERROR;
323         break;
324       case BtStatus::BT_STATUS_AUTH_FAILURE:
325         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_CONNECTION_REFUSED;
326         break;
327       case BtStatus::BT_STATUS_RMT_DEV_DOWN:
328         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_REMOTE_UNAVAILABLE;
329         break;
330       case BtStatus::BT_STATUS_AUTH_REJECTED:
331       case BtStatus::BT_STATUS_FAIL:
332       case BtStatus::BT_STATUS_NOT_READY:
333       case BtStatus::BT_STATUS_NOMEM:
334       case BtStatus::BT_STATUS_UNHANDLED:
335       default:
336         state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_UNKNOWN_ERROR;
337         break;
338     }
339   } else {
340     switch ((BtStatus)status) {
341       case BtStatus::BT_STATUS_SUCCESS:
342         state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_SUCCEED;
343         break;
344       case BtStatus::BT_STATUS_BUSY:
345         state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_BUSY_DISCONNECTING;
346         break;
347       case BtStatus::BT_STATUS_DONE:
348         state = (int64_t)
349                 MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_ALREADY_DISCONNECTED;
350         break;
351       case BtStatus::BT_STATUS_UNSUPPORTED:
352         state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_UNKNOWN_ERROR;
353         break;
354       case BtStatus::BT_STATUS_PARM_INVALID:
355         state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_INVALID_PARAMS;
356         break;
357       case BtStatus::BT_STATUS_AUTH_FAILURE:
358         state = (int64_t)
359                 MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_DISCONNECTION_REFUSED;
360         break;
361       case BtStatus::BT_STATUS_RMT_DEV_DOWN:
362         state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_UNKNOWN_ERROR;
363         break;
364       case BtStatus::BT_STATUS_AUTH_REJECTED:
365         state = (int64_t)
366                 MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_DISCONNECTION_REFUSED;
367         break;
368       case BtStatus::BT_STATUS_FAIL:
369       case BtStatus::BT_STATUS_NOT_READY:
370       case BtStatus::BT_STATUS_NOMEM:
371       case BtStatus::BT_STATUS_UNHANDLED:
372       default:
373         state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_UNKNOWN_ERROR;
374         break;
375     }
376   }
377 
378   return state;
379 }
380 
ToProfileConnectionState(uint32_t profile,uint32_t state)381 static std::pair<uint32_t, uint32_t> ToProfileConnectionState(uint32_t profile, uint32_t state) {
382   std::pair<uint32_t, uint32_t> output;
383 
384   switch ((ProfilesFloss)profile) {
385     case ProfilesFloss::A2dpSink:
386       output.first = (uint32_t)Profile::A2DP;
387       switch ((BtavConnectionState)state) {
388         case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTED:
389           output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
390           break;
391         case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTING:
392           output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
393           break;
394         case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTED:
395           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
396           break;
397         case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTING:
398           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
399           break;
400         default:
401           output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
402           break;
403       }
404       break;
405     // case ProfilesFloss::A2dpSource:
406     // case ProfilesFloss::AdvAudioDist:
407     // case ProfilesFloss::Hsp:
408     // case ProfilesFloss::HspAg:
409     case ProfilesFloss::Hfp:
410       output.first = (uint32_t)Profile::HFP;
411       switch ((BthfConnectionState)state) {
412         case BthfConnectionState::BTHF_CONNECTION_STATE_DISCONNECTED:
413           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
414           break;
415         case BthfConnectionState::BTHF_CONNECTION_STATE_CONNECTING:
416           output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
417           break;
418         case BthfConnectionState::BTHF_CONNECTION_STATE_CONNECTED:
419         case BthfConnectionState::BTHF_CONNECTION_STATE_SLC_CONNECTED:
420           output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
421           break;
422         case BthfConnectionState::BTHF_CONNECTION_STATE_DISCONNECTING:
423           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
424           break;
425         default:
426           output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
427           break;
428       }
429       break;
430     // case ProfilesFloss::HfpAg:
431     case ProfilesFloss::AvrcpController:
432       output.first = (uint32_t)Profile::AVRCP;
433       switch ((BtavConnectionState)state) {
434         case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTED:
435           output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
436           break;
437         case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTING:
438           output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
439           break;
440         case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTED:
441           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
442           break;
443         case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTING:
444           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
445           break;
446         default:
447           output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
448           break;
449       }
450       break;
451     // case ProfilesFloss::AvrcpTarget:
452     // case ProfilesFloss::ObexObjectPush:
453     case ProfilesFloss::Hid:
454     case ProfilesFloss::Hogp:
455       output.first = (uint32_t)Profile::HID;
456       switch ((BthhConnectionState)state) {
457         case BthhConnectionState::BTHH_CONN_STATE_CONNECTED:
458           output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
459           break;
460         case BthhConnectionState::BTHH_CONN_STATE_CONNECTING:
461           output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
462           break;
463         case BthhConnectionState::BTHH_CONN_STATE_DISCONNECTED:
464           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
465           break;
466         case BthhConnectionState::BTHH_CONN_STATE_DISCONNECTING:
467           output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
468           break;
469         case BthhConnectionState::BTHH_CONN_STATE_ACCEPTING:
470           // For metric purpose, we map accepting to connecting.
471           output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
472           break;
473         case BthhConnectionState::BTHH_CONN_STATE_UNKNOWN:
474           output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
475           break;
476       }
477       break;
478     // case ProfilesFloss::Panu:
479     // case ProfilesFloss::Nap:
480     // case ProfilesFloss::Bnep:
481     // case ProfilesFloss::PbapPce:
482     // case ProfilesFloss::PbapPse:
483     // case ProfilesFloss::Map:
484     // case ProfilesFloss::Mns:
485     // case ProfilesFloss::Mas:
486     // case ProfilesFloss::Sap:
487     // case ProfilesFloss::HearingAid:
488     // case ProfilesFloss::LeAudio:
489     // case ProfilesFloss::Dip:
490     // case ProfilesFloss::VolumeControl:
491     // case ProfilesFloss::GenericMediaControl:
492     // case ProfilesFloss::MediaControl:
493     // case ProfilesFloss::CoordinatedSet:
494     default:
495       output = std::make_pair((uint32_t)Profile::UNKNOWN, state);
496       break;
497   }
498 
499   return output;
500 }
501 
ToProfileConnectionEvent(std::string addr,uint32_t profile,uint32_t status,uint32_t state)502 ProfileConnectionEvent ToProfileConnectionEvent(std::string addr, uint32_t profile, uint32_t status,
503                                                 uint32_t state) {
504   ProfileConnectionEvent event;
505   // A map stores the pending StateChangeType used to match a (dis)connection event with unknown
506   // type. map<std::pair<address, profile>, type>
507   static std::map<std::pair<std::string, uint32_t>, StateChangeType> pending_type;
508 
509   auto profile_state_pair = ToProfileConnectionState(profile, state);
510   auto key = std::make_pair(addr, profile_state_pair.first);
511   event.profile = (int64_t)profile_state_pair.first;
512 
513   switch ((ProfilesConnectionState)profile_state_pair.second) {
514     case ProfilesConnectionState::CONNECTED:
515       event.type = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
516       event.state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_SUCCEED;
517       pending_type.erase(key);
518       break;
519     case ProfilesConnectionState::CONNECTING:
520       event.type = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
521       event.state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_STARTING;
522       pending_type[key] = StateChangeType::STATE_CHANGE_TYPE_CONNECT;
523       break;
524     case ProfilesConnectionState::DISCONNECTED:
525       event.type = pending_type.find(key) != pending_type.end()
526                            ? (int64_t)pending_type[key]
527                            : (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
528       // If the profile successfully disconnected for a connect intent, i.e., a connection is
529       // attempted but received a disconnection state update. Report this as an unknown error.
530       if (StateChangeType::STATE_CHANGE_TYPE_CONNECT == (StateChangeType)event.type &&
531           BtStatus::BT_STATUS_SUCCESS == (BtStatus)status) {
532         event.state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_UNKNOWN_ERROR;
533       } else {
534         event.state = StatusToProfileConnectionState(status, (StateChangeType)event.type);
535       }
536       pending_type.erase(key);
537       break;
538     case ProfilesConnectionState::DISCONNECTING:
539       event.type = (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
540       event.state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_STARTING;
541       pending_type[key] = StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
542       break;
543     default:
544       event.profile = (int64_t)Profile::UNKNOWN;
545       break;
546   }
547 
548   return event;
549 }
550 
ToAclConnectionStatus(uint32_t status,StateChangeType type,uint32_t hci_reason)551 static int64_t ToAclConnectionStatus(uint32_t status, StateChangeType type, uint32_t hci_reason) {
552   int64_t state;
553   if (StateChangeType::STATE_CHANGE_TYPE_CONNECT == type) {
554     switch ((BtStatus)status) {
555       case BtStatus::BT_STATUS_SUCCESS:
556         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_SUCCEED;
557         break;
558       case BtStatus::BT_STATUS_BUSY:
559         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_BUSY;
560         break;
561       case BtStatus::BT_STATUS_DONE:
562         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_ALREADY;
563         break;
564       case BtStatus::BT_STATUS_UNSUPPORTED:
565         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_NOT_SUPPORTED;
566         break;
567       case BtStatus::BT_STATUS_PARM_INVALID:
568         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_INVALID_PARAMS;
569         break;
570       case BtStatus::BT_STATUS_AUTH_FAILURE:
571         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_AUTH_FAILED;
572         break;
573       case BtStatus::BT_STATUS_RMT_DEV_DOWN:
574         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_DISCONNECTED;
575         break;
576       case BtStatus::BT_STATUS_AUTH_REJECTED:
577       case BtStatus::BT_STATUS_FAIL:
578       case BtStatus::BT_STATUS_NOT_READY:
579       case BtStatus::BT_STATUS_NOMEM:
580       case BtStatus::BT_STATUS_UNHANDLED:
581       default:
582         state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_UNKNOWN;
583         break;
584     }
585   } else {
586     switch (hci_reason) {
587       case HCI_ERR_CONNECTION_TOUT:
588         state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_TIMEOUT;
589         break;
590       case HCI_ERR_PEER_USER:
591       case HCI_ERR_REMOTE_LOW_RESOURCE:
592       case HCI_ERR_REMOTE_POWER_OFF:
593         state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_REMOTE;
594         break;
595       case HCI_ERR_CONN_CAUSE_LOCAL_HOST:
596         state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_LOCAL_HOST;
597         // TODO: distinguish from ACL_DISCONN_STATE_LOCAL_HOST_SUSPEND
598         break;
599       case HCI_ERR_AUTH_FAILURE:
600       case HCI_ERR_KEY_MISSING:
601       case HCI_ERR_HOST_REJECT_SECURITY:
602         state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_AUTH_FAILURE;
603         break;
604       default:
605         state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_UNKNOWN;
606         break;
607     }
608   }
609 
610   return state;
611 }
612 
613 // pending acl conn event is map<addr, pair<state, time>>
614 static std::map<std::string, std::pair<uint32_t, int64_t>> pending_acl_events;
615 
PendingAclConnectAttemptEvent(std::string addr,int64_t time,uint32_t acl_state)616 void PendingAclConnectAttemptEvent(std::string addr, int64_t time, uint32_t acl_state) {
617   pending_acl_events[addr] = std::make_pair(acl_state, time);
618 }
619 
ToAclConnectionEvent(std::string addr,int64_t time,uint32_t acl_status,uint32_t acl_state,uint32_t direction,uint32_t hci_reason)620 AclConnectionEvent ToAclConnectionEvent(std::string addr, int64_t time, uint32_t acl_status,
621                                         uint32_t acl_state, uint32_t direction,
622                                         uint32_t hci_reason) {
623   AclConnectionEvent event;
624 
625   if (pending_acl_events.find(addr) == pending_acl_events.end()) {
626     // No attempt found! Assume initiated by system.
627     event.initiator = (int64_t)MetricAclConnectionInitiator::ACL_CONNECTION_INITIATOR_SYSTEM;
628     event.direction = direction;
629     event.start_time = time;
630 
631     // There is no failed disconnection. Therefore on failure, assume it's a connection attempt.
632     if (acl_state == (uint32_t)BtAclState::BT_ACL_STATE_CONNECTED ||
633         acl_status != (uint32_t)BtStatus::BT_STATUS_SUCCESS) {
634       event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
635     } else {
636       event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
637     }
638   } else {
639     // connection attempt found. Assume initiated by client.
640     std::pair<uint32_t, int64_t> pending_event = pending_acl_events[addr];
641     pending_acl_events.erase(addr);
642     event.initiator = (int64_t)MetricAclConnectionInitiator::ACL_CONNECTION_INITIATOR_CLIENT;
643     event.direction = (int64_t)MetricAclConnectionDirection::ACL_CONNECTION_OUTGOING;
644     event.start_time = pending_event.second;
645 
646     if (pending_event.first == (uint32_t)BtAclState::BT_ACL_STATE_CONNECTED) {
647       event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
648     } else {
649       event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
650     }
651   }
652 
653   if (event.state == (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT) {
654     event.start_status = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_STARTING;
655   } else {
656     event.start_status = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_STARTING;
657   }
658 
659   event.status = ToAclConnectionStatus(acl_status, (StateChangeType)event.state, hci_reason);
660 
661   return event;
662 }
663 
GetChipsetInfoId(const char * path,const char * file)664 static int64_t GetChipsetInfoId(const char* path, const char* file) {
665   std::string content;
666   int64_t id;
667 
668   if (base::ReadFileToString(base::FilePath(path).Append(file), &content)) {
669     if (android::base::ParseInt(base::CollapseWhitespaceASCII(content, false), &id)) {
670       return id;
671     }
672   }
673   return 0;
674 }
675 
GetChipsetInfoModuleName()676 static std::string GetChipsetInfoModuleName() {
677   std::string module;
678   int adapter_index = GetAdapterIndex();
679   std::string path = base::StringPrintf(kChipsetInfoModaliasPath, adapter_index);
680 
681   if (base::ReadFileToString(base::FilePath(path), &module)) {
682     return base::CollapseWhitespaceASCII(module, false);
683   }
684   return "";
685 }
686 
GetChipsetInfoTransport(void)687 static MetricTransportType GetChipsetInfoTransport(void) {
688   MetricTransportType transport = MetricTransportType::TRANSPORT_TYPE_UNKNOWN;
689   base::FilePath module_realpath;
690   std::string module_name;
691   int adapter_index = GetAdapterIndex();
692   std::string path = base::StringPrintf(kChipInfoModuleDirPath, adapter_index);
693 
694   // examples of module_realpath: /sys/module/btusb and /sys/module/hci_uart
695   module_realpath = base::MakeAbsoluteFilePath(base::FilePath(path));
696   if (module_realpath.empty()) {
697     return transport;
698   }
699 
700   module_name = module_realpath.BaseName().value();
701   if (base::MatchPattern(module_name, "*usb*")) {
702     transport = MetricTransportType::TRANSPORT_TYPE_USB;
703   } else if (base::MatchPattern(module_name, "*uart*")) {
704     transport = MetricTransportType::TRANSPORT_TYPE_UART;
705   } else if (base::MatchPattern(module_name, "*sdio*")) {
706     transport = MetricTransportType::TRANSPORT_TYPE_SDIO;
707   }
708 
709   return transport;
710 }
711 
GetMetricsChipsetInfo()712 MetricsChipsetInfo GetMetricsChipsetInfo() {
713   MetricsChipsetInfo info;
714 
715   info.vid = GetChipsetInfoId(kChipsetInfoWlanDirPath, "vendor");
716   info.pid = GetChipsetInfoId(kChipsetInfoWlanDirPath, "device");
717 
718   if (!info.vid || !info.pid) {
719     info.vid = GetChipsetInfoId(kChipsetInfoMlanDirPath, "vendor");
720     info.pid = GetChipsetInfoId(kChipsetInfoMlanDirPath, "device");
721   }
722 
723   if (!info.vid || !info.pid) {
724     info.chipset_string = GetChipsetInfoModuleName();
725   }
726 
727   info.transport = (int)GetChipsetInfoTransport();
728   return info;
729 }
730 
731 }  // namespace metrics
732 }  // namespace bluetooth
733