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