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 #ifndef ANDROID_SERVERS_CAMERA_TAGMONITOR_H
18 #define ANDROID_SERVERS_CAMERA_TAGMONITOR_H
19 
20 #include <vector>
21 #include <atomic>
22 #include <mutex>
23 #include <unordered_map>
24 #include <string>
25 
26 #include <utils/RefBase.h>
27 #include <utils/Timers.h>
28 
29 #include <media/RingBuffer.h>
30 #include <system/camera_metadata.h>
31 #include <system/camera_vendor_tags.h>
32 #include <camera/CameraMetadata.h>
33 #include <device3/InFlightRequest.h>
34 
35 namespace android {
36 
37 /**
38  * A monitor for camera metadata values.
39  * Tracks changes to specified metadata values over time, keeping a circular
40  * buffer log that can be dumped at will. */
41 class TagMonitor {
42   public:
43 
44     // Monitor argument
45     static const std::string kMonitorOption;
46 
47     enum eventSource {
48         REQUEST,
49         RESULT
50     };
51 
52     TagMonitor();
53 
54     TagMonitor(const TagMonitor& other);
55 
initialize(metadata_vendor_id_t id)56     void initialize(metadata_vendor_id_t id) { mVendorTagId = id; }
57 
58     // Parse tag name list (comma-separated) and if valid, enable monitoring
59     // If invalid, do nothing.
60     // Recognizes "3a" as a shortcut for enabling tracking 3A state, mode, and
61     // triggers
62     void parseTagsToMonitor(std::string tagNames);
63 
64     // Disable monitoring; does not clear the event log
65     void disableMonitoring();
66 
67     // Scan through the metadata and update the monitoring information
68     void monitorMetadata(eventSource source, int64_t frameNumber,
69             nsecs_t timestamp, const CameraMetadata& metadata,
70             const std::unordered_map<std::string, CameraMetadata>& physicalMetadata,
71             const camera3::camera_stream_buffer_t *outputBuffers = nullptr,
72             uint32_t numOutputBuffers = 0, int32_t inputStreamId = -1);
73 
74     // Dump current event log to the provided fd
75     void dumpMonitoredMetadata(int fd);
76 
77     // Dumps the latest monitored Tag events to the passed vector.
78     // NOTE: The events are appended to the vector in reverser chronological order
79     // (i.e. most recent first)
80     void getLatestMonitoredTagEvents(std::vector<std::string> &out);
81 
82   private:
83     // Dumps monitored tag events to the passed vector without acquiring
84     // mMonitorMutex. mMonitorMutex must be acquired before calling this
85     // function.
86     void dumpMonitoredTagEventsToVectorLocked(std::vector<std::string> &out);
87 
88     static std::string getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type,
89             int count, int indentation);
90 
91     void monitorSingleMetadata(TagMonitor::eventSource source, int64_t frameNumber,
92             nsecs_t timestamp, const std::string& cameraId, uint32_t tag,
93             const CameraMetadata& metadata, const std::unordered_set<int32_t> &outputStreamIds,
94             int32_t inputStreamId);
95 
96     std::atomic<bool> mMonitoringEnabled;
97     std::mutex mMonitorMutex;
98 
99     // Current tags to monitor and record changes to
100     std::vector<uint32_t> mMonitoredTagList;
101 
102     // Latest-seen values of tracked tags
103     CameraMetadata mLastMonitoredRequestValues;
104     CameraMetadata mLastMonitoredResultValues;
105 
106     std::unordered_map<std::string, CameraMetadata> mLastMonitoredPhysicalRequestKeys;
107     std::unordered_map<std::string, CameraMetadata> mLastMonitoredPhysicalResultKeys;
108 
109     int32_t mLastInputStreamId = -1;
110     std::unordered_set<int32_t> mLastStreamIds;
111 
112     /**
113      * A monitoring event
114      * Stores a new metadata field value and the timestamp at which it changed.
115      * Copies the source metadata value array and frees it on destruct.
116      */
117     struct MonitorEvent {
118         template<typename T>
119         MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp,
120                 const T &newValue, const std::string& cameraId,
121                 const std::unordered_set<int32_t> &outputStreamIds, int32_t inputStreamId);
122         ~MonitorEvent();
123 
124         eventSource source;
125         uint32_t frameNumber;
126         nsecs_t timestamp;
127         std::string cameraId;
128         uint32_t tag;
129         uint8_t type;
130         std::vector<uint8_t> newData;
131         // NOTE: We want to print changes to outputStreamIds and inputStreamId in their own lines.
132         // So any MonitorEvent where these fields are not the default value will have garbage
133         // values for all fields other than source, frameNumber, timestamp, and cameraId.
134         std::unordered_set<int32_t> outputStreamIds;
135         int32_t inputStreamId = -1;
136     };
137 
138     // A ring buffer for tracking the last kMaxMonitorEvents metadata changes
139     static const int kMaxMonitorEvents = 100;
140     RingBuffer<MonitorEvent> mMonitoringEvents;
141 
142     // 3A fields to use with the "3a" option
143     static const char *k3aTags;
144     metadata_vendor_id_t mVendorTagId;
145 };
146 
147 } // namespace android
148 
149 #endif
150