Home | History | Annotate | Download | only in src
      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 #define LOG_TAG "bt_osi_metrics"
     19 
     20 #include <unistd.h>
     21 #include <algorithm>
     22 #include <cerrno>
     23 #include <chrono>
     24 #include <cstdint>
     25 #include <cstring>
     26 #include <memory>
     27 #include <mutex>
     28 
     29 #include <base/base64.h>
     30 #include <base/logging.h>
     31 
     32 #include "osi/include/leaky_bonded_queue.h"
     33 #include "osi/include/log.h"
     34 #include "osi/include/osi.h"
     35 #include "osi/include/time.h"
     36 
     37 #include "osi/include/metrics.h"
     38 
     39 namespace system_bt_osi {
     40 
     41 // Maximum number of log entries for each repeated field
     42 #define MAX_NUM_BLUETOOTH_SESSION 50
     43 #define MAX_NUM_PAIR_EVENT 50
     44 #define MAX_NUM_WAKE_EVENT 50
     45 #define MAX_NUM_SCAN_EVENT 50
     46 
     47 static float combine_averages(float avg_a, int64_t ct_a, float avg_b,
     48                               int64_t ct_b) {
     49   if (ct_a > 0 && ct_b > 0) {
     50     return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b);
     51   } else if (ct_b > 0) {
     52     return avg_b;
     53   } else {
     54     return avg_a;
     55   }
     56 }
     57 
     58 static int32_t combine_averages(int32_t avg_a, int64_t ct_a, int32_t avg_b,
     59                                 int64_t ct_b) {
     60   if (ct_a > 0 && ct_b > 0) {
     61     return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b);
     62   } else if (ct_b > 0) {
     63     return avg_b;
     64   } else {
     65     return avg_a;
     66   }
     67 }
     68 
     69 void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
     70   if (metrics.audio_duration_ms > 0) {
     71     audio_duration_ms = std::max(static_cast<int64_t>(0), audio_duration_ms);
     72     audio_duration_ms += metrics.audio_duration_ms;
     73   }
     74   if (metrics.media_timer_min_ms > 0) {
     75     if (media_timer_min_ms < 0) {
     76       media_timer_min_ms = metrics.media_timer_min_ms;
     77     } else {
     78       media_timer_min_ms =
     79           std::min(media_timer_min_ms, metrics.media_timer_min_ms);
     80     }
     81   }
     82   if (metrics.media_timer_max_ms > 0) {
     83     media_timer_max_ms =
     84         std::max(media_timer_max_ms, metrics.media_timer_max_ms);
     85   }
     86   if (metrics.media_timer_avg_ms > 0 && metrics.total_scheduling_count > 0) {
     87     if (media_timer_avg_ms < 0 || total_scheduling_count < 0) {
     88       media_timer_avg_ms = metrics.media_timer_avg_ms;
     89       total_scheduling_count = metrics.total_scheduling_count;
     90     } else {
     91       media_timer_avg_ms = combine_averages(
     92           media_timer_avg_ms, total_scheduling_count,
     93           metrics.media_timer_avg_ms, metrics.total_scheduling_count);
     94       total_scheduling_count += metrics.total_scheduling_count;
     95     }
     96   }
     97   if (metrics.buffer_overruns_max_count > 0) {
     98     buffer_overruns_max_count =
     99         std::max(buffer_overruns_max_count, metrics.buffer_overruns_max_count);
    100   }
    101   if (metrics.buffer_overruns_total > 0) {
    102     buffer_overruns_total =
    103         std::max(static_cast<int32_t>(0), buffer_overruns_total);
    104     buffer_overruns_total += metrics.buffer_overruns_total;
    105   }
    106   if (metrics.buffer_underruns_average > 0 &&
    107       metrics.buffer_underruns_count > 0) {
    108     if (buffer_underruns_average < 0 || buffer_underruns_count < 0) {
    109       buffer_underruns_average = metrics.buffer_underruns_average;
    110       buffer_underruns_count = metrics.buffer_underruns_count;
    111     } else {
    112       buffer_underruns_average = combine_averages(
    113           metrics.buffer_underruns_average, metrics.buffer_underruns_count,
    114           buffer_underruns_average, buffer_underruns_count);
    115       buffer_underruns_count += metrics.buffer_underruns_count;
    116     }
    117   }
    118 }
    119 
    120 bool A2dpSessionMetrics::operator==(const A2dpSessionMetrics& rhs) const {
    121   return audio_duration_ms == rhs.audio_duration_ms &&
    122          media_timer_min_ms == rhs.media_timer_min_ms &&
    123          media_timer_max_ms == rhs.media_timer_max_ms &&
    124          media_timer_avg_ms == rhs.media_timer_avg_ms &&
    125          total_scheduling_count == rhs.total_scheduling_count &&
    126          buffer_overruns_max_count == rhs.buffer_overruns_max_count &&
    127          buffer_overruns_total == rhs.buffer_overruns_total &&
    128          buffer_underruns_average == rhs.buffer_underruns_average &&
    129          buffer_underruns_count == rhs.buffer_underruns_count;
    130 }
    131 
    132 struct BluetoothMetricsLogger::impl {
    133   // TODO(siyuanh): Implement for linux
    134 };
    135 
    136 BluetoothMetricsLogger::BluetoothMetricsLogger() : pimpl_(new impl) {}
    137 
    138 void BluetoothMetricsLogger::LogPairEvent(uint32_t disconnect_reason,
    139                                           uint64_t timestamp_ms,
    140                                           uint32_t device_class,
    141                                           device_type_t device_type) {
    142   // TODO(siyuanh): Implement for linux
    143 }
    144 
    145 void BluetoothMetricsLogger::LogWakeEvent(wake_event_type_t type,
    146                                           const std::string& requestor,
    147                                           const std::string& name,
    148                                           uint64_t timestamp_ms) {
    149   // TODO(siyuanh): Implement for linux
    150 }
    151 
    152 void BluetoothMetricsLogger::LogScanEvent(bool start,
    153                                           const std::string& initator,
    154                                           scan_tech_t type, uint32_t results,
    155                                           uint64_t timestamp_ms) {
    156   // TODO(siyuanh): Implement for linux
    157 }
    158 
    159 void BluetoothMetricsLogger::LogBluetoothSessionStart(
    160     connection_tech_t connection_tech_type, uint64_t timestamp_ms) {
    161   // TODO(siyuanh): Implement for linux
    162 }
    163 
    164 void BluetoothMetricsLogger::LogBluetoothSessionEnd(
    165     disconnect_reason_t disconnect_reason, uint64_t timestamp_ms) {
    166   // TODO(siyuanh): Implement for linux
    167 }
    168 
    169 void BluetoothMetricsLogger::LogBluetoothSessionDeviceInfo(
    170     uint32_t device_class, device_type_t device_type) {
    171   // TODO(siyuanh): Implement for linux
    172 }
    173 
    174 void BluetoothMetricsLogger::LogA2dpSession(
    175     const A2dpSessionMetrics& a2dp_session_metrics) {
    176   // TODO(siyuanh): Implement for linux
    177 }
    178 
    179 void BluetoothMetricsLogger::WriteString(std::string* serialized, bool clear) {
    180   // TODO(siyuanh): Implement for linux
    181 }
    182 
    183 void BluetoothMetricsLogger::WriteBase64String(std::string* serialized,
    184                                                bool clear) {
    185   // TODO(siyuanh): Implement for linux
    186 }
    187 
    188 void BluetoothMetricsLogger::WriteBase64(int fd, bool clear) {
    189   // TODO(siyuanh): Implement for linux
    190 }
    191 
    192 void BluetoothMetricsLogger::CutoffSession() {
    193   // TODO(siyuanh): Implement for linux
    194 }
    195 
    196 void BluetoothMetricsLogger::Build() {
    197   // TODO(siyuanh): Implement for linux
    198 }
    199 
    200 void BluetoothMetricsLogger::Reset() {
    201   // TODO(siyuanh): Implement for linux
    202 }
    203 
    204 }  // namespace system_bt_osi
    205