• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2016 Google, Inc.
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 #include <stdint.h>
19 #include <memory>
20 #include <string>
21 
22 namespace system_bt_osi {
23 
24 /* Values of A2DP metrics that we care about
25  *
26  *    audio_duration_ms : sum of audio duration (in milliseconds).
27  *    device_class: device class of the paired device.
28  *    media_timer_min_ms : minimum scheduled time (in milliseconds)
29  *                         of the media timer.
30  *    media_timer_max_ms: maximum scheduled time (in milliseconds)
31  *                        of the media timer.
32  *    media_timer_avg_ms: average scheduled time (in milliseconds)
33  *                        of the media timer.
34  *    buffer_overruns_max_count: TODO - not clear what this is.
35  *    buffer_overruns_total : number of times the media buffer with
36  *                            audio data has overrun
37  *    buffer_underruns_average: TODO - not clear what this is.
38  *    buffer_underruns_count: number of times there was no enough
39  *                            audio data to add to the media buffer.
40  * NOTE: Negative values are invalid
41 */
42 class A2dpSessionMetrics {
43  public:
A2dpSessionMetrics()44   A2dpSessionMetrics() {}
45 
46   /*
47    * Update the metrics value in the current metrics object using the metrics
48    * objects supplied
49    */
50   void Update(const A2dpSessionMetrics& metrics);
51 
52   /*
53    * Compare whether two metrics objects are equal
54    */
55   bool operator==(const A2dpSessionMetrics& rhs) const;
56 
57   /*
58    * Initialize all values to -1 which is invalid in order to make a distinction
59    * between 0 and invalid values
60    */
61   int64_t audio_duration_ms = -1;
62   int32_t media_timer_min_ms = -1;
63   int32_t media_timer_max_ms = -1;
64   int32_t media_timer_avg_ms = -1;
65   int64_t total_scheduling_count = -1;
66   int32_t buffer_overruns_max_count = -1;
67   int32_t buffer_overruns_total = -1;
68   float buffer_underruns_average = -1;
69   int32_t buffer_underruns_count = -1;
70 };
71 
72 class BluetoothMetricsLogger {
73  public:
GetInstance()74   static BluetoothMetricsLogger* GetInstance() {
75     static BluetoothMetricsLogger* instance = new BluetoothMetricsLogger();
76     return instance;
77   }
78 
79   /*
80    * Record a pairing event
81    *
82    * Parameters:
83    *    timestamp_ms: Unix epoch time in milliseconds
84    *    device_class: class of remote device
85    *    device_type: type of remote device
86    *    disconnect_reason: HCI reason for pairing disconnection.
87    *                       See: stack/include/hcidefs.h
88    */
89   void LogPairEvent(uint32_t disconnect_reason, uint64_t timestamp_ms,
90                     uint32_t device_class, device_type_t device_type);
91 
92   /*
93    * Record a wake event
94    *
95    * Parameters:
96    *    timestamp_ms: Unix epoch time in milliseconds
97    *    type: whether it was acquired or released
98    *    requestor: if provided is the service requesting the wake lock
99    *    name: the name of the wake lock held
100    */
101   void LogWakeEvent(wake_event_type_t type, const std::string& requestor,
102                     const std::string& name, uint64_t timestamp_ms);
103 
104   /*
105    * Record a scan event
106    *
107    * Parameters
108    *    timestamp_ms : Unix epoch time in milliseconds
109    *    start : true if this is the beginning of the scan
110    *    initiator: a unique ID identifying the app starting the scan
111    *    type: whether the scan reports BR/EDR, LE, or both.
112    *    results: number of results to be reported.
113    */
114   void LogScanEvent(bool start, const std::string& initator, scan_tech_t type,
115                     uint32_t results, uint64_t timestamp_ms);
116 
117   /*
118    * Start logging a Bluetooth session
119    *
120    * A Bluetooth session is defined a a connection between this device and
121    * another remote device which may include multiple profiles and protocols
122    *
123    * Only one Bluetooth session can exist at one time. Calling this method twice
124    * without LogBluetoothSessionEnd will result in logging a premature end of
125    * current Bluetooth session
126    *
127    * Parameters:
128    *    connection_tech_type : type of connection technology
129    *    timestamp_ms : the timestamp for session start, 0 means now
130    *
131    */
132   void LogBluetoothSessionStart(connection_tech_t connection_tech_type,
133                                 uint64_t timestamp_ms);
134 
135   /*
136    * Stop logging a Bluetooth session and pushes it to the log queue
137    *
138    * If no Bluetooth session exist, this method exits immediately
139    *
140    * Parameters:
141    *    disconnect_reason : A string representation of disconnect reason
142    *    timestamp_ms : the timestamp of session end, 0 means now
143    *
144    */
145   void LogBluetoothSessionEnd(disconnect_reason_t disconnect_reason,
146                               uint64_t timestamp_ms);
147 
148   /*
149    * Log information about remote device in a current Bluetooth session
150    *
151    * If a Bluetooth session does not exist, create one with default parameter
152    * and timestamp now
153    *
154    * Parameters:
155    *    device_class : device_class defined in btm_api_types.h
156    *    device_type : type of remote device
157    */
158   void LogBluetoothSessionDeviceInfo(uint32_t device_class,
159                                      device_type_t device_type);
160 
161   /*
162    * Log A2DP Audio Session Information
163    *
164    * - Repeated calls to this method will override previous metrics if in the
165    *   same Bluetooth connection
166    * - If a Bluetooth session does not exist, create one with default parameter
167    *   and timestamp now
168    *
169    * Parameters:
170    *    a2dp_session_metrics - pointer to struct holding a2dp stats
171    *
172    */
173   void LogA2dpSession(const A2dpSessionMetrics& a2dp_session_metrics);
174 
175   /*
176    * Writes the metrics, in base64 protobuf format, into the descriptor FD
177    * If CLEAR is true, metrics events are cleared afterwards.
178    */
179   void WriteBase64(int fd, bool clear);
180   void WriteBase64String(std::string* serialized, bool clear);
181   void WriteString(std::string* serialized, bool clear);
182 
183   /*
184    * Reset the metrics logger by cleaning up its staging queues and existing
185    * protobuf objects.
186    */
187   void Reset();
188 
189   /*
190    * Maximum number of log entries for each session or event
191    */
192   static const size_t kMaxNumBluetoothSession = 50;
193   static const size_t kMaxNumPairEvent = 50;
194   static const size_t kMaxNumWakeEvent = 1000;
195   static const size_t kMaxNumScanEvent = 50;
196 
197  private:
198   BluetoothMetricsLogger();
199 
200   /*
201    * When a Bluetooth session is on and the user initiates a metrics dump, we
202    * need to be able to upload whatever we have first. This method breaks the
203    * ongoing Bluetooth session into two sessions with the previous one labeled
204    * as "METRICS_DUMP" for the disconnect reason.
205    */
206   void CutoffSession();
207 
208   /*
209    * Build the internal metrics object using information gathered
210    */
211   void Build();
212 
213   /*
214    * Reset objects related to current Bluetooth session
215    */
216   void ResetSession();
217 
218   /*
219    * Reset the underlining BluetoothLog object
220    */
221   void ResetLog();
222 
223   /*
224    * PIMPL style implementation to hide internal dependencies
225    */
226   struct impl;
227   std::unique_ptr<impl> const pimpl_;
228 };
229 
230 } // namespace system_bt_osi
231