1 /*
2 * Copyright (C) 2016 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 #define LOG_TAG "Camera3-TagMonitor"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include "TagMonitor.h"
22
23 #include <inttypes.h>
24 #include <utils/Log.h>
25 #include <camera/VendorTagDescriptor.h>
26 #include <camera_metadata_hidden.h>
27
28 namespace android {
29
TagMonitor()30 TagMonitor::TagMonitor():
31 mMonitoringEnabled(false),
32 mMonitoringEvents(kMaxMonitorEvents),
33 mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID)
34 {}
35
TagMonitor(const TagMonitor & other)36 TagMonitor::TagMonitor(const TagMonitor& other):
37 mMonitoringEnabled(other.mMonitoringEnabled.load()),
38 mMonitoredTagList(other.mMonitoredTagList),
39 mLastMonitoredRequestValues(other.mLastMonitoredRequestValues),
40 mLastMonitoredResultValues(other.mLastMonitoredResultValues),
41 mLastMonitoredPhysicalRequestKeys(other.mLastMonitoredPhysicalRequestKeys),
42 mLastMonitoredPhysicalResultKeys(other.mLastMonitoredPhysicalResultKeys),
43 mMonitoringEvents(other.mMonitoringEvents),
44 mVendorTagId(other.mVendorTagId) {}
45
46 const String16 TagMonitor::kMonitorOption = String16("-m");
47
48 const char* TagMonitor::k3aTags =
49 "android.control.aeMode, android.control.afMode, android.control.awbMode,"
50 "android.control.aeState, android.control.afState, android.control.awbState,"
51 "android.control.aePrecaptureTrigger, android.control.afTrigger,"
52 "android.control.aeRegions, android.control.awbRegions, android.control.afRegions,"
53 "android.control.aeExposureCompensation, android.control.aeLock, android.control.awbLock,"
54 "android.control.aeAntibandingMode, android.control.aeTargetFpsRange,"
55 "android.control.effectMode, android.control.mode, android.control.sceneMode,"
56 "android.control.videoStabilizationMode";
57
parseTagsToMonitor(String8 tagNames)58 void TagMonitor::parseTagsToMonitor(String8 tagNames) {
59 std::lock_guard<std::mutex> lock(mMonitorMutex);
60
61 // Expand shorthands
62 ssize_t idx = tagNames.find("3a");
63 if (idx != -1) {
64 ssize_t end = tagNames.find(",", idx);
65 char* start = tagNames.lockBuffer(tagNames.size());
66 start[idx] = '\0';
67 char* rest = (end != -1) ? (start + end) : (start + tagNames.size());
68 tagNames = String8::format("%s%s%s", start, k3aTags, rest);
69 }
70
71 sp<VendorTagDescriptor> vTags =
72 VendorTagDescriptor::getGlobalVendorTagDescriptor();
73 if ((nullptr == vTags.get()) || (0 >= vTags->getTagCount())) {
74 sp<VendorTagDescriptorCache> cache =
75 VendorTagDescriptorCache::getGlobalVendorTagCache();
76 if (cache.get()) {
77 cache->getVendorTagDescriptor(mVendorTagId, &vTags);
78 }
79 }
80
81 bool gotTag = false;
82
83 char *tokenized = tagNames.lockBuffer(tagNames.size());
84 char *savePtr;
85 char *nextTagName = strtok_r(tokenized, ", ", &savePtr);
86 while (nextTagName != nullptr) {
87 uint32_t tag;
88 status_t res = CameraMetadata::getTagFromName(nextTagName, vTags.get(), &tag);
89 if (res != OK) {
90 ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName);
91 } else {
92 if (!gotTag) {
93 mMonitoredTagList.clear();
94 gotTag = true;
95 }
96 mMonitoredTagList.push_back(tag);
97 }
98 nextTagName = strtok_r(nullptr, ", ", &savePtr);
99 }
100
101 tagNames.unlockBuffer();
102
103 if (gotTag) {
104 // Got at least one new tag
105 mMonitoringEnabled = true;
106 }
107 }
108
disableMonitoring()109 void TagMonitor::disableMonitoring() {
110 mMonitoringEnabled = false;
111 mLastMonitoredRequestValues.clear();
112 mLastMonitoredResultValues.clear();
113 mLastMonitoredPhysicalRequestKeys.clear();
114 mLastMonitoredPhysicalResultKeys.clear();
115 }
116
monitorMetadata(eventSource source,int64_t frameNumber,nsecs_t timestamp,const CameraMetadata & metadata,const std::unordered_map<std::string,CameraMetadata> & physicalMetadata)117 void TagMonitor::monitorMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp,
118 const CameraMetadata& metadata,
119 const std::unordered_map<std::string, CameraMetadata>& physicalMetadata) {
120 if (!mMonitoringEnabled) return;
121
122 std::lock_guard<std::mutex> lock(mMonitorMutex);
123
124 if (timestamp == 0) {
125 timestamp = systemTime(SYSTEM_TIME_BOOTTIME);
126 }
127
128 std::string emptyId;
129 for (auto tag : mMonitoredTagList) {
130 monitorSingleMetadata(source, frameNumber, timestamp, emptyId, tag, metadata);
131
132 for (auto& m : physicalMetadata) {
133 monitorSingleMetadata(source, frameNumber, timestamp, m.first, tag, m.second);
134 }
135 }
136 }
137
monitorSingleMetadata(eventSource source,int64_t frameNumber,nsecs_t timestamp,const std::string & cameraId,uint32_t tag,const CameraMetadata & metadata)138 void TagMonitor::monitorSingleMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp,
139 const std::string& cameraId, uint32_t tag, const CameraMetadata& metadata) {
140
141 CameraMetadata &lastValues = (source == REQUEST) ?
142 (cameraId.empty() ? mLastMonitoredRequestValues :
143 mLastMonitoredPhysicalRequestKeys[cameraId]) :
144 (cameraId.empty() ? mLastMonitoredResultValues :
145 mLastMonitoredPhysicalResultKeys[cameraId]);
146
147 camera_metadata_ro_entry entry = metadata.find(tag);
148 if (lastValues.isEmpty()) {
149 lastValues = CameraMetadata(mMonitoredTagList.size());
150 const camera_metadata_t *metaBuffer =
151 lastValues.getAndLock();
152 set_camera_metadata_vendor_id(
153 const_cast<camera_metadata_t *> (metaBuffer), mVendorTagId);
154 lastValues.unlock(metaBuffer);
155 }
156
157 camera_metadata_entry lastEntry = lastValues.find(tag);
158
159 if (entry.count > 0) {
160 bool isDifferent = false;
161 if (lastEntry.count > 0) {
162 // Have a last value, compare to see if changed
163 if (lastEntry.type == entry.type &&
164 lastEntry.count == entry.count) {
165 // Same type and count, compare values
166 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
167 size_t entryBytes = bytesPerValue * lastEntry.count;
168 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
169 if (cmp != 0) {
170 isDifferent = true;
171 }
172 } else {
173 // Count or type has changed
174 isDifferent = true;
175 }
176 } else {
177 // No last entry, so always consider to be different
178 isDifferent = true;
179 }
180
181 if (isDifferent) {
182 ALOGV("%s: Tag %s changed", __FUNCTION__,
183 get_local_camera_metadata_tag_name_vendor_id(
184 tag, mVendorTagId));
185 lastValues.update(entry);
186 mMonitoringEvents.emplace(source, frameNumber, timestamp, entry, cameraId);
187 }
188 } else if (lastEntry.count > 0) {
189 // Value has been removed
190 ALOGV("%s: Tag %s removed", __FUNCTION__,
191 get_local_camera_metadata_tag_name_vendor_id(
192 tag, mVendorTagId));
193 lastValues.erase(tag);
194 entry.tag = tag;
195 entry.type = get_local_camera_metadata_tag_type_vendor_id(tag,
196 mVendorTagId);
197 entry.count = 0;
198 mMonitoringEvents.emplace(source, frameNumber, timestamp, entry, cameraId);
199 }
200 }
201
dumpMonitoredMetadata(int fd)202 void TagMonitor::dumpMonitoredMetadata(int fd) {
203 std::lock_guard<std::mutex> lock(mMonitorMutex);
204
205 if (mMonitoringEnabled) {
206 dprintf(fd, " Tag monitoring enabled for tags:\n");
207 for (uint32_t tag : mMonitoredTagList) {
208 dprintf(fd, " %s.%s\n",
209 get_local_camera_metadata_section_name_vendor_id(tag,
210 mVendorTagId),
211 get_local_camera_metadata_tag_name_vendor_id(tag,
212 mVendorTagId));
213 }
214 } else {
215 dprintf(fd, " Tag monitoring disabled (enable with -m <name1,..,nameN>)\n");
216 }
217 if (mMonitoringEvents.size() > 0) {
218 dprintf(fd, " Monitored tag event log:\n");
219 for (const auto& event : mMonitoringEvents) {
220 int indentation = (event.source == REQUEST) ? 15 : 30;
221 dprintf(fd, " f%d:%" PRId64 "ns:%*s%*s%s.%s: ",
222 event.frameNumber, event.timestamp,
223 2, event.cameraId.c_str(),
224 indentation,
225 event.source == REQUEST ? "REQ:" : "RES:",
226 get_local_camera_metadata_section_name_vendor_id(event.tag,
227 mVendorTagId),
228 get_local_camera_metadata_tag_name_vendor_id(event.tag,
229 mVendorTagId));
230 if (event.newData.size() == 0) {
231 dprintf(fd, " (Removed)\n");
232 } else {
233 printData(fd, event.newData.data(), event.tag,
234 event.type, event.newData.size() / camera_metadata_type_size[event.type],
235 indentation + 18);
236 }
237 }
238 }
239
240 }
241
242 // TODO: Consolidate with printData from camera_metadata.h
243
244 #define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29
245
printData(int fd,const uint8_t * data_ptr,uint32_t tag,int type,int count,int indentation)246 void TagMonitor::printData(int fd, const uint8_t *data_ptr, uint32_t tag,
247 int type, int count, int indentation) {
248 static int values_per_line[NUM_TYPES] = {
249 [TYPE_BYTE] = 16,
250 [TYPE_INT32] = 8,
251 [TYPE_FLOAT] = 8,
252 [TYPE_INT64] = 4,
253 [TYPE_DOUBLE] = 4,
254 [TYPE_RATIONAL] = 4,
255 };
256 size_t type_size = camera_metadata_type_size[type];
257 char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];
258 uint32_t value;
259
260 int lines = count / values_per_line[type];
261 if (count % values_per_line[type] != 0) lines++;
262
263 int index = 0;
264 int j, k;
265 for (j = 0; j < lines; j++) {
266 dprintf(fd, "%*s[", (j != 0) ? indentation + 4 : 0, "");
267 for (k = 0;
268 k < values_per_line[type] && count > 0;
269 k++, count--, index += type_size) {
270
271 switch (type) {
272 case TYPE_BYTE:
273 value = *(data_ptr + index);
274 if (camera_metadata_enum_snprint(tag,
275 value,
276 value_string_tmp,
277 sizeof(value_string_tmp))
278 == OK) {
279 dprintf(fd, "%s ", value_string_tmp);
280 } else {
281 dprintf(fd, "%hhu ",
282 *(data_ptr + index));
283 }
284 break;
285 case TYPE_INT32:
286 value =
287 *(int32_t*)(data_ptr + index);
288 if (camera_metadata_enum_snprint(tag,
289 value,
290 value_string_tmp,
291 sizeof(value_string_tmp))
292 == OK) {
293 dprintf(fd, "%s ", value_string_tmp);
294 } else {
295 dprintf(fd, "%" PRId32 " ",
296 *(int32_t*)(data_ptr + index));
297 }
298 break;
299 case TYPE_FLOAT:
300 dprintf(fd, "%0.8f ",
301 *(float*)(data_ptr + index));
302 break;
303 case TYPE_INT64:
304 dprintf(fd, "%" PRId64 " ",
305 *(int64_t*)(data_ptr + index));
306 break;
307 case TYPE_DOUBLE:
308 dprintf(fd, "%0.8f ",
309 *(double*)(data_ptr + index));
310 break;
311 case TYPE_RATIONAL: {
312 int32_t numerator = *(int32_t*)(data_ptr + index);
313 int32_t denominator = *(int32_t*)(data_ptr + index + 4);
314 dprintf(fd, "(%d / %d) ",
315 numerator, denominator);
316 break;
317 }
318 default:
319 dprintf(fd, "??? ");
320 }
321 }
322 dprintf(fd, "]\n");
323 }
324 }
325
326 template<typename T>
MonitorEvent(eventSource src,uint32_t frameNumber,nsecs_t timestamp,const T & value,const std::string & cameraId)327 TagMonitor::MonitorEvent::MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp,
328 const T &value, const std::string& cameraId) :
329 source(src),
330 frameNumber(frameNumber),
331 timestamp(timestamp),
332 tag(value.tag),
333 type(value.type),
334 newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count),
335 cameraId(cameraId) {
336 }
337
~MonitorEvent()338 TagMonitor::MonitorEvent::~MonitorEvent() {
339 }
340
341 } // namespace android
342