Fix behavior of `watch dump`
This CL fixes the behavior of `watch dump` to dump out the tag
monitoring information once and exit, instead of dumping out collected
error traces.
It also reverts the `print` command back to `live` to better reflect
what the command does.
Bug: 199746421
Test: Tested Manually
Change-Id: If4f9886be0b7db50d43499afbd501bc0d26fc1f4
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c721074..32977f7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -4747,12 +4747,12 @@
status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) {
if (args.size() >= 3 && args[1] == String16("start")) {
return startWatchingTags(args, outFd);
- } else if (args.size() == 2 && args[1] == String16("dump")) {
- return camera3::CameraTraces::dump(outFd);
} else if (args.size() == 2 && args[1] == String16("stop")) {
return stopWatchingTags(outFd);
- } else if (args.size() >= 2 && args[1] == String16("print")) {
- return printWatchedTags(args, inFd, outFd);
+ } else if (args.size() == 2 && args[1] == String16("dump")) {
+ return printWatchedTags(outFd);
+ } else if (args.size() >= 2 && args[1] == String16("live")) {
+ return printWatchedTagsUntilInterrupt(args, inFd, outFd);
} else if (args.size() == 2 && args[1] == String16("clear")) {
return clearCachedMonitoredTagDumps(outFd);
}
@@ -4761,9 +4761,9 @@
" starts watching the provided tags for clients with provided package\n"
" recognizes tag shorthands like '3a'\n"
" watches all clients if no client is passed, or if 'all' is listed\n"
- " dump dumps camera trace\n"
+ " dump dumps the monitoring information and exits\n"
" stop stops watching all tags\n"
- " print [-n <refresh_interval_ms>]\n"
+ " live [-n <refresh_interval_ms>]\n"
" prints the monitored information in real time\n"
" Hit return to exit\n"
" clear clears all buffers storing information for watch command");
@@ -4842,59 +4842,65 @@
return OK;
}
-status_t CameraService::printWatchedTags(const Vector<String16> &args, int inFd, int outFd) {
- // Figure outFd refresh interval, if present in args
- long refreshTimeoutMs = 1000L; // refresh every 1s by default
- if (args.size() > 2) {
- size_t intervalIdx; // index of '-n'
- for (intervalIdx = 2; intervalIdx < args.size() && String16("-n") != 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; }
- }
- }
-
- // Set min timeout of 10s. This prevents edge cases in polling when timeout of 0 is passed.
- refreshTimeoutMs = refreshTimeoutMs < 10 ? 10 : refreshTimeoutMs;
-
+status_t CameraService::printWatchedTags(int outFd) {
+ Mutex::Autolock logLock(mLogLock);
std::set<String16> connectedMonitoredClients;
- {
- Mutex::Autolock logLock(mLogLock);
- bool serviceLock = tryLock(mServiceLock);
- // get all watched clients that are currently connected
- for (const auto &clientDescriptor: mActiveClientManager.getAll()) {
- if (clientDescriptor == nullptr) { continue; }
- sp<BasicClient> client = clientDescriptor->getValue();
- if (client.get() == nullptr) { continue; }
- if (!isClientWatchedLocked(client.get())) { continue; }
+ bool printedSomething = false; // tracks if any monitoring information was printed
+ // (from either cached or active clients)
- connectedMonitoredClients.emplace(client->getPackageName());
+ bool serviceLock = tryLock(mServiceLock);
+ // get all watched clients that are currently connected
+ for (const auto &clientDescriptor: mActiveClientManager.getAll()) {
+ if (clientDescriptor == nullptr) { continue; }
+
+ sp<BasicClient> client = clientDescriptor->getValue();
+ if (client.get() == nullptr) { continue; }
+ if (!isClientWatchedLocked(client.get())) { continue; }
+
+ std::vector<std::string> dumpVector;
+ client->dumpWatchedEventsToVector(dumpVector);
+
+ size_t printIdx = dumpVector.size();
+ if (printIdx == 0) {
+ continue;
}
- if (serviceLock) { mServiceLock.unlock(); }
- // Print entries in mWatchedClientsDumpCache for clients that are not connected
- for (const auto &kv: mWatchedClientsDumpCache) {
- const String16 &package = kv.first;
- if (connectedMonitoredClients.find(package) != connectedMonitoredClients.end()) {
- continue;
- }
-
- dprintf(outFd, "Client: %s\n", String8(package).string());
- dprintf(outFd, "%s\n", kv.second.c_str());
+ // Print tag dumps for active client
+ const String8 &cameraId = clientDescriptor->getKey();
+ String8 packageName8 = String8(client->getPackageName());
+ const char *printablePackageName = packageName8.lockBuffer(packageName8.size());
+ dprintf(outFd, "Client: %s (active)\n", printablePackageName);
+ while(printIdx > 0) {
+ printIdx--;
+ dprintf(outFd, "%s:%s %s", cameraId.string(), printablePackageName,
+ dumpVector[printIdx].c_str());
}
+ dprintf(outFd, "\n");
+ packageName8.unlockBuffer();
+ printedSomething = true;
+
+ connectedMonitoredClients.emplace(client->getPackageName());
+ }
+ if (serviceLock) { mServiceLock.unlock(); }
+
+ // Print entries in mWatchedClientsDumpCache for clients that are not connected
+ for (const auto &kv: mWatchedClientsDumpCache) {
+ const String16 &package = kv.first;
+ if (connectedMonitoredClients.find(package) != connectedMonitoredClients.end()) {
+ continue;
+ }
+
+ dprintf(outFd, "Client: %s (cached)\n", String8(package).string());
+ dprintf(outFd, "%s\n", kv.second.c_str());
+ printedSomething = true;
}
- if (connectedMonitoredClients.empty()) {
- dprintf(outFd, "No watched client active.\n");
- return OK;
+ if (!printedSomething) {
+ dprintf(outFd, "No monitoring information to print.\n");
}
- // For connected watched clients, print monitored tags live
- return printWatchedTagsUntilInterrupt(refreshTimeoutMs, inFd, outFd);
+ return OK;
}
// Print all events in vector `events' that came after lastPrintedEvent
@@ -4995,7 +5001,25 @@
}
}
-status_t CameraService::printWatchedTagsUntilInterrupt(long refreshMillis, int inFd, int outFd) {
+status_t CameraService::printWatchedTagsUntilInterrupt(const Vector<String16> &args,
+ int inFd, int outFd) {
+ // Figure out refresh interval, if present in args
+ long refreshTimeoutMs = 1000L; // refresh every 1s by default
+ if (args.size() > 2) {
+ size_t intervalIdx; // index of '-n'
+ for (intervalIdx = 2; intervalIdx < args.size() && String16("-n") != 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; }
+ }
+ }
+
+ // Set min timeout of 10ms. This prevents edge cases in polling when timeout of 0 is passed.
+ refreshTimeoutMs = refreshTimeoutMs < 10 ? 10 : refreshTimeoutMs;
+
dprintf(outFd, "Press return to exit...\n\n");
std::map<String16, std::string> packageNameToLastEvent;
@@ -5031,7 +5055,7 @@
cameraId.unlockBuffer();
}
}
- if (shouldInterruptWatchCommand(inFd, outFd, refreshMillis)) {
+ if (shouldInterruptWatchCommand(inFd, outFd, refreshTimeoutMs)) {
break;
}
}