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