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 #ifndef CPP_EVS_MANAGER_AIDL_STATS_INCLUDE_STATSCOLLECTOR_H
18 #define CPP_EVS_MANAGER_AIDL_STATS_INCLUDE_STATSCOLLECTOR_H
19 
20 #include "CameraUsageStats.h"
21 #include "LooperWrapper.h"
22 
23 #include <android-base/chrono_utils.h>
24 #include <android-base/logging.h>
25 #include <android-base/result.h>
26 #include <utils/Mutex.h>
27 
28 #include <deque>
29 #include <thread>
30 #include <unordered_map>
31 #include <vector>
32 
33 namespace aidl::android::automotive::evs::implementation {
34 
35 class HalCamera;  // From HalCamera.h
36 
37 enum CollectionEvent {
38     INIT = 0,
39     PERIODIC,
40     CUSTOM_START,
41     CUSTOM_END,
42     TERMINATED,
43 };
44 
45 struct CollectionRecord {
46     // Latest statistics collection
47     CameraUsageStatsRecord latest = {};
48 
49     // History of collected statistics records
50     std::deque<CameraUsageStatsRecord> history;
51 };
52 
53 struct CollectionInfo {
54     // Collection interval between two subsequent collections
55     std::chrono::nanoseconds interval = 0ns;
56 
57     // The maximum number of records this collection stores
58     size_t maxCacheSize = 0;
59 
60     // Time when the latest collection was done
61     nsecs_t lastCollectionTime = 0;
62 
63     // Collected statistics records per instances
64     std::unordered_map<std::string, CollectionRecord> records;
65 };
66 
67 class StatsCollector : public ::android::MessageHandler {
68 public:
StatsCollector()69     explicit StatsCollector() :
70           mLooper(new LooperWrapper()),
71           mCurrentCollectionEvent(CollectionEvent::INIT),
72           mPeriodicCollectionInfo({}),
73           mCustomCollectionInfo({}) {}
74 
~StatsCollector()75     virtual ~StatsCollector() { stopCollection(); }
76 
77     // Starts collecting CameraUsageStats
78     ::android::base::Result<void> startCollection();
79 
80     // Stops collecting the statistics
81     ::android::base::Result<void> stopCollection();
82 
83     // Starts collecting CameraUsageStarts during a given duration at a given
84     // interval.
85     ::android::base::Result<void> startCustomCollection(std::chrono::nanoseconds interval,
86                                                         std::chrono::nanoseconds duration)
87             EXCLUDES(mMutex);
88 
89     // Stops current custom collection and shows the result from the device with
90     // a given unique id.  If this is "all",all results
91     // will be returned.
92     ::android::base::Result<std::string> stopCustomCollection(const std::string& id = "")
93             EXCLUDES(mMutex);
94 
95     // Registers HalCamera object to monitor
96     ::android::base::Result<void> registerClientToMonitor(const std::shared_ptr<HalCamera>& camera)
97             EXCLUDES(mMutex);
98 
99     // Unregister HalCamera object
100     ::android::base::Result<void> unregisterClientToMonitor(const std::string& id) EXCLUDES(mMutex);
101 
102     // Returns a string that contains the latest statistics pulled from
103     // currently active clients
104     ::android::base::Result<void> toString(std::unordered_map<std::string, std::string>* usages,
105                                            const char* indent = "") EXCLUDES(mMutex);
106 
107 private:
108     // Mutex to protect records
109     mutable ::android::Mutex mMutex;
110 
111     // Looper to message the collection thread
112     ::android::sp<LooperWrapper> mLooper;
113 
114     // Background thread to pull stats from the clients
115     std::thread mCollectionThread;
116 
117     // Current state of the monitor
118     CollectionEvent mCurrentCollectionEvent GUARDED_BY(mMutex);
119 
120     // Periodic collection information
121     CollectionInfo mPeriodicCollectionInfo GUARDED_BY(mMutex);
122 
123     // A collection during the custom period the user sets
124     CollectionInfo mCustomCollectionInfo GUARDED_BY(mMutex);
125 
126     // A list of HalCamera objects to monitor
127     std::unordered_map<std::string, std::weak_ptr<HalCamera>> mClientsToMonitor GUARDED_BY(mMutex);
128 
129     // Handles the messages from the looper
130     void handleMessage(const ::android::Message& message) override;
131 
132     // Handles each CollectionEvent
133     ::android::base::Result<void> handleCollectionEvent(CollectionEvent event, CollectionInfo* info)
134             EXCLUDES(mMutex);
135 
136     // Pulls the statistics from each active HalCamera objects and generates the
137     // records
138     ::android::base::Result<void> collectLocked(CollectionInfo* info) REQUIRES(mMutex);
139 
140     // Returns a string corresponding to a given collection event
141     std::string toString(const CollectionEvent& event) const;
142 };
143 
144 }  // namespace aidl::android::automotive::evs::implementation
145 
146 #endif  // CPP_EVS_MANAGER_AIDL_STATS_INCLUDE_STATSCOLLECTOR_H
147