Add 'watch' command to CameraService
Currently there is no way to monitor tags and dump per frame data from
Camera devices without calling dumpsys, which in turn dumps a lot of
unnecessary information.
This CL adds a 'watch' command to CameraService which can be called
through `cmd`. 'watch' provides a path to manage tag monitoring without
dumpsys. 'watch' currently has four functions:
1. start <taglist>: starts mornitoring the provided tags in attached
devices.
2. stop: stop monitoring all tags
3. live: prints monitored information to the terminal live
4. dump: dumps any collected camera traces
This CL adds a function to camera device each for the three tag
monitoring function listed above.
Test: n/a
Bug: 199746421
Change-Id: Ia5ce13f6e50c82085afcc676309cdbffef915a41
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 49d5cd8..88c0bb5 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -3115,6 +3115,21 @@
return OK;
}
+status_t CameraService::BasicClient::startWatchingTags(const String8&, int) {
+ // Can't watch tags directly, must go through CameraService::startWatchingTags
+ return OK;
+}
+
+status_t CameraService::BasicClient::stopWatchingTags(int) {
+ // Can't watch tags directly, must go through CameraService::stopWatchingTags
+ return OK;
+}
+
+status_t CameraService::BasicClient::dumpWatchedEventsToVector(std::vector<std::string> &) {
+ // Can't watch tags directly, must go through CameraService::dumpWatchedEventsToVector
+ return OK;
+}
+
String16 CameraService::BasicClient::getPackageName() const {
return mClientPackageName;
}
@@ -4136,7 +4151,7 @@
// Dump camera traces if there were any
dprintf(fd, "\n");
- camera3::CameraTraces::dump(fd, args);
+ camera3::CameraTraces::dump(fd);
// Process dump arguments, if any
int n = args.size();
@@ -4534,9 +4549,11 @@
return handleGetImageDumpMask(out);
} else if (args.size() >= 2 && args[0] == String16("set-camera-mute")) {
return handleSetCameraMute(args);
+ } else if (args.size() >= 2 && args[0] == String16("watch")) {
+ return handleWatchCommand(args, out);
} else if (args.size() == 1 && args[0] == String16("help")) {
printHelp(out);
- return NO_ERROR;
+ return OK;
}
printHelp(err);
return BAD_VALUE;
@@ -4680,6 +4697,134 @@
return OK;
}
+status_t CameraService::handleWatchCommand(const Vector<String16>& args, int out) {
+ if (args.size() == 3 && args[1] == String16("start")) {
+ return startWatchingTags(args[2], out);
+ } else if (args.size() == 2 && args[1] == String16("dump")) {
+ return camera3::CameraTraces::dump(out);
+ } else if (args.size() == 2 && args[1] == String16("stop")) {
+ return stopWatchingTags(out);
+ } else if (args.size() >= 2 && args[1] == String16("live")) {
+ return printWatchedTagsUntilInterrupt(args, out);
+ }
+ dprintf(out, "Camera service watch commands:\n"
+ " start <comma_separated_tag_list> starts watching the provided tags\n"
+ " recognizes shorthands like '3a'\n"
+ " dump dumps camera trace\n"
+ " stop stops watching all tags\n"
+ " live prints the monitored information in real time\n"
+ " Hit Ctrl+C to stop.\n");
+ return BAD_VALUE;
+}
+
+status_t CameraService::startWatchingTags(const String16 &tags, int outFd) {
+ // track tags to initialize future clients with the monitoring information
+ mMonitorTags = String8(tags);
+
+ auto cameraClients = mActiveClientManager.getAll();
+ for (const auto &clientDescriptor: cameraClients) {
+ if (clientDescriptor == nullptr) { continue; }
+ sp<BasicClient> client = clientDescriptor->getValue();
+ if (client.get() == nullptr) { continue; }
+ client->startWatchingTags(mMonitorTags, outFd);
+ }
+ return OK;
+}
+
+status_t CameraService::stopWatchingTags(int outFd) {
+ // clear mMonitorTags to prevent new clients from monitoring tags at initialization
+ mMonitorTags = String8::empty();
+
+ auto cameraClients = mActiveClientManager.getAll();
+ for (const auto &clientDescriptor : cameraClients) {
+ if (clientDescriptor == nullptr) { continue; }
+ sp<BasicClient> client = clientDescriptor->getValue();
+ if (client.get() == nullptr) { continue; }
+ client->stopWatchingTags(outFd);
+ }
+ return OK;
+}
+
+status_t CameraService::printWatchedTagsUntilInterrupt(const Vector<String16> &args, int outFd) {
+ useconds_t refreshTimeoutMs = 1000; // refresh every 1s by default
+
+ if (args.size() > 2) {
+ size_t intervalIdx; // index of refresh interval argument
+ for (intervalIdx = 2;
+ intervalIdx < args.size()
+ && String16("-n") != args[intervalIdx]
+ && String16("--interval") != args[intervalIdx];
+ intervalIdx++);
+
+ size_t intervalValIdx = intervalIdx + 1;
+ if (intervalValIdx < args.size()) {
+ refreshTimeoutMs = strtol(String8(args[intervalValIdx].string()), nullptr, 10);
+ if (errno) { return BAD_VALUE; }
+ }
+ }
+
+ std::unordered_map<std::string, std::string> cameraToLastEvent;
+ auto cameraClients = mActiveClientManager.getAll();
+
+ if (cameraClients.empty()) {
+ dprintf(outFd, "No clients connected.\n");
+ return OK;
+ }
+
+ dprintf(outFd, "Press Ctrl + C to exit...\n\n");
+ while (true) {
+ for (const auto& clientDescriptor : cameraClients) {
+ if (clientDescriptor == nullptr) { continue; }
+ const char* cameraId = clientDescriptor->getKey().string();
+
+ // This also initializes the map entries with an empty string
+ const std::string& lastPrintedEvent = cameraToLastEvent[cameraId];
+
+ sp<BasicClient> client = clientDescriptor->getValue();
+ if (client.get() == nullptr) { continue; }
+
+ std::vector<std::string> latestEvents;
+ client->dumpWatchedEventsToVector(latestEvents);
+
+ if (!latestEvents.empty()) {
+ printNewWatchedEvents(outFd,
+ cameraId,
+ client->getPackageName(),
+ latestEvents,
+ lastPrintedEvent);
+ cameraToLastEvent[cameraId] = latestEvents[0];
+ }
+ }
+ usleep(refreshTimeoutMs * 1000); // convert ms to us
+ }
+ return OK;
+}
+
+void CameraService::printNewWatchedEvents(int outFd,
+ const char *cameraId,
+ const String16 &packageName,
+ const std::vector<std::string> &events,
+ const std::string &lastPrintedEvent) {
+ if (events.empty()) { return; }
+
+ // index of lastPrintedEvent in events.
+ // lastPrintedIdx = events.size() if lastPrintedEvent is not in events
+ size_t lastPrintedIdx;
+ for (lastPrintedIdx = 0;
+ lastPrintedIdx < events.size() && lastPrintedEvent != events[lastPrintedIdx];
+ lastPrintedIdx++);
+
+ if (lastPrintedIdx == 0) { return; } // early exit if no new event in `events`
+
+ const char *printPackageName = String8(packageName).string();
+ // print events in chronological order (latest event last)
+ size_t idxToPrint = lastPrintedIdx;
+ do {
+ idxToPrint--;
+ dprintf(outFd, "%s:%s %s", cameraId, printPackageName, events[idxToPrint].c_str());
+ } while (idxToPrint != 0);
+}
+
status_t CameraService::printHelp(int out) {
return dprintf(out, "Camera service commands:\n"
" get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
@@ -4692,6 +4837,7 @@
" Valid values 0=OFF, 1=ON for JPEG\n"
" get-image-dump-mask returns the current image-dump-mask value\n"
" set-camera-mute <0/1> enable or disable camera muting\n"
+ " watch <start|stop|dump|live> manages tag monitoring in connected clients\n"
" help print this message\n");
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 7a69123..f701d30 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -272,6 +272,10 @@
// Internal dump method to be called by CameraService
virtual status_t dumpClient(int fd, const Vector<String16>& args) = 0;
+ virtual status_t startWatchingTags(const String8 &tags, int outFd);
+ virtual status_t stopWatchingTags(int outFd);
+ virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
+
// Return the package name for this client
virtual String16 getPackageName() const;
@@ -1149,6 +1153,26 @@
// Set the camera mute state
status_t handleSetCameraMute(const Vector<String16>& args);
+ // Handle 'watch' command as passed through 'cmd'
+ status_t handleWatchCommand(const Vector<String16> &args, int out);
+
+ // Enable tag monitoring of the given tags in all attached clients
+ status_t startWatchingTags(const String16 &tags, int outFd);
+
+ // Disable tag monitoring in all attached clients
+ status_t stopWatchingTags(int outFd);
+
+ // Print events of monitored tags in all attached devices as they are captured
+ // NOTE: This function does not terminate unless interrupted.
+ status_t printWatchedTagsUntilInterrupt(const Vector<String16> &args, int outFd);
+
+ // Print all events in vector `events' that came after lastPrintedEvent
+ static void printNewWatchedEvents(int outFd,
+ const char *cameraId,
+ const String16 &packageName,
+ const std::vector<std::string> &events,
+ const std::string &lastPrintedEvent);
+
// Prints the shell command help
status_t printHelp(int out);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1f3d478..67ec150 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1797,6 +1797,35 @@
return dumpDevice(fd, args);
}
+status_t CameraDeviceClient::startWatchingTags(const String8 &tags, int out) {
+ sp<CameraDeviceBase> device = mDevice;
+ if (!device) {
+ dprintf(out, " Device is detached.");
+ return OK;
+ }
+ device->startWatchingTags(tags);
+ return OK;
+}
+
+status_t CameraDeviceClient::stopWatchingTags(int out) {
+ sp<CameraDeviceBase> device = mDevice;
+ if (!device) {
+ dprintf(out, " Device is detached.");
+ return OK;
+ }
+ device->stopWatchingTags();
+ return OK;
+}
+
+status_t CameraDeviceClient::dumpWatchedEventsToVector(std::vector<std::string> &out) {
+ sp<CameraDeviceBase> device = mDevice;
+ if (!device) {
+ return OK;
+ }
+ device->dumpWatchedEventsToVector(out);
+ return OK;
+}
+
void CameraDeviceClient::notifyError(int32_t errorCode,
const CaptureResultExtras& resultExtras) {
// Thread safe. Don't bother locking.
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 76b3f53..288f2d7 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -199,6 +199,10 @@
virtual status_t dumpClient(int fd, const Vector<String16>& args);
+ virtual status_t startWatchingTags(const String8 &tags, int out);
+ virtual status_t stopWatchingTags(int out);
+ virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
+
/**
* Device listener interface
*/
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 652842b..10fa33f 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -110,6 +110,18 @@
return OK;
}
+status_t CameraOfflineSessionClient::startWatchingTags(const String8 &tags, int outFd) {
+ return BasicClient::startWatchingTags(tags, outFd);
+}
+
+status_t CameraOfflineSessionClient::stopWatchingTags(int outFd) {
+ return BasicClient::stopWatchingTags(outFd);
+}
+
+status_t CameraOfflineSessionClient::dumpWatchedEventsToVector(std::vector<std::string> &out) {
+ return BasicClient::dumpWatchedEventsToVector(out);
+}
+
binder::Status CameraOfflineSessionClient::disconnect() {
Mutex::Autolock icl(mBinderSerializationLock);
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index b5238b8..920a176 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -71,6 +71,10 @@
status_t dumpClient(int /*fd*/, const Vector<String16>& /*args*/) override;
+ status_t startWatchingTags(const String8 &tags, int outFd) override;
+ status_t stopWatchingTags(int outFd) override;
+ status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
+
status_t initialize(sp<CameraProviderManager> /*manager*/,
const String8& /*monitorTags*/) override;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 1147e23..0283d01 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -155,6 +155,38 @@
}
template <typename TClientBase>
+status_t Camera2ClientBase<TClientBase>::startWatchingTags(const String8 &tags, int out) {
+ sp<CameraDeviceBase> device = mDevice;
+ if (!device) {
+ dprintf(out, " Device is detached");
+ return OK;
+ }
+
+ return device->startWatchingTags(tags);
+}
+
+template <typename TClientBase>
+status_t Camera2ClientBase<TClientBase>::stopWatchingTags(int out) {
+ sp<CameraDeviceBase> device = mDevice;
+ if (!device) {
+ dprintf(out, " Device is detached");
+ return OK;
+ }
+
+ return device->stopWatchingTags();
+}
+
+template <typename TClientBase>
+status_t Camera2ClientBase<TClientBase>::dumpWatchedEventsToVector(std::vector<std::string> &out) {
+ sp<CameraDeviceBase> device = mDevice;
+ if (!device) {
+ // Nothing to dump if the device is detached
+ return OK;
+ }
+ return device->dumpWatchedEventsToVector(out);
+}
+
+template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::dumpDevice(
int fd,
const Vector<String16>& args) {
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index b593bfa..ba6a230 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -61,6 +61,9 @@
virtual status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags);
virtual status_t dumpClient(int fd, const Vector<String16>& args);
+ virtual status_t startWatchingTags(const String8 &tags, int out);
+ virtual status_t stopWatchingTags(int out);
+ virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
/**
* NotificationListener implementation
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 3c95ed3..8168821 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -97,6 +97,9 @@
virtual status_t disconnect() = 0;
virtual status_t dump(int fd, const Vector<String16> &args) = 0;
+ virtual status_t startWatchingTags(const String8 &tags) = 0;
+ virtual status_t stopWatchingTags() = 0;
+ virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out) = 0;
/**
* The physical camera device's static characteristics metadata buffer
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 67f99bf..8925b15 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -848,6 +848,21 @@
return OK;
}
+status_t Camera3Device::startWatchingTags(const String8 &tags) {
+ mTagMonitor.parseTagsToMonitor(tags);
+ return OK;
+}
+
+status_t Camera3Device::stopWatchingTags() {
+ mTagMonitor.disableMonitoring();
+ return OK;
+}
+
+status_t Camera3Device::dumpWatchedEventsToVector(std::vector<std::string> &out) {
+ mTagMonitor.getLatestMonitoredTagEvents(out);
+ return OK;
+}
+
const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
ALOGVV("%s: E", __FUNCTION__);
if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 4ffdc5f..f2394ad 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -106,6 +106,9 @@
status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) override;
status_t disconnect() override;
status_t dump(int fd, const Vector<String16> &args) override;
+ status_t startWatchingTags(const String8 &tags) override;
+ status_t stopWatchingTags() override;
+ status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
const CameraMetadata& info() const override;
const CameraMetadata& infoPhysical(const String8& physicalId) const override;
diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp
index 0198690..0cd4f5d 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.cpp
+++ b/services/camera/libcameraservice/utils/CameraTraces.cpp
@@ -64,7 +64,7 @@
ATRACE_END();
}
-status_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((unused))) {
+status_t CameraTraces::dump(int fd) {
ALOGV("%s: fd = %d", __FUNCTION__, fd);
Mutex::Autolock al(sImpl.tracesLock);
List<ProcessCallStack>& pcsList = sImpl.pcsList;
diff --git a/services/camera/libcameraservice/utils/CameraTraces.h b/services/camera/libcameraservice/utils/CameraTraces.h
index 13ca16d..71fa334 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.h
+++ b/services/camera/libcameraservice/utils/CameraTraces.h
@@ -42,7 +42,7 @@
*
* <p>Each line is indented by DUMP_INDENT spaces.</p>
*/
- static status_t dump(int fd, const Vector<String16>& args);
+ static status_t dump(int fd);
private:
enum {
diff --git a/services/camera/libcameraservice/utils/TagMonitor.cpp b/services/camera/libcameraservice/utils/TagMonitor.cpp
index 4488098..461f5e9 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.cpp
+++ b/services/camera/libcameraservice/utils/TagMonitor.cpp
@@ -239,38 +239,59 @@
} else {
dprintf(fd, " Tag monitoring disabled (enable with -m <name1,..,nameN>)\n");
}
- if (mMonitoringEvents.size() > 0) {
- dprintf(fd, " Monitored tag event log:\n");
- for (const auto& event : mMonitoringEvents) {
- int indentation = (event.source == REQUEST) ? 15 : 30;
- dprintf(fd, " f%d:%" PRId64 "ns:%*s%*s%s.%s: ",
- event.frameNumber, event.timestamp,
- 2, event.cameraId.c_str(),
- indentation,
- event.source == REQUEST ? "REQ:" : "RES:",
- get_local_camera_metadata_section_name_vendor_id(event.tag,
- mVendorTagId),
- get_local_camera_metadata_tag_name_vendor_id(event.tag,
- mVendorTagId));
- if (event.newData.size() == 0) {
- dprintf(fd, " (Removed)\n");
- } else {
- printData(fd, event.newData.data(), event.tag,
- event.type, event.newData.size() / camera_metadata_type_size[event.type],
- indentation + 18, event.outputStreamIds, event.inputStreamId);
- }
- }
- }
+ if (mMonitoringEvents.size() == 0) { return; }
+
+ dprintf(fd, " Monitored tag event log:\n");
+
+ std::vector<std::string> eventStrs;
+ dumpMonitoredTagEventsToVectorLocked(eventStrs);
+ for (const std::string &eventStr : eventStrs) {
+ dprintf(fd, " %s", eventStr.c_str());
+ }
}
-// TODO: Consolidate with printData from camera_metadata.h
+void TagMonitor::getLatestMonitoredTagEvents(std::vector<std::string> &out) {
+ std::lock_guard<std::mutex> lock(mMonitorMutex);
+ dumpMonitoredTagEventsToVectorLocked(out);
+}
+
+void TagMonitor::dumpMonitoredTagEventsToVectorLocked(std::vector<std::string> &vec) {
+ if (mMonitoringEvents.size() == 0) { return; }
+
+ for (const auto& event : mMonitoringEvents) {
+ int indentation = (event.source == REQUEST) ? 15 : 30;
+ String8 eventString = String8::format("f%d:%" PRId64 "ns:%*s%*s%s.%s: ",
+ event.frameNumber, event.timestamp,
+ 2, event.cameraId.c_str(),
+ indentation,
+ event.source == REQUEST ? "REQ:" : "RES:",
+ get_local_camera_metadata_section_name_vendor_id(event.tag, mVendorTagId),
+ get_local_camera_metadata_tag_name_vendor_id(event.tag, mVendorTagId));
+ if (event.newData.size() == 0) {
+ eventString += " (Removed)";
+ } else {
+ eventString += getEventDataString(event.newData.data(),
+ event.tag,
+ event.type,
+ event.newData.size() / camera_metadata_type_size[event.type],
+ indentation + 18,
+ event.outputStreamIds,
+ event.inputStreamId);
+ }
+ vec.emplace_back(eventString.string());
+ }
+}
#define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29
-void TagMonitor::printData(int fd, const uint8_t *data_ptr, uint32_t tag,
- int type, int count, int indentation, const std::unordered_set<int32_t> &outputStreamIds,
- int32_t inputStreamId) {
+String8 TagMonitor::getEventDataString(const uint8_t* data_ptr,
+ uint32_t tag,
+ int type,
+ int count,
+ int indentation,
+ const std::unordered_set<int32_t>& outputStreamIds,
+ int32_t inputStreamId) {
static int values_per_line[NUM_TYPES] = {
[TYPE_BYTE] = 16,
[TYPE_INT32] = 8,
@@ -279,6 +300,7 @@
[TYPE_DOUBLE] = 4,
[TYPE_RATIONAL] = 4,
};
+
size_t type_size = camera_metadata_type_size[type];
char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];
uint32_t value;
@@ -286,10 +308,11 @@
int lines = count / values_per_line[type];
if (count % values_per_line[type] != 0) lines++;
+ String8 returnStr = String8();
int index = 0;
int j, k;
for (j = 0; j < lines; j++) {
- dprintf(fd, "%*s[", (j != 0) ? indentation + 4 : 0, "");
+ returnStr.appendFormat("%*s[", (j != 0) ? indentation + 4 : 0, "");
for (k = 0;
k < values_per_line[type] && count > 0;
k++, count--, index += type_size) {
@@ -302,10 +325,9 @@
value_string_tmp,
sizeof(value_string_tmp))
== OK) {
- dprintf(fd, "%s ", value_string_tmp);
+ returnStr += value_string_tmp;
} else {
- dprintf(fd, "%hhu ",
- *(data_ptr + index));
+ returnStr.appendFormat("%hhu", *(data_ptr + index));
}
break;
case TYPE_INT32:
@@ -316,47 +338,43 @@
value_string_tmp,
sizeof(value_string_tmp))
== OK) {
- dprintf(fd, "%s ", value_string_tmp);
+ returnStr += value_string_tmp;
} else {
- dprintf(fd, "%" PRId32 " ",
- *(int32_t*)(data_ptr + index));
+ returnStr.appendFormat("%" PRId32 " ", *(int32_t*)(data_ptr + index));
}
break;
case TYPE_FLOAT:
- dprintf(fd, "%0.8f ",
- *(float*)(data_ptr + index));
+ returnStr.appendFormat("%0.8f", *(float*)(data_ptr + index));
break;
case TYPE_INT64:
- dprintf(fd, "%" PRId64 " ",
- *(int64_t*)(data_ptr + index));
+ returnStr.appendFormat("%" PRId64 " ", *(int64_t*)(data_ptr + index));
break;
case TYPE_DOUBLE:
- dprintf(fd, "%0.8f ",
- *(double*)(data_ptr + index));
+ returnStr.appendFormat("%0.8f ", *(double*)(data_ptr + index));
break;
case TYPE_RATIONAL: {
int32_t numerator = *(int32_t*)(data_ptr + index);
int32_t denominator = *(int32_t*)(data_ptr + index + 4);
- dprintf(fd, "(%d / %d) ",
- numerator, denominator);
+ returnStr.appendFormat("(%d / %d) ", numerator, denominator);
break;
}
default:
- dprintf(fd, "??? ");
+ returnStr += "??? ";
}
}
- dprintf(fd, "] ");
- if (outputStreamIds.size() > 0) {
- dprintf(fd, "output stream ids: ");
+ returnStr += "] ";
+ if (!outputStreamIds.empty()) {
+ returnStr += "output stream ids: ";
for (const auto &id : outputStreamIds) {
- dprintf(fd, " %d ", id);
+ returnStr.appendFormat(" %d ", id);
}
}
if (inputStreamId != -1) {
- dprintf(fd, "input stream id: %d", inputStreamId);
+ returnStr.appendFormat("input stream id: %d", inputStreamId);
}
- dprintf(fd, "\n");
+ returnStr += "\n";
}
+ return returnStr;
}
template<typename T>
diff --git a/services/camera/libcameraservice/utils/TagMonitor.h b/services/camera/libcameraservice/utils/TagMonitor.h
index f6df4b7..088d6fe 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.h
+++ b/services/camera/libcameraservice/utils/TagMonitor.h
@@ -74,11 +74,23 @@
// Dump current event log to the provided fd
void dumpMonitoredMetadata(int fd);
- private:
+ // Dumps the latest monitored Tag events to the passed vector.
+ // NOTE: The events are appended to the vector in reverser chronological order
+ // (i.e. most recent first)
+ void getLatestMonitoredTagEvents(std::vector<std::string> &out);
- static void printData(int fd, const uint8_t *data_ptr, uint32_t tag,
- int type, int count, int indentation,
- const std::unordered_set<int32_t> &outputStreamIds, int32_t inputStreamId);
+ private:
+ // Dumps monitored tag events to the passed vector without acquiring
+ // mMonitorMutex. mMonitorMutex must be acquired before calling this
+ // function.
+ void dumpMonitoredTagEventsToVectorLocked(std::vector<std::string> &out);
+
+ static String8 getEventDataString(const uint8_t *data_ptr,
+ uint32_t tag, int type,
+ int count,
+ int indentation,
+ const std::unordered_set<int32_t> &outputStreamIds,
+ int32_t inputStreamId);
void monitorSingleMetadata(TagMonitor::eventSource source, int64_t frameNumber,
nsecs_t timestamp, const std::string& cameraId, uint32_t tag,