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 <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h>
20 
21 #include <chrono>
22 #include <cstdint>
23 #include <memory>
24 #include <unordered_map>
25 #include <utility>
26 #include <vector>
27 
28 #include "common/strings.h"
29 #include "hci/address.h"
30 #include "os/metrics.h"
31 
32 namespace bluetooth {
33 
34 namespace metrics {
35 
36 using android::bluetooth::le::LeAclConnectionState;
37 using android::bluetooth::le::LeConnectionOriginType;
38 using android::bluetooth::le::LeConnectionState;
39 using android::bluetooth::le::LeConnectionType;
40 
41 using ClockTimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;
42 
43 const static ClockTimePoint kInvalidTimePoint{};
44 
get_timedelta_nanos(const ClockTimePoint & t1,const ClockTimePoint & t2)45 inline int64_t get_timedelta_nanos(const ClockTimePoint& t1, const ClockTimePoint& t2) {
46   if (t1 == kInvalidTimePoint || t2 == kInvalidTimePoint) {
47     return -1;
48   }
49   return std::abs(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
50 }
51 
52 class BaseMetricsLoggerModule {
53  public:
BaseMetricsLoggerModule()54   BaseMetricsLoggerModule() {}
55   virtual void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options) = 0;
~BaseMetricsLoggerModule()56   virtual ~BaseMetricsLoggerModule() {}
57 };
58 
59 class MetricsLoggerModule : public BaseMetricsLoggerModule {
60  public:
MetricsLoggerModule()61   MetricsLoggerModule() {}
62   void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options);
~MetricsLoggerModule()63   virtual ~MetricsLoggerModule() {}
64 };
65 
66 class LEConnectionMetricState {
67  public:
68   hci::Address address;
LEConnectionMetricState(const hci::Address address)69   LEConnectionMetricState(const hci::Address address) : address(address) {}
70   LeConnectionState state;
71   LeAclConnectionState acl_state;
72   LeConnectionType input_connection_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED;
73   android::bluetooth::hci::StatusEnum acl_status_code;
74   ClockTimePoint start_timepoint = kInvalidTimePoint;
75   ClockTimePoint end_timepoint = kInvalidTimePoint;
76   bool is_cancelled = false;
77   LeConnectionOriginType connection_origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED;
78 
79   bool IsStarted();
80   bool IsEnded();
81   bool IsCancelled();
82 
83   void AddStateChangedEvent(
84       LeConnectionOriginType origin_type,
85       LeConnectionType connection_type,
86       LeConnectionState transaction_state,
87       std::vector<std::pair<os::ArgumentType, int>> argument_list);
88 
89 };
90 
91 class LEConnectionMetricsRemoteDevice {
92  public:
93   LEConnectionMetricsRemoteDevice();
94 
95   LEConnectionMetricsRemoteDevice(BaseMetricsLoggerModule* baseMetricsLoggerModule);
96 
97   void AddStateChangedEvent(
98       const hci::Address& address,
99       LeConnectionOriginType origin_type,
100       LeConnectionType connection_type,
101       LeConnectionState transaction_state,
102       std::vector<std::pair<os::ArgumentType, int>> argument_list);
103 
104   void UploadLEConnectionSession(const hci::Address& address);
105 
106  private:
107   mutable std::mutex le_connection_metrics_remote_device_guard;
108   std::vector<std::unique_ptr<LEConnectionMetricState>> device_metrics;
109   std::unordered_map<hci::Address, LEConnectionMetricState*> opened_devices;
110   BaseMetricsLoggerModule* metrics_logger_module;
111 };
112 
113 class MetricsCollector {
114  public:
115   // getting the LE Connection Metrics Collector
116   static LEConnectionMetricsRemoteDevice* GetLEConnectionMetricsCollector();
117 
118  private:
119   static LEConnectionMetricsRemoteDevice* le_connection_metrics_remote_device;
120 };
121 
122 }  // namespace metrics
123 }  // namespace bluetooth
124