Statsd sends active config broadcasts
Statsd now sends active configs changed broadcasts when needed per uid.
Also made an adb command to help debug.
More gts tests and unit tests required, will follow.
Test: GTS in topic
Bug: 123372077
Change-Id: Ib079018ded85d002581ffc2ba1240138ce7a54e7
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index bd21a95..b478fed 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -176,6 +176,21 @@
sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
return true;
}
+ },
+ [this](const int& uid, const vector<int64_t>& activeConfigs) {
+ auto receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
+ sp<IStatsCompanionService> sc = getStatsCompanionService();
+ if (sc == nullptr) {
+ VLOG("Could not access statsCompanion");
+ return false;
+ } else if (receiver == nullptr) {
+ VLOG("Could not find receiver for uid %d", uid);
+ return false;
+ } else {
+ sc->sendActiveConfigsChangedBroadcast(receiver, activeConfigs);
+ VLOG("StatsService::active configs broadcast succeeded for uid %d" , uid);
+ return true;
+ }
});
mConfigManager->AddListener(mProcessor);
@@ -357,6 +372,9 @@
if (!args[0].compare(String8("print-logs"))) {
return cmd_print_logs(out, args);
}
+ if (!args[0].compare(String8("send-active-configs"))) {
+ return cmd_trigger_active_config_broadcast(out, args);
+ }
if (!args[0].compare(String8("data-subscribe"))) {
if (mShellSubscriber == nullptr) {
mShellSubscriber = new ShellSubscriber(mUidMap, mPullerManager);
@@ -449,6 +467,19 @@
dprintf(out, " NAME The name of the configuration\n");
dprintf(out, "\n");
dprintf(out, "\n");
+ dprintf(out,
+ "usage: adb shell cmd stats send-active-configs [--uid=UID] [--configs] "
+ "[NAME1] [NAME2] [NAME3..]\n");
+ dprintf(out, " Send a broadcast that informs the subscriber of the current active configs.\n");
+ dprintf(out, " --uid=UID The uid of the configurations. It is only possible to pass\n");
+ dprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
+ dprintf(out, " calling uid is used.\n");
+ dprintf(out, " --configs Send the list of configs in the name list instead of\n");
+ dprintf(out, " the currently active configs\n");
+ dprintf(out, " NAME LIST List of configuration names to be included in the broadcast.\n");
+
+ dprintf(out, "\n");
+ dprintf(out, "\n");
dprintf(out, "usage: adb shell cmd stats print-stats\n");
dprintf(out, " Prints some basic stats.\n");
dprintf(out, " --proto Print proto binary instead of string format.\n");
@@ -499,6 +530,59 @@
return NO_ERROR;
}
+status_t StatsService::cmd_trigger_active_config_broadcast(int out, Vector<String8>& args) {
+ const int argCount = args.size();
+ int uid;
+ vector<int64_t> configIds;
+ if (argCount == 1) {
+ // Automatically pick the uid and send a broadcast that has no active configs.
+ uid = IPCThreadState::self()->getCallingUid();
+ mProcessor->GetActiveConfigs(uid, configIds);
+ } else {
+ int curArg = 1;
+ if(args[curArg].find("--uid=") == 0) {
+ string uidArgStr(args[curArg].c_str());
+ string uidStr = uidArgStr.substr(6);
+ if (!getUidFromString(uidStr.c_str(), uid)) {
+ dprintf(out, "Invalid UID. Note that the config can only be set for "
+ "other UIDs on eng or userdebug builds.\n");
+ return UNKNOWN_ERROR;
+ }
+ curArg++;
+ } else {
+ uid = IPCThreadState::self()->getCallingUid();
+ }
+ if (curArg == argCount || args[curArg] != "--configs") {
+ VLOG("Reached end of args, or specify configs not set. Sending actual active configs,");
+ mProcessor->GetActiveConfigs(uid, configIds);
+ } else {
+ // Flag specified, use the given list of configs.
+ curArg++;
+ for (int i = curArg; i < argCount; i++) {
+ char* endp;
+ int64_t configID = strtoll(args[i].c_str(), &endp, 10);
+ if (endp == args[i].c_str() || *endp != '\0') {
+ dprintf(out, "Error parsing config ID.\n");
+ return UNKNOWN_ERROR;
+ }
+ VLOG("Adding config id %ld", static_cast<long>(configID));
+ configIds.push_back(configID);
+ }
+ }
+ }
+ auto receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
+ sp<IStatsCompanionService> sc = getStatsCompanionService();
+ if (sc == nullptr) {
+ VLOG("Could not access statsCompanion");
+ } else if (receiver == nullptr) {
+ VLOG("Could not find receiver for uid %d", uid);
+ } else {
+ sc->sendActiveConfigsChangedBroadcast(receiver, configIds);
+ VLOG("StatsService::trigger active configs changed broadcast succeeded for uid %d" , uid);
+ }
+ return NO_ERROR;
+}
+
status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& args) {
const int argCount = args.size();
if (argCount >= 2) {
@@ -762,7 +846,10 @@
}
bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) {
- const char* s = args[uidArgIndex].c_str();
+ return getUidFromString(args[uidArgIndex].c_str(), uid);
+}
+
+bool StatsService::getUidFromString(const char* s, int32_t& uid) {
if (*s == '\0') {
return false;
}
@@ -998,8 +1085,13 @@
ENFORCE_DUMP_AND_USAGE_STATS(packageName);
IPCThreadState* ipc = IPCThreadState::self();
- mConfigManager->SetActiveConfigsChangedReceiver(ipc->getCallingUid(), intentSender);
- //TODO: Return the list of configs that are already active
+ int uid = ipc->getCallingUid();
+ mConfigManager->SetActiveConfigsChangedReceiver(uid, intentSender);
+ if (output != nullptr) {
+ mProcessor->GetActiveConfigs(uid, *output);
+ } else {
+ ALOGW("StatsService::setActiveConfigsChanged output was nullptr");
+ }
return Status::ok();
}