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 17 #pragma once 18 19 #include <hardware/bt_le_audio.h> 20 21 #include <chrono> 22 #include <cstdint> 23 #include <memory> 24 #include <unordered_map> 25 26 #include "le_audio_types.h" 27 #include "types/raw_address.h" 28 29 namespace bluetooth::le_audio { 30 31 namespace metrics { 32 using ClockTimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>; 33 } 34 35 enum ConnectionStatus : int32_t { 36 UNKNOWN = 0, 37 SUCCESS = 1, 38 FAILED = 2, 39 }; 40 41 /* android.bluetooth.leaudio.ContextType */ 42 enum class LeAudioMetricsContextType : int32_t { 43 INVALID = 0, 44 UNSPECIFIED = 1, 45 COMMUNICATION = 2, 46 MEDIA = 3, 47 INSTRUCTIONAL = 4, 48 ATTENTION_SEEKING = 5, 49 IMMEDIATE_ALERT = 6, 50 MAN_MACHINE = 7, 51 EMERGENCY_ALERT = 8, 52 RINGTONE = 9, 53 TV = 10, 54 LIVE = 11, 55 GAME = 12, 56 RFU = 13, 57 }; 58 59 class GroupMetrics { 60 public: GroupMetrics()61 GroupMetrics() {} 62 ~GroupMetrics()63 virtual ~GroupMetrics() {} 64 65 virtual void AddStateChangedEvent(const RawAddress& address, 66 bluetooth::le_audio::ConnectionState state, 67 ConnectionStatus status) = 0; 68 69 virtual void AddStreamStartedEvent( 70 bluetooth::le_audio::types::LeAudioContextType context_type) = 0; 71 72 virtual void AddStreamEndedEvent() = 0; 73 74 virtual void SetGroupSize(int32_t group_size) = 0; 75 76 virtual bool IsClosed() = 0; 77 78 virtual void WriteStats() = 0; 79 80 virtual void Flush() = 0; 81 }; 82 83 class MetricsCollector { 84 public: 85 static MetricsCollector* Get(); 86 87 /** 88 * Update the size of given group which will be used in the 89 * LogMetricBluetoothLeAudioConnectionStateChanged() 90 * 91 * @param group_id ID of target group 92 * @param group_size Size of target group 93 */ 94 void OnGroupSizeUpdate(int32_t group_id, int32_t group_size); 95 96 /** 97 * When there is a change in Bluetooth LE Audio connection state 98 * 99 * @param group_id Group ID of the associated device. 100 * @param address Address of the associated device. 101 * @param state New LE Audio connetion state. 102 * @param status status or reason of the state transition. Ignored at 103 * CONNECTING states. 104 */ 105 void OnConnectionStateChanged(int32_t group_id, const RawAddress& address, 106 bluetooth::le_audio::ConnectionState state, 107 ConnectionStatus status); 108 109 /** 110 * When there is a change in LE Audio stream started 111 * 112 * @param group_id Group ID of the associated stream. 113 */ 114 void OnStreamStarted(int32_t group_id, 115 bluetooth::le_audio::types::LeAudioContextType context_type); 116 117 /** 118 * When there is a change in LE Audio stream started 119 * 120 * @param group_id Group ID of the associated stream. 121 */ 122 void OnStreamEnded(int32_t group_id); 123 124 /** 125 * When there is a change in Bluetooth LE Audio broadcast state 126 * 127 * @param started if broadcast streaming is started. 128 */ 129 void OnBroadcastStateChanged(bool started); 130 131 /** 132 * Flush all log to statsd 133 * 134 * @param group_id Group ID of the associated stream. 135 */ 136 void Flush(); 137 138 protected: MetricsCollector()139 MetricsCollector() {} 140 141 private: 142 static MetricsCollector* instance; 143 144 std::unordered_map<int32_t, std::unique_ptr<GroupMetrics>> opened_groups_; 145 std::unordered_map<int32_t, int32_t> group_size_table_; 146 147 metrics::ClockTimePoint broadcast_beginning_timepoint_; 148 }; 149 150 } // namespace bluetooth::le_audio 151