You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
8.2 KiB
266 lines
8.2 KiB
/****************************************************************************** |
|
* |
|
* Copyright (C) 2016 Google, Inc. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at: |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
******************************************************************************/ |
|
|
|
#pragma once |
|
|
|
#include <stdint.h> |
|
#include <memory> |
|
#include <string> |
|
|
|
namespace system_bt_osi { |
|
|
|
// Typedefs to hide protobuf definition to the rest of stack |
|
|
|
typedef enum { |
|
DEVICE_TYPE_UNKNOWN, |
|
DEVICE_TYPE_BREDR, |
|
DEVICE_TYPE_LE, |
|
DEVICE_TYPE_DUMO, |
|
} device_type_t; |
|
|
|
typedef enum { |
|
WAKE_EVENT_UNKNOWN, |
|
WAKE_EVENT_ACQUIRED, |
|
WAKE_EVENT_RELEASED, |
|
} wake_event_type_t; |
|
|
|
typedef enum { |
|
SCAN_TYPE_UNKNOWN, |
|
SCAN_TECH_TYPE_LE, |
|
SCAN_TECH_TYPE_BREDR, |
|
SCAN_TECH_TYPE_BOTH, |
|
} scan_tech_t; |
|
|
|
typedef enum { |
|
CONNECTION_TECHNOLOGY_TYPE_UNKNOWN, |
|
CONNECTION_TECHNOLOGY_TYPE_LE, |
|
CONNECTION_TECHNOLOGY_TYPE_BREDR, |
|
} connection_tech_t; |
|
|
|
typedef enum { |
|
DISCONNECT_REASON_UNKNOWN, |
|
DISCONNECT_REASON_METRICS_DUMP, |
|
DISCONNECT_REASON_NEXT_START_WITHOUT_END_PREVIOUS, |
|
} disconnect_reason_t; |
|
|
|
/* Values of A2DP metrics that we care about |
|
* |
|
* audio_duration_ms : sum of audio duration (in milliseconds). |
|
* device_class: device class of the paired device. |
|
* media_timer_min_ms : minimum scheduled time (in milliseconds) |
|
* of the media timer. |
|
* media_timer_max_ms: maximum scheduled time (in milliseconds) |
|
* of the media timer. |
|
* media_timer_avg_ms: average scheduled time (in milliseconds) |
|
* of the media timer. |
|
* buffer_overruns_max_count: TODO - not clear what this is. |
|
* buffer_overruns_total : number of times the media buffer with |
|
* audio data has overrun |
|
* buffer_underruns_average: TODO - not clear what this is. |
|
* buffer_underruns_count: number of times there was no enough |
|
* audio data to add to the media buffer. |
|
* NOTE: Negative values are invalid |
|
*/ |
|
class A2dpSessionMetrics { |
|
public: |
|
A2dpSessionMetrics() {} |
|
|
|
/* |
|
* Update the metrics value in the current metrics object using the metrics |
|
* objects supplied |
|
*/ |
|
void Update(const A2dpSessionMetrics& metrics); |
|
|
|
/* |
|
* Compare whether two metrics objects are equal |
|
*/ |
|
bool operator==(const A2dpSessionMetrics& rhs) const; |
|
|
|
/* |
|
* Initialize all values to -1 which is invalid in order to make a distinction |
|
* between 0 and invalid values |
|
*/ |
|
int64_t audio_duration_ms = -1; |
|
int32_t media_timer_min_ms = -1; |
|
int32_t media_timer_max_ms = -1; |
|
int32_t media_timer_avg_ms = -1; |
|
int64_t total_scheduling_count = -1; |
|
int32_t buffer_overruns_max_count = -1; |
|
int32_t buffer_overruns_total = -1; |
|
float buffer_underruns_average = -1; |
|
int32_t buffer_underruns_count = -1; |
|
}; |
|
|
|
class BluetoothMetricsLogger { |
|
public: |
|
static BluetoothMetricsLogger* GetInstance() { |
|
static BluetoothMetricsLogger* instance = new BluetoothMetricsLogger(); |
|
return instance; |
|
} |
|
|
|
/* |
|
* Record a pairing event |
|
* |
|
* Parameters: |
|
* timestamp_ms: Unix epoch time in milliseconds |
|
* device_class: class of remote device |
|
* device_type: type of remote device |
|
* disconnect_reason: HCI reason for pairing disconnection. |
|
* See: stack/include/hcidefs.h |
|
*/ |
|
void LogPairEvent(uint32_t disconnect_reason, uint64_t timestamp_ms, |
|
uint32_t device_class, device_type_t device_type); |
|
|
|
/* |
|
* Record a wake event |
|
* |
|
* Parameters: |
|
* timestamp_ms: Unix epoch time in milliseconds |
|
* type: whether it was acquired or released |
|
* requestor: if provided is the service requesting the wake lock |
|
* name: the name of the wake lock held |
|
*/ |
|
void LogWakeEvent(wake_event_type_t type, const std::string& requestor, |
|
const std::string& name, uint64_t timestamp_ms); |
|
|
|
/* |
|
* Record a scan event |
|
* |
|
* Parameters |
|
* timestamp_ms : Unix epoch time in milliseconds |
|
* start : true if this is the beginning of the scan |
|
* initiator: a unique ID identifying the app starting the scan |
|
* type: whether the scan reports BR/EDR, LE, or both. |
|
* results: number of results to be reported. |
|
*/ |
|
void LogScanEvent(bool start, const std::string& initator, scan_tech_t type, |
|
uint32_t results, uint64_t timestamp_ms); |
|
|
|
/* |
|
* Start logging a Bluetooth session |
|
* |
|
* A Bluetooth session is defined a a connection between this device and |
|
* another remote device which may include multiple profiles and protocols |
|
* |
|
* Only one Bluetooth session can exist at one time. Calling this method twice |
|
* without LogBluetoothSessionEnd will result in logging a premature end of |
|
* current Bluetooth session |
|
* |
|
* Parameters: |
|
* connection_tech_type : type of connection technology |
|
* timestamp_ms : the timestamp for session start, 0 means now |
|
* |
|
*/ |
|
void LogBluetoothSessionStart(connection_tech_t connection_tech_type, |
|
uint64_t timestamp_ms); |
|
|
|
/* |
|
* Stop logging a Bluetooth session and pushes it to the log queue |
|
* |
|
* If no Bluetooth session exist, this method exits immediately |
|
* |
|
* Parameters: |
|
* disconnect_reason : A string representation of disconnect reason |
|
* timestamp_ms : the timestamp of session end, 0 means now |
|
* |
|
*/ |
|
void LogBluetoothSessionEnd(disconnect_reason_t disconnect_reason, |
|
uint64_t timestamp_ms); |
|
|
|
/* |
|
* Log information about remote device in a current Bluetooth session |
|
* |
|
* If a Bluetooth session does not exist, create one with default parameter |
|
* and timestamp now |
|
* |
|
* Parameters: |
|
* device_class : device_class defined in btm_api_types.h |
|
* device_type : type of remote device |
|
*/ |
|
void LogBluetoothSessionDeviceInfo(uint32_t device_class, |
|
device_type_t device_type); |
|
|
|
/* |
|
* Log A2DP Audio Session Information |
|
* |
|
* - Repeated calls to this method will override previous metrics if in the |
|
* same Bluetooth connection |
|
* - If a Bluetooth session does not exist, create one with default parameter |
|
* and timestamp now |
|
* |
|
* Parameters: |
|
* a2dp_session_metrics - pointer to struct holding a2dp stats |
|
* |
|
*/ |
|
void LogA2dpSession(const A2dpSessionMetrics& a2dp_session_metrics); |
|
|
|
/* |
|
* Writes the metrics, in base64 protobuf format, into the descriptor FD |
|
* If CLEAR is true, metrics events are cleared afterwards. |
|
*/ |
|
void WriteBase64(int fd, bool clear); |
|
void WriteBase64String(std::string* serialized, bool clear); |
|
void WriteString(std::string* serialized, bool clear); |
|
|
|
/* |
|
* Reset the metrics logger by cleaning up its staging queues and existing |
|
* protobuf objects. |
|
*/ |
|
void Reset(); |
|
|
|
/* |
|
* Maximum number of log entries for each session or event |
|
*/ |
|
static const size_t kMaxNumBluetoothSession = 50; |
|
static const size_t kMaxNumPairEvent = 50; |
|
static const size_t kMaxNumWakeEvent = 1000; |
|
static const size_t kMaxNumScanEvent = 50; |
|
|
|
private: |
|
BluetoothMetricsLogger(); |
|
|
|
/* |
|
* When a Bluetooth session is on and the user initiates a metrics dump, we |
|
* need to be able to upload whatever we have first. This method breaks the |
|
* ongoing Bluetooth session into two sessions with the previous one labeled |
|
* as "METRICS_DUMP" for the disconnect reason. |
|
*/ |
|
void CutoffSession(); |
|
|
|
/* |
|
* Build the internal metrics object using information gathered |
|
*/ |
|
void Build(); |
|
|
|
/* |
|
* Reset objects related to current Bluetooth session |
|
*/ |
|
void ResetSession(); |
|
|
|
/* |
|
* Reset the underlining BluetoothLog object |
|
*/ |
|
void ResetLog(); |
|
|
|
/* |
|
* PIMPL style implementation to hide internal dependencies |
|
*/ |
|
struct impl; |
|
std::unique_ptr<impl> const pimpl_; |
|
}; |
|
}
|
|
|