• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "stats/include/CameraUsageStats.h"
18 
19 #include <android-base/logging.h>
20 
21 #include <statslog_evsmanagerd.h>
22 
23 namespace {
24 
25 using ::aidl::android::hardware::automotive::evs::BufferDesc;
26 using ::android::AutoMutex;
27 using ::android::base::StringAppendF;
28 
29 // Length of frame roundTrip history
30 constexpr int32_t kMaxHistoryLength = 100;
31 
32 }  // namespace
33 
34 namespace aidl::android::automotive::evs::implementation {
35 
updateFrameStatsOnArrivalLocked(const std::vector<BufferDesc> & bufs)36 void CameraUsageStats::updateFrameStatsOnArrivalLocked(const std::vector<BufferDesc>& bufs) {
37     const auto now = ::android::uptimeMillis();
38     for (const auto& b : bufs) {
39         mBufferHistory.insert_or_assign(b.bufferId, now);
40     }
41 }
42 
updateFrameStatsOnReturnLocked(const std::vector<BufferDesc> & bufs)43 void CameraUsageStats::updateFrameStatsOnReturnLocked(const std::vector<BufferDesc>& bufs) {
44     const auto now = ::android::uptimeMillis();
45     for (auto& b : bufs) {
46         auto it = mBufferHistory.find(b.bufferId);
47         if (it == mBufferHistory.end()) {
48             LOG(WARNING) << "Buffer " << b.bufferId << " from " << b.deviceId << " is unknown.";
49         } else {
50             const auto roundTrip = now - it->second.timestamp;
51             it->second.history.push(roundTrip);
52             it->second.sum += roundTrip;
53             if (it->second.history.size() > kMaxHistoryLength) {
54                 it->second.sum -= it->second.history.front();
55                 it->second.history.pop();
56             }
57 
58             if (roundTrip > it->second.peak) {
59                 it->second.peak = roundTrip;
60             }
61 
62             if (mStats.framesFirstRoundtripLatency == 0) {
63                 mStats.framesFirstRoundtripLatency = roundTrip;
64             }
65         }
66     }
67 }
68 
framesReceived(int32_t n)69 void CameraUsageStats::framesReceived(int32_t n) {
70     AutoMutex lock(mMutex);
71     mStats.framesReceived += n;
72 }
73 
framesReceived(const std::vector<BufferDesc> & bufs)74 void CameraUsageStats::framesReceived(const std::vector<BufferDesc>& bufs) {
75     AutoMutex lock(mMutex);
76     mStats.framesReceived += bufs.size();
77 
78     updateFrameStatsOnArrivalLocked(bufs);
79 }
80 
framesReturned(int32_t n)81 void CameraUsageStats::framesReturned(int32_t n) {
82     AutoMutex lock(mMutex);
83     mStats.framesReturned += n;
84 }
85 
framesReturned(const std::vector<BufferDesc> & bufs)86 void CameraUsageStats::framesReturned(const std::vector<BufferDesc>& bufs) {
87     AutoMutex lock(mMutex);
88     mStats.framesReturned += bufs.size();
89 
90     updateFrameStatsOnReturnLocked(bufs);
91 }
92 
framesIgnored(int32_t n)93 void CameraUsageStats::framesIgnored(int32_t n) {
94     AutoMutex lock(mMutex);
95     mStats.framesIgnored += n;
96 }
97 
framesSkippedToSync(int32_t n)98 void CameraUsageStats::framesSkippedToSync(int32_t n) {
99     AutoMutex lock(mMutex);
100     mStats.framesSkippedToSync += n;
101 }
102 
eventsReceived()103 void CameraUsageStats::eventsReceived() {
104     AutoMutex lock(mMutex);
105     ++mStats.erroneousEventsCount;
106 }
107 
updateNumClients(size_t n)108 void CameraUsageStats::updateNumClients(size_t n) {
109     AutoMutex lock(mMutex);
110     if (n > mStats.peakClientsCount) {
111         mStats.peakClientsCount = n;
112     }
113 }
114 
getTimeCreated() const115 int64_t CameraUsageStats::getTimeCreated() const {
116     AutoMutex lock(mMutex);
117     return mTimeCreatedMs;
118 }
119 
getFramesReceived() const120 int64_t CameraUsageStats::getFramesReceived() const {
121     AutoMutex lock(mMutex);
122     return mStats.framesReceived;
123 }
124 
getFramesReturned() const125 int64_t CameraUsageStats::getFramesReturned() const {
126     AutoMutex lock(mMutex);
127     return mStats.framesReturned;
128 }
129 
snapshot()130 CameraUsageStatsRecord CameraUsageStats::snapshot() {
131     AutoMutex lock(mMutex);
132 
133     int32_t sum = 0;
134     int32_t peak = 0;
135     int32_t len = 0;
136     for (auto& [_, rec] : mBufferHistory) {
137         sum += rec.sum;
138         len += rec.history.size();
139         if (peak < rec.peak) {
140             peak = rec.peak;
141         }
142     }
143 
144     mStats.framesPeakRoundtripLatency = peak;
145     mStats.framesAvgRoundtripLatency = static_cast<double>(sum) / len;
146     return mStats;
147 }
148 
writeStats() const149 void CameraUsageStats::writeStats() const {
150     using ::aidl::android::automotive::evs::stats::EVS_USAGE_STATS_REPORTED;
151     using ::aidl::android::automotive::evs::stats::stats_write;
152     AutoMutex lock(mMutex);
153 
154     // Reports the usage statistics before the destruction
155     // EvsUsageStatsReported atom is defined in
156     // frameworks/base/cmds/statsd/src/atoms.proto
157     const auto duration = ::android::uptimeMillis() - mTimeCreatedMs;
158     auto result = stats_write(EVS_USAGE_STATS_REPORTED, mId, mStats.peakClientsCount,
159                               mStats.erroneousEventsCount, mStats.framesFirstRoundtripLatency,
160                               mStats.framesAvgRoundtripLatency, mStats.framesPeakRoundtripLatency,
161                               mStats.framesReceived, mStats.framesIgnored,
162                               mStats.framesSkippedToSync, duration);
163     if (result < 0) {
164         LOG(WARNING) << "Failed to report usage stats";
165     }
166 }
167 
toString(const CameraUsageStatsRecord & record,const char * indent)168 std::string CameraUsageStats::toString(const CameraUsageStatsRecord& record, const char* indent) {
169     return record.toString(indent);
170 }
171 
172 }  // namespace aidl::android::automotive::evs::implementation
173