1 /*
2  * Copyright (C) 2017 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 DEBUG false  // STOPSHIP if true
18 #include "Log.h"
19 
20 #include "StatsService.h"
21 #include "stats_log_util.h"
22 #include "android-base/stringprintf.h"
23 #include "config/ConfigKey.h"
24 #include "config/ConfigManager.h"
25 #include "guardrail/StatsdStats.h"
26 #include "storage/StorageManager.h"
27 #include "subscriber/SubscriberReporter.h"
28 
29 #include <android-base/file.h>
30 #include <android-base/strings.h>
31 #include <cutils/multiuser.h>
32 #include <src/statsd_config.pb.h>
33 #include <src/uid_data.pb.h>
34 #include <private/android_filesystem_config.h>
35 #include <statslog_statsd.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <sys/system_properties.h>
39 #include <unistd.h>
40 #include <utils/String16.h>
41 
42 using namespace android;
43 
44 using android::base::StringPrintf;
45 using android::util::FIELD_COUNT_REPEATED;
46 using android::util::FIELD_TYPE_MESSAGE;
47 
48 using Status = ::ndk::ScopedAStatus;
49 
50 namespace android {
51 namespace os {
52 namespace statsd {
53 
54 constexpr const char* kPermissionDump = "android.permission.DUMP";
55 
56 constexpr const char* kPermissionRegisterPullAtom = "android.permission.REGISTER_STATS_PULL_ATOM";
57 
58 #define STATS_SERVICE_DIR "/data/misc/stats-service"
59 
60 // for StatsDataDumpProto
61 const int FIELD_ID_REPORTS_LIST = 1;
62 
63 static Status exception(int32_t code, const std::string& msg) {
64     ALOGE("%s (%d)", msg.c_str(), code);
65     return Status::fromExceptionCodeWithMessage(code, msg.c_str());
66 }
67 
68 static bool checkPermission(const char* permission) {
69     pid_t pid = AIBinder_getCallingPid();
70     uid_t uid = AIBinder_getCallingUid();
71     return checkPermissionForIds(permission, pid, uid);
72 }
73 
74 Status checkUid(uid_t expectedUid) {
75     uid_t uid = AIBinder_getCallingUid();
76     if (uid == expectedUid || uid == AID_ROOT) {
77         return Status::ok();
78     } else {
79         return exception(EX_SECURITY,
80                          StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
81     }
82 }
83 
84 #define ENFORCE_UID(uid) {                                        \
85     Status status = checkUid((uid));                              \
86     if (!status.isOk()) {                                         \
87         return status;                                            \
88     }                                                             \
89 }
90 
91 StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
92     : mAnomalyAlarmMonitor(new AlarmMonitor(
93               MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
94               [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) {
95                   mProcessor->setAnomalyAlarm(timeMillis);
96                   StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
97               },
98               [this](const shared_ptr<IStatsCompanionService>& /*sc*/) {
99                   mProcessor->cancelAnomalyAlarm();
100                   StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
101               })),
102       mPeriodicAlarmMonitor(new AlarmMonitor(
103               MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
104               [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
105                   if (sc != nullptr) {
106                       sc->setAlarmForSubscriberTriggering(timeMillis);
107                       StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
108                   }
109               },
110               [](const shared_ptr<IStatsCompanionService>& sc) {
111                   if (sc != nullptr) {
112                       sc->cancelAlarmForSubscriberTriggering();
113                       StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
114                   }
115               })),
116       mEventQueue(queue),
117       mBootCompleteTrigger({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag},
118                            [this]() { mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); }),
119       mStatsCompanionServiceDeathRecipient(
120               AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) {
121     mUidMap = UidMap::getInstance();
122     mPullerManager = new StatsPullerManager();
123     StatsPuller::SetUidMap(mUidMap);
124     mConfigManager = new ConfigManager();
125     mProcessor = new StatsLogProcessor(
126             mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
127             getElapsedRealtimeNs(),
128             [this](const ConfigKey& key) {
129                 shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
130                 if (receiver == nullptr) {
131                     VLOG("Could not find a broadcast receiver for %s", key.ToString().c_str());
132                     return false;
133                 } else if (receiver->sendDataBroadcast(
134                            mProcessor->getLastReportTimeNs(key)).isOk()) {
135                     return true;
136                 } else {
137                     VLOG("Failed to send a broadcast for receiver %s", key.ToString().c_str());
138                     return false;
139                 }
140             },
141             [this](const int& uid, const vector<int64_t>& activeConfigs) {
142                 shared_ptr<IPendingIntentRef> receiver =
143                     mConfigManager->GetActiveConfigsChangedReceiver(uid);
144                 if (receiver == nullptr) {
145                     VLOG("Could not find receiver for uid %d", uid);
146                     return false;
147                 } else if (receiver->sendActiveConfigsChangedBroadcast(activeConfigs).isOk()) {
148                     VLOG("StatsService::active configs broadcast succeeded for uid %d" , uid);
149                     return true;
150                 } else {
151                     VLOG("StatsService::active configs broadcast failed for uid %d" , uid);
152                     return false;
153                 }
154             });
155 
156     mUidMap->setListener(mProcessor);
157     mConfigManager->AddListener(mProcessor);
158 
159     init_system_properties();
160 
161     if (mEventQueue != nullptr) {
162         std::thread pushedEventThread([this] { readLogs(); });
163         pushedEventThread.detach();
164     }
165 }
166 
167 StatsService::~StatsService() {
168 }
169 
170 /* Runs on a dedicated thread to process pushed events. */
171 void StatsService::readLogs() {
172     // Read forever..... long live statsd
173     while (1) {
174         // Block until an event is available.
175         auto event = mEventQueue->waitPop();
176         // Pass it to StatsLogProcess to all configs/metrics
177         // At this point, the LogEventQueue is not blocked, so that the socketListener
178         // can read events from the socket and write to buffer to avoid data drop.
179         mProcessor->OnLogEvent(event.get());
180         // The ShellSubscriber is only used by shell for local debugging.
181         if (mShellSubscriber != nullptr) {
182             mShellSubscriber->onLogEvent(*event);
183         }
184     }
185 }
186 
187 void StatsService::init_system_properties() {
188     mEngBuild = false;
189     const prop_info* buildType = __system_property_find("ro.build.type");
190     if (buildType != NULL) {
191         __system_property_read_callback(buildType, init_build_type_callback, this);
192     }
193 }
194 
195 void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
196                                             uint32_t serial) {
197     if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
198         reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
199     }
200 }
201 
202 /**
203  * Write data from statsd.
204  * Format for statsdStats:  adb shell dumpsys stats --metadata [-v] [--proto]
205  * Format for data report:  adb shell dumpsys stats [anything other than --metadata] [--proto]
206  * Anything ending in --proto will be in proto format.
207  * Anything without --metadata as the first argument will be report information.
208  *     (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
209  * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
210  */
211 status_t StatsService::dump(int fd, const char** args, uint32_t numArgs) {
212     if (!checkPermission(kPermissionDump)) {
213         return PERMISSION_DENIED;
214     }
215 
216     int lastArg = numArgs - 1;
217     bool asProto = false;
218     if (lastArg >= 0 && string(args[lastArg]) == "--proto") { // last argument
219         asProto = true;
220         lastArg--;
221     }
222     if (numArgs > 0 && string(args[0]) == "--metadata") { // first argument
223         // Request is to dump statsd stats.
224         bool verbose = false;
225         if (lastArg >= 0 && string(args[lastArg]) == "-v") {
226             verbose = true;
227             lastArg--;
228         }
229         dumpStatsdStats(fd, verbose, asProto);
230     } else {
231         // Request is to dump statsd report data.
232         if (asProto) {
233             dumpIncidentSection(fd);
234         } else {
235             dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n");
236         }
237     }
238 
239     return NO_ERROR;
240 }
241 
242 /**
243  * Write debugging data about statsd in text or proto format.
244  */
245 void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) {
246     if (proto) {
247         vector<uint8_t> data;
248         StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
249         for (size_t i = 0; i < data.size(); i ++) {
250             dprintf(out, "%c", data[i]);
251         }
252     } else {
253         StatsdStats::getInstance().dumpStats(out);
254         mProcessor->dumpStates(out, verbose);
255     }
256 }
257 
258 /**
259  * Write stats report data in StatsDataDumpProto incident section format.
260  */
261 void StatsService::dumpIncidentSection(int out) {
262     ProtoOutputStream proto;
263     for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) {
264         uint64_t reportsListToken =
265                 proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST);
266         // Don't include the current bucket to avoid skipping buckets.
267         // If we need to include the current bucket later, consider changing to NO_TIME_CONSTRAINTS
268         // or other alternatives to avoid skipping buckets for pulled metrics.
269         mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
270                                  false /* includeCurrentBucket */, false /* erase_data */,
271                                  ADB_DUMP,
272                                  FAST,
273                                  &proto);
274         proto.end(reportsListToken);
275         proto.flush(out);
276         proto.clear();
277     }
278 }
279 
280 /**
281  * Implementation of the adb shell cmd stats command.
282  */
283 status_t StatsService::handleShellCommand(int in, int out, int err, const char** argv,
284                                           uint32_t argc) {
285     uid_t uid = AIBinder_getCallingUid();
286     if (uid != AID_ROOT && uid != AID_SHELL) {
287         return PERMISSION_DENIED;
288     }
289 
290     Vector<String8> utf8Args;
291     utf8Args.setCapacity(argc);
292     for (uint32_t i = 0; i < argc; i++) {
293         utf8Args.push(String8(argv[i]));
294     }
295 
296     if (argc >= 1) {
297         // adb shell cmd stats config ...
298         if (!utf8Args[0].compare(String8("config"))) {
299             return cmd_config(in, out, err, utf8Args);
300         }
301 
302         if (!utf8Args[0].compare(String8("print-uid-map"))) {
303             return cmd_print_uid_map(out, utf8Args);
304         }
305 
306         if (!utf8Args[0].compare(String8("dump-report"))) {
307             return cmd_dump_report(out, utf8Args);
308         }
309 
310         if (!utf8Args[0].compare(String8("pull-source")) && argc > 1) {
311             return cmd_print_pulled_metrics(out, utf8Args);
312         }
313 
314         if (!utf8Args[0].compare(String8("send-broadcast"))) {
315             return cmd_trigger_broadcast(out, utf8Args);
316         }
317 
318         if (!utf8Args[0].compare(String8("print-stats"))) {
319             return cmd_print_stats(out, utf8Args);
320         }
321 
322         if (!utf8Args[0].compare(String8("meminfo"))) {
323             return cmd_dump_memory_info(out);
324         }
325 
326         if (!utf8Args[0].compare(String8("write-to-disk"))) {
327             return cmd_write_data_to_disk(out);
328         }
329 
330         if (!utf8Args[0].compare(String8("log-app-breadcrumb"))) {
331             return cmd_log_app_breadcrumb(out, utf8Args);
332         }
333 
334         if (!utf8Args[0].compare(String8("log-binary-push"))) {
335             return cmd_log_binary_push(out, utf8Args);
336         }
337 
338         if (!utf8Args[0].compare(String8("clear-puller-cache"))) {
339             return cmd_clear_puller_cache(out);
340         }
341 
342         if (!utf8Args[0].compare(String8("print-logs"))) {
343             return cmd_print_logs(out, utf8Args);
344         }
345 
346         if (!utf8Args[0].compare(String8("send-active-configs"))) {
347             return cmd_trigger_active_config_broadcast(out, utf8Args);
348         }
349 
350         if (!utf8Args[0].compare(String8("data-subscribe"))) {
351             {
352                 std::lock_guard<std::mutex> lock(mShellSubscriberMutex);
353                 if (mShellSubscriber == nullptr) {
354                     mShellSubscriber = new ShellSubscriber(mUidMap, mPullerManager);
355                 }
356             }
357             int timeoutSec = -1;
358             if (argc >= 2) {
359                 timeoutSec = atoi(utf8Args[1].c_str());
360             }
361             mShellSubscriber->startNewSubscription(in, out, timeoutSec);
362             return NO_ERROR;
363         }
364     }
365 
366     print_cmd_help(out);
367     return NO_ERROR;
368 }
369 
370 void StatsService::print_cmd_help(int out) {
371     dprintf(out,
372             "usage: adb shell cmd stats print-stats-log [tag_required] "
373             "[timestamp_nsec_optional]\n");
374     dprintf(out, "\n");
375     dprintf(out, "\n");
376     dprintf(out, "usage: adb shell cmd stats meminfo\n");
377     dprintf(out, "\n");
378     dprintf(out, "  Prints the malloc debug information. You need to run the following first: \n");
379     dprintf(out, "   # adb shell stop\n");
380     dprintf(out, "   # adb shell setprop libc.debug.malloc.program statsd \n");
381     dprintf(out, "   # adb shell setprop libc.debug.malloc.options backtrace \n");
382     dprintf(out, "   # adb shell start\n");
383     dprintf(out, "\n");
384     dprintf(out, "\n");
385     dprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
386     dprintf(out, "\n");
387     dprintf(out, "  Prints the UID, app name, version mapping.\n");
388     dprintf(out, "  PKG           Optional package name to print the uids of the package\n");
389     dprintf(out, "\n");
390     dprintf(out, "\n");
391     dprintf(out, "usage: adb shell cmd stats pull-source ATOM_TAG [PACKAGE] \n");
392     dprintf(out, "\n");
393     dprintf(out, "  Prints the output of a pulled atom\n");
394     dprintf(out, "  UID           The atom to pull\n");
395     dprintf(out, "  PACKAGE       The package to pull from. Default is AID_SYSTEM\n");
396     dprintf(out, "\n");
397     dprintf(out, "\n");
398     dprintf(out, "usage: adb shell cmd stats write-to-disk \n");
399     dprintf(out, "\n");
400     dprintf(out, "  Flushes all data on memory to disk.\n");
401     dprintf(out, "\n");
402     dprintf(out, "\n");
403     dprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
404     dprintf(out, "  Writes an AppBreadcrumbReported event to the statslog buffer.\n");
405     dprintf(out, "  UID           The uid to use. It is only possible to pass a UID\n");
406     dprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
407     dprintf(out, "                uid is used.\n");
408     dprintf(out, "  LABEL         Integer in [0, 15], as per atoms.proto.\n");
409     dprintf(out, "  STATE         Integer in [0, 3], as per atoms.proto.\n");
410     dprintf(out, "\n");
411     dprintf(out, "\n");
412     dprintf(out,
413             "usage: adb shell cmd stats log-binary-push NAME VERSION STAGING ROLLBACK_ENABLED "
414             "LOW_LATENCY STATE EXPERIMENT_IDS\n");
415     dprintf(out, "  Log a binary push state changed event.\n");
416     dprintf(out, "  NAME                The train name.\n");
417     dprintf(out, "  VERSION             The train version code.\n");
418     dprintf(out, "  STAGING             If this train requires a restart.\n");
419     dprintf(out, "  ROLLBACK_ENABLED    If rollback should be enabled for this install.\n");
420     dprintf(out, "  LOW_LATENCY         If the train requires low latency monitoring.\n");
421     dprintf(out, "  STATE               The status of the train push.\n");
422     dprintf(out, "                      Integer value of the enum in atoms.proto.\n");
423     dprintf(out, "  EXPERIMENT_IDS      Comma separated list of experiment ids.\n");
424     dprintf(out, "                      Leave blank for none.\n");
425     dprintf(out, "\n");
426     dprintf(out, "\n");
427     dprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
428     dprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
429     dprintf(out, "\n");
430     dprintf(out, "  Adds, updates or removes a configuration. The proto should be in\n");
431     dprintf(out, "  wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
432     dprintf(out, "  provided, then all configs will be removed from memory and disk.\n");
433     dprintf(out, "\n");
434     dprintf(out, "  UID           The uid to use. It is only possible to pass the UID\n");
435     dprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
436     dprintf(out, "                uid is used.\n");
437     dprintf(out, "  NAME          The per-uid name to use\n");
438     dprintf(out, "\n");
439     dprintf(out, "\n              *Note: If both UID and NAME are omitted then all configs will\n");
440     dprintf(out, "\n                     be removed from memory and disk!\n");
441     dprintf(out, "\n");
442     dprintf(out,
443             "usage: adb shell cmd stats dump-report [UID] NAME [--keep_data] "
444             "[--include_current_bucket] [--proto]\n");
445     dprintf(out, "  Dump all metric data for a configuration.\n");
446     dprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
447     dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
448     dprintf(out, "                calling uid is used.\n");
449     dprintf(out, "  NAME          The name of the configuration\n");
450     dprintf(out, "  --keep_data   Do NOT erase the data upon dumping it.\n");
451     dprintf(out, "  --proto       Print proto binary.\n");
452     dprintf(out, "\n");
453     dprintf(out, "\n");
454     dprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
455     dprintf(out, "  Send a broadcast that triggers the subscriber to fetch metrics.\n");
456     dprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
457     dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
458     dprintf(out, "                calling uid is used.\n");
459     dprintf(out, "  NAME          The name of the configuration\n");
460     dprintf(out, "\n");
461     dprintf(out, "\n");
462     dprintf(out,
463             "usage: adb shell cmd stats send-active-configs [--uid=UID] [--configs] "
464             "[NAME1] [NAME2] [NAME3..]\n");
465     dprintf(out, "  Send a broadcast that informs the subscriber of the current active configs.\n");
466     dprintf(out, "  --uid=UID     The uid of the configurations. It is only possible to pass\n");
467     dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
468     dprintf(out, "                calling uid is used.\n");
469     dprintf(out, "  --configs     Send the list of configs in the name list instead of\n");
470     dprintf(out, "                the currently active configs\n");
471     dprintf(out, "  NAME LIST     List of configuration names to be included in the broadcast.\n");
472     dprintf(out, "\n");
473     dprintf(out, "\n");
474     dprintf(out, "usage: adb shell cmd stats print-stats\n");
475     dprintf(out, "  Prints some basic stats.\n");
476     dprintf(out, "  --proto       Print proto binary instead of string format.\n");
477     dprintf(out, "\n");
478     dprintf(out, "\n");
479     dprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
480     dprintf(out, "  Clear cached puller data.\n");
481     dprintf(out, "\n");
482     dprintf(out, "usage: adb shell cmd stats print-logs\n");
483     dprintf(out, "  Requires root privileges.\n");
484     dprintf(out, "  Can be disabled by calling adb shell cmd stats print-logs 0\n");
485 }
486 
487 status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) {
488     string name;
489     bool good = false;
490     int uid;
491     const int argCount = args.size();
492     if (argCount == 2) {
493         // Automatically pick the UID
494         uid = AIBinder_getCallingUid();
495         name.assign(args[1].c_str(), args[1].size());
496         good = true;
497     } else if (argCount == 3) {
498         good = getUidFromArgs(args, 1, uid);
499         if (!good) {
500             dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
501                          "other UIDs on eng or userdebug builds.\n");
502         }
503         name.assign(args[2].c_str(), args[2].size());
504     }
505     if (!good) {
506         print_cmd_help(out);
507         return UNKNOWN_ERROR;
508     }
509     ConfigKey key(uid, StrToInt64(name));
510     shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
511     if (receiver == nullptr) {
512         VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str());
513         return UNKNOWN_ERROR;
514     } else if (receiver->sendDataBroadcast(mProcessor->getLastReportTimeNs(key)).isOk()) {
515         VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
516              args[2].c_str());
517     } else {
518         VLOG("StatsService::trigger broadcast failed to %s, %s", args[1].c_str(), args[2].c_str());
519         return UNKNOWN_ERROR;
520     }
521     return NO_ERROR;
522 }
523 
524 status_t StatsService::cmd_trigger_active_config_broadcast(int out, Vector<String8>& args) {
525     const int argCount = args.size();
526     int uid;
527     vector<int64_t> configIds;
528     if (argCount == 1) {
529         // Automatically pick the uid and send a broadcast that has no active configs.
530         uid = AIBinder_getCallingUid();
531         mProcessor->GetActiveConfigs(uid, configIds);
532     } else {
533         int curArg = 1;
534         if(args[curArg].find("--uid=") == 0) {
535             string uidArgStr(args[curArg].c_str());
536             string uidStr = uidArgStr.substr(6);
537             if (!getUidFromString(uidStr.c_str(), uid)) {
538                 dprintf(out, "Invalid UID. Note that the config can only be set for "
539                              "other UIDs on eng or userdebug builds.\n");
540                 return UNKNOWN_ERROR;
541             }
542             curArg++;
543         } else {
544             uid = AIBinder_getCallingUid();
545         }
546         if (curArg == argCount || args[curArg] != "--configs") {
547             VLOG("Reached end of args, or specify configs not set. Sending actual active configs,");
548             mProcessor->GetActiveConfigs(uid, configIds);
549         } else {
550             // Flag specified, use the given list of configs.
551             curArg++;
552             for (int i = curArg; i < argCount; i++) {
553                 char* endp;
554                 int64_t configID = strtoll(args[i].c_str(), &endp, 10);
555                 if (endp == args[i].c_str() || *endp != '\0') {
556                     dprintf(out, "Error parsing config ID.\n");
557                     return UNKNOWN_ERROR;
558                 }
559                 VLOG("Adding config id %ld", static_cast<long>(configID));
560                 configIds.push_back(configID);
561             }
562         }
563     }
564     shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
565     if (receiver == nullptr) {
566         VLOG("Could not find receiver for uid %d", uid);
567         return UNKNOWN_ERROR;
568     } else if (receiver->sendActiveConfigsChangedBroadcast(configIds).isOk()) {
569         VLOG("StatsService::trigger active configs changed broadcast succeeded for uid %d" , uid);
570     } else {
571         VLOG("StatsService::trigger active configs changed broadcast failed for uid %d", uid);
572         return UNKNOWN_ERROR;
573     }
574     return NO_ERROR;
575 }
576 
577 status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& args) {
578     const int argCount = args.size();
579     if (argCount >= 2) {
580         if (args[1] == "update" || args[1] == "remove") {
581             bool good = false;
582             int uid = -1;
583             string name;
584 
585             if (argCount == 3) {
586                 // Automatically pick the UID
587                 uid = AIBinder_getCallingUid();
588                 name.assign(args[2].c_str(), args[2].size());
589                 good = true;
590             } else if (argCount == 4) {
591                 good = getUidFromArgs(args, 2, uid);
592                 if (!good) {
593                     dprintf(err, "Invalid UID. Note that the config can only be set for "
594                                  "other UIDs on eng or userdebug builds.\n");
595                 }
596                 name.assign(args[3].c_str(), args[3].size());
597             } else if (argCount == 2 && args[1] == "remove") {
598                 good = true;
599             }
600 
601             if (!good) {
602                 // If arg parsing failed, print the help text and return an error.
603                 print_cmd_help(out);
604                 return UNKNOWN_ERROR;
605             }
606 
607             if (args[1] == "update") {
608                 char* endp;
609                 int64_t configID = strtoll(name.c_str(), &endp, 10);
610                 if (endp == name.c_str() || *endp != '\0') {
611                     dprintf(err, "Error parsing config ID.\n");
612                     return UNKNOWN_ERROR;
613                 }
614 
615                 // Read stream into buffer.
616                 string buffer;
617                 if (!android::base::ReadFdToString(in, &buffer)) {
618                     dprintf(err, "Error reading stream for StatsConfig.\n");
619                     return UNKNOWN_ERROR;
620                 }
621 
622                 // Parse buffer.
623                 StatsdConfig config;
624                 if (!config.ParseFromString(buffer)) {
625                     dprintf(err, "Error parsing proto stream for StatsConfig.\n");
626                     return UNKNOWN_ERROR;
627                 }
628 
629                 // Add / update the config.
630                 mConfigManager->UpdateConfig(ConfigKey(uid, configID), config);
631             } else {
632                 if (argCount == 2) {
633                     cmd_remove_all_configs(out);
634                 } else {
635                     // Remove the config.
636                     mConfigManager->RemoveConfig(ConfigKey(uid, StrToInt64(name)));
637                 }
638             }
639 
640             return NO_ERROR;
641         }
642     }
643     print_cmd_help(out);
644     return UNKNOWN_ERROR;
645 }
646 
647 status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) {
648     if (mProcessor != nullptr) {
649         int argCount = args.size();
650         bool good = false;
651         bool proto = false;
652         bool includeCurrentBucket = false;
653         bool eraseData = true;
654         int uid;
655         string name;
656         if (!std::strcmp("--proto", args[argCount-1].c_str())) {
657             proto = true;
658             argCount -= 1;
659         }
660         if (!std::strcmp("--include_current_bucket", args[argCount-1].c_str())) {
661             includeCurrentBucket = true;
662             argCount -= 1;
663         }
664         if (!std::strcmp("--keep_data", args[argCount-1].c_str())) {
665             eraseData = false;
666             argCount -= 1;
667         }
668         if (argCount == 2) {
669             // Automatically pick the UID
670             uid = AIBinder_getCallingUid();
671             name.assign(args[1].c_str(), args[1].size());
672             good = true;
673         } else if (argCount == 3) {
674             good = getUidFromArgs(args, 1, uid);
675             if (!good) {
676                 dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
677                              "other UIDs on eng or userdebug builds.\n");
678             }
679             name.assign(args[2].c_str(), args[2].size());
680         }
681         if (good) {
682             vector<uint8_t> data;
683             mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
684                                      includeCurrentBucket, eraseData, ADB_DUMP,
685                                      NO_TIME_CONSTRAINTS,
686                                      &data);
687             if (proto) {
688                 for (size_t i = 0; i < data.size(); i ++) {
689                     dprintf(out, "%c", data[i]);
690                 }
691             } else {
692                 dprintf(out, "Non-proto stats data dump not currently supported.\n");
693             }
694             return android::OK;
695         } else {
696             // If arg parsing failed, print the help text and return an error.
697             print_cmd_help(out);
698             return UNKNOWN_ERROR;
699         }
700     } else {
701         dprintf(out, "Log processor does not exist...\n");
702         return UNKNOWN_ERROR;
703     }
704 }
705 
706 status_t StatsService::cmd_print_stats(int out, const Vector<String8>& args) {
707     int argCount = args.size();
708     bool proto = false;
709     if (!std::strcmp("--proto", args[argCount-1].c_str())) {
710         proto = true;
711         argCount -= 1;
712     }
713     StatsdStats& statsdStats = StatsdStats::getInstance();
714     if (proto) {
715         vector<uint8_t> data;
716         statsdStats.dumpStats(&data, false); // does not reset statsdStats.
717         for (size_t i = 0; i < data.size(); i ++) {
718             dprintf(out, "%c", data[i]);
719         }
720 
721     } else {
722         vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
723         for (const ConfigKey& key : configs) {
724             dprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
725                     mProcessor->GetMetricsSize(key));
726         }
727         statsdStats.dumpStats(out);
728     }
729     return NO_ERROR;
730 }
731 
732 status_t StatsService::cmd_print_uid_map(int out, const Vector<String8>& args) {
733     if (args.size() > 1) {
734         string pkg;
735         pkg.assign(args[1].c_str(), args[1].size());
736         auto uids = mUidMap->getAppUid(pkg);
737         dprintf(out, "%s -> [ ", pkg.c_str());
738         for (const auto& uid : uids) {
739             dprintf(out, "%d ", uid);
740         }
741         dprintf(out, "]\n");
742     } else {
743         mUidMap->printUidMap(out);
744     }
745     return NO_ERROR;
746 }
747 
748 status_t StatsService::cmd_write_data_to_disk(int out) {
749     dprintf(out, "Writing data to disk\n");
750     mProcessor->WriteDataToDisk(ADB_DUMP, NO_TIME_CONSTRAINTS, getElapsedRealtimeNs());
751     return NO_ERROR;
752 }
753 
754 status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& args) {
755     bool good = false;
756     int32_t uid;
757     int32_t label;
758     int32_t state;
759     const int argCount = args.size();
760     if (argCount == 3) {
761         // Automatically pick the UID
762         uid = AIBinder_getCallingUid();
763         label = atoi(args[1].c_str());
764         state = atoi(args[2].c_str());
765         good = true;
766     } else if (argCount == 4) {
767         good = getUidFromArgs(args, 1, uid);
768         if (!good) {
769             dprintf(out,
770                     "Invalid UID. Note that selecting a UID for writing AppBreadcrumb can only be "
771                     "done for other UIDs on eng or userdebug builds.\n");
772         }
773         label = atoi(args[2].c_str());
774         state = atoi(args[3].c_str());
775     }
776     if (good) {
777         dprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
778         android::os::statsd::util::stats_write(
779                 android::os::statsd::util::APP_BREADCRUMB_REPORTED, uid, label, state);
780     } else {
781         print_cmd_help(out);
782         return UNKNOWN_ERROR;
783     }
784     return NO_ERROR;
785 }
786 
787 status_t StatsService::cmd_log_binary_push(int out, const Vector<String8>& args) {
788     // Security checks are done in the sendBinaryPushStateChanged atom.
789     const int argCount = args.size();
790     if (argCount != 7 && argCount != 8) {
791         dprintf(out, "Incorrect number of argument supplied\n");
792         return UNKNOWN_ERROR;
793     }
794     string trainName = string(args[1].c_str());
795     int64_t trainVersion = strtoll(args[2].c_str(), nullptr, 10);
796     int32_t state = atoi(args[6].c_str());
797     vector<int64_t> experimentIds;
798     if (argCount == 8) {
799         vector<string> experimentIdsString = android::base::Split(string(args[7].c_str()), ",");
800         for (string experimentIdString : experimentIdsString) {
801             int64_t experimentId = strtoll(experimentIdString.c_str(), nullptr, 10);
802             experimentIds.push_back(experimentId);
803         }
804     }
805     dprintf(out, "Logging BinaryPushStateChanged\n");
806     vector<uint8_t> experimentIdBytes;
807     writeExperimentIdsToProto(experimentIds, &experimentIdBytes);
808     LogEvent event(trainName, trainVersion, args[3], args[4], args[5], state, experimentIdBytes, 0);
809     mProcessor->OnLogEvent(&event);
810     return NO_ERROR;
811 }
812 
813 status_t StatsService::cmd_print_pulled_metrics(int out, const Vector<String8>& args) {
814     int s = atoi(args[1].c_str());
815     vector<int32_t> uids;
816     if (args.size() > 2) {
817         string package = string(args[2].c_str());
818         auto it = UidMap::sAidToUidMapping.find(package);
819         if (it != UidMap::sAidToUidMapping.end()) {
820             uids.push_back(it->second);
821         } else {
822             set<int32_t> uids_set = mUidMap->getAppUid(package);
823             uids.insert(uids.end(), uids_set.begin(), uids_set.end());
824         }
825     } else {
826         uids.push_back(AID_SYSTEM);
827     }
828     vector<shared_ptr<LogEvent>> stats;
829     if (mPullerManager->Pull(s, uids, getElapsedRealtimeNs(), &stats)) {
830         for (const auto& it : stats) {
831             dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
832         }
833         dprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
834         return NO_ERROR;
835     }
836     return UNKNOWN_ERROR;
837 }
838 
839 status_t StatsService::cmd_remove_all_configs(int out) {
840     dprintf(out, "Removing all configs...\n");
841     VLOG("StatsService::cmd_remove_all_configs was called");
842     mConfigManager->RemoveAllConfigs();
843     StorageManager::deleteAllFiles(STATS_SERVICE_DIR);
844     return NO_ERROR;
845 }
846 
847 status_t StatsService::cmd_dump_memory_info(int out) {
848     dprintf(out, "meminfo not available.\n");
849     return NO_ERROR;
850 }
851 
852 status_t StatsService::cmd_clear_puller_cache(int out) {
853     VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
854             AIBinder_getCallingPid(), AIBinder_getCallingUid());
855     if (checkPermission(kPermissionDump)) {
856         int cleared = mPullerManager->ForceClearPullerCache();
857         dprintf(out, "Puller removed %d cached data!\n", cleared);
858         return NO_ERROR;
859     } else {
860         return PERMISSION_DENIED;
861     }
862 }
863 
864 status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
865     Status status = checkUid(AID_ROOT);
866     if (!status.isOk()) {
867         return PERMISSION_DENIED;
868     }
869 
870     VLOG("StatsService::cmd_print_logs with pid %i, uid %i", AIBinder_getCallingPid(),
871          AIBinder_getCallingUid());
872     bool enabled = true;
873     if (args.size() >= 2) {
874         enabled = atoi(args[1].c_str()) != 0;
875     }
876     mProcessor->setPrintLogs(enabled);
877     return NO_ERROR;
878 }
879 
880 bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) {
881     return getUidFromString(args[uidArgIndex].c_str(), uid);
882 }
883 
884 bool StatsService::getUidFromString(const char* s, int32_t& uid) {
885     if (*s == '\0') {
886         return false;
887     }
888     char* endc = NULL;
889     int64_t longUid = strtol(s, &endc, 0);
890     if (*endc != '\0') {
891         return false;
892     }
893     int32_t goodUid = static_cast<int32_t>(longUid);
894     if (longUid < 0 || static_cast<uint64_t>(longUid) != static_cast<uid_t>(goodUid)) {
895         return false;  // It was not of uid_t type.
896     }
897     uid = goodUid;
898 
899     int32_t callingUid = AIBinder_getCallingUid();
900     return mEngBuild // UserDebug/EngBuild are allowed to impersonate uids.
901             || (callingUid == goodUid) // Anyone can 'impersonate' themselves.
902             || (callingUid == AID_ROOT && goodUid == AID_SHELL); // ROOT can impersonate SHELL.
903 }
904 
905 Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) {
906     ENFORCE_UID(AID_SYSTEM);
907     // Read stream into buffer.
908     string buffer;
909     if (!android::base::ReadFdToString(fd.get(), &buffer)) {
910         return exception(EX_ILLEGAL_ARGUMENT, "Failed to read all data from the pipe.");
911     }
912 
913     // Parse buffer.
914     UidData uidData;
915     if (!uidData.ParseFromString(buffer)) {
916         return exception(EX_ILLEGAL_ARGUMENT, "Error parsing proto stream for UidData.");
917     }
918 
919     vector<String16> versionStrings;
920     vector<String16> installers;
921     vector<String16> packageNames;
922     vector<int32_t> uids;
923     vector<int64_t> versions;
924 
925     const auto numEntries = uidData.app_info_size();
926     versionStrings.reserve(numEntries);
927     installers.reserve(numEntries);
928     packageNames.reserve(numEntries);
929     uids.reserve(numEntries);
930     versions.reserve(numEntries);
931 
932     for (const auto& appInfo: uidData.app_info()) {
933         packageNames.emplace_back(String16(appInfo.package_name().c_str()));
934         uids.push_back(appInfo.uid());
935         versions.push_back(appInfo.version());
936         versionStrings.emplace_back(String16(appInfo.version_string().c_str()));
937         installers.emplace_back(String16(appInfo.installer().c_str()));
938     }
939 
940     mUidMap->updateMap(getElapsedRealtimeNs(),
941                        uids,
942                        versions,
943                        versionStrings,
944                        packageNames,
945                        installers);
946 
947     mBootCompleteTrigger.markComplete(kUidMapReceivedTag);
948     VLOG("StatsService::informAllUidData UidData proto parsed successfully.");
949     return Status::ok();
950 }
951 
952 Status StatsService::informOnePackage(const string& app, int32_t uid, int64_t version,
953                                       const string& versionString, const string& installer) {
954     ENFORCE_UID(AID_SYSTEM);
955 
956     VLOG("StatsService::informOnePackage was called");
957     String16 utf16App = String16(app.c_str());
958     String16 utf16VersionString = String16(versionString.c_str());
959     String16 utf16Installer = String16(installer.c_str());
960 
961     mUidMap->updateApp(getElapsedRealtimeNs(), utf16App, uid, version, utf16VersionString,
962                        utf16Installer);
963     return Status::ok();
964 }
965 
966 Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
967     ENFORCE_UID(AID_SYSTEM);
968 
969     VLOG("StatsService::informOnePackageRemoved was called");
970     String16 utf16App = String16(app.c_str());
971     mUidMap->removeApp(getElapsedRealtimeNs(), utf16App, uid);
972     mConfigManager->RemoveConfigs(uid);
973     return Status::ok();
974 }
975 
976 Status StatsService::informAnomalyAlarmFired() {
977     ENFORCE_UID(AID_SYSTEM);
978     // Anomaly alarms are handled internally now. This code should be fully deleted.
979     return Status::ok();
980 }
981 
982 Status StatsService::informAlarmForSubscriberTriggeringFired() {
983     ENFORCE_UID(AID_SYSTEM);
984 
985     VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
986     int64_t currentTimeSec = getElapsedRealtimeSec();
987     std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
988             mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
989     if (alarmSet.size() > 0) {
990         VLOG("Found periodic alarm fired.");
991         mProcessor->onPeriodicAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
992     } else {
993         ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
994     }
995     return Status::ok();
996 }
997 
998 Status StatsService::informPollAlarmFired() {
999     ENFORCE_UID(AID_SYSTEM);
1000 
1001     VLOG("StatsService::informPollAlarmFired was called");
1002     mProcessor->informPullAlarmFired(getElapsedRealtimeNs());
1003     VLOG("StatsService::informPollAlarmFired succeeded");
1004     return Status::ok();
1005 }
1006 
1007 Status StatsService::systemRunning() {
1008     ENFORCE_UID(AID_SYSTEM);
1009 
1010     // When system_server is up and running, schedule the dropbox task to run.
1011     VLOG("StatsService::systemRunning");
1012     sayHiToStatsCompanion();
1013     return Status::ok();
1014 }
1015 
1016 Status StatsService::informDeviceShutdown() {
1017     ENFORCE_UID(AID_SYSTEM);
1018     VLOG("StatsService::informDeviceShutdown");
1019     int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
1020     mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST, elapsedRealtimeNs);
1021     mProcessor->SaveActiveConfigsToDisk(elapsedRealtimeNs);
1022     mProcessor->SaveMetadataToDisk(getWallClockNs(), elapsedRealtimeNs);
1023     return Status::ok();
1024 }
1025 
1026 void StatsService::sayHiToStatsCompanion() {
1027     shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
1028     if (statsCompanion != nullptr) {
1029         VLOG("Telling statsCompanion that statsd is ready");
1030         statsCompanion->statsdReady();
1031     } else {
1032         VLOG("Could not access statsCompanion");
1033     }
1034 }
1035 
1036 Status StatsService::statsCompanionReady() {
1037     ENFORCE_UID(AID_SYSTEM);
1038 
1039     VLOG("StatsService::statsCompanionReady was called");
1040     shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
1041     if (statsCompanion == nullptr) {
1042         return exception(EX_NULL_POINTER,
1043                          "StatsCompanion unavailable despite it contacting statsd.");
1044     }
1045     VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
1046     AIBinder_linkToDeath(statsCompanion->asBinder().get(),
1047                          mStatsCompanionServiceDeathRecipient.get(), this);
1048     mPullerManager->SetStatsCompanionService(statsCompanion);
1049     mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
1050     mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
1051     return Status::ok();
1052 }
1053 
1054 Status StatsService::bootCompleted() {
1055     ENFORCE_UID(AID_SYSTEM);
1056 
1057     VLOG("StatsService::bootCompleted was called");
1058     mBootCompleteTrigger.markComplete(kBootCompleteTag);
1059     return Status::ok();
1060 }
1061 
1062 void StatsService::Startup() {
1063     mConfigManager->Startup();
1064     mProcessor->LoadActiveConfigsFromDisk();
1065     mProcessor->LoadMetadataFromDisk(getWallClockNs(), getElapsedRealtimeNs());
1066 }
1067 
1068 void StatsService::Terminate() {
1069     ALOGI("StatsService::Terminating");
1070     if (mProcessor != nullptr) {
1071         int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
1072         mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST, elapsedRealtimeNs);
1073         mProcessor->SaveActiveConfigsToDisk(elapsedRealtimeNs);
1074         mProcessor->SaveMetadataToDisk(getWallClockNs(), elapsedRealtimeNs);
1075     }
1076 }
1077 
1078 // Test only interface!!!
1079 void StatsService::OnLogEvent(LogEvent* event) {
1080     mProcessor->OnLogEvent(event);
1081     if (mShellSubscriber != nullptr) {
1082         mShellSubscriber->onLogEvent(*event);
1083     }
1084 }
1085 
1086 Status StatsService::getData(int64_t key, const int32_t callingUid, vector<uint8_t>* output) {
1087     ENFORCE_UID(AID_SYSTEM);
1088 
1089     VLOG("StatsService::getData with Uid %i", callingUid);
1090     ConfigKey configKey(callingUid, key);
1091     // The dump latency does not matter here since we do not include the current bucket, we do not
1092     // need to pull any new data anyhow.
1093     mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
1094                              true /* erase_data */, GET_DATA_CALLED, FAST, output);
1095     return Status::ok();
1096 }
1097 
1098 Status StatsService::getMetadata(vector<uint8_t>* output) {
1099     ENFORCE_UID(AID_SYSTEM);
1100 
1101     StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
1102     return Status::ok();
1103 }
1104 
1105 Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config,
1106                                       const int32_t callingUid) {
1107     ENFORCE_UID(AID_SYSTEM);
1108 
1109     if (addConfigurationChecked(callingUid, key, config)) {
1110         return Status::ok();
1111     } else {
1112         return exception(EX_ILLEGAL_ARGUMENT, "Could not parse malformatted StatsdConfig.");
1113     }
1114 }
1115 
1116 bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config) {
1117     ConfigKey configKey(uid, key);
1118     StatsdConfig cfg;
1119     if (config.size() > 0) {  // If the config is empty, skip parsing.
1120         if (!cfg.ParseFromArray(&config[0], config.size())) {
1121             return false;
1122         }
1123     }
1124     mConfigManager->UpdateConfig(configKey, cfg);
1125     return true;
1126 }
1127 
1128 Status StatsService::removeDataFetchOperation(int64_t key,
1129                                               const int32_t callingUid) {
1130     ENFORCE_UID(AID_SYSTEM);
1131     ConfigKey configKey(callingUid, key);
1132     mConfigManager->RemoveConfigReceiver(configKey);
1133     return Status::ok();
1134 }
1135 
1136 Status StatsService::setDataFetchOperation(int64_t key,
1137                                            const shared_ptr<IPendingIntentRef>& pir,
1138                                            const int32_t callingUid) {
1139     ENFORCE_UID(AID_SYSTEM);
1140 
1141     ConfigKey configKey(callingUid, key);
1142     mConfigManager->SetConfigReceiver(configKey, pir);
1143     if (StorageManager::hasConfigMetricsReport(configKey)) {
1144         VLOG("StatsService::setDataFetchOperation marking configKey %s to dump reports on disk",
1145              configKey.ToString().c_str());
1146         mProcessor->noteOnDiskData(configKey);
1147     }
1148     return Status::ok();
1149 }
1150 
1151 Status StatsService::setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
1152                                                       const int32_t callingUid,
1153                                                       vector<int64_t>* output) {
1154     ENFORCE_UID(AID_SYSTEM);
1155 
1156     mConfigManager->SetActiveConfigsChangedReceiver(callingUid, pir);
1157     if (output != nullptr) {
1158         mProcessor->GetActiveConfigs(callingUid, *output);
1159     } else {
1160         ALOGW("StatsService::setActiveConfigsChanged output was nullptr");
1161     }
1162     return Status::ok();
1163 }
1164 
1165 Status StatsService::removeActiveConfigsChangedOperation(const int32_t callingUid) {
1166     ENFORCE_UID(AID_SYSTEM);
1167 
1168     mConfigManager->RemoveActiveConfigsChangedReceiver(callingUid);
1169     return Status::ok();
1170 }
1171 
1172 Status StatsService::removeConfiguration(int64_t key, const int32_t callingUid) {
1173     ENFORCE_UID(AID_SYSTEM);
1174 
1175     ConfigKey configKey(callingUid, key);
1176     mConfigManager->RemoveConfig(configKey);
1177     return Status::ok();
1178 }
1179 
1180 Status StatsService::setBroadcastSubscriber(int64_t configId,
1181                                             int64_t subscriberId,
1182                                             const shared_ptr<IPendingIntentRef>& pir,
1183                                             const int32_t callingUid) {
1184     ENFORCE_UID(AID_SYSTEM);
1185 
1186     VLOG("StatsService::setBroadcastSubscriber called.");
1187     ConfigKey configKey(callingUid, configId);
1188     SubscriberReporter::getInstance()
1189             .setBroadcastSubscriber(configKey, subscriberId, pir);
1190     return Status::ok();
1191 }
1192 
1193 Status StatsService::unsetBroadcastSubscriber(int64_t configId,
1194                                               int64_t subscriberId,
1195                                               const int32_t callingUid) {
1196     ENFORCE_UID(AID_SYSTEM);
1197 
1198     VLOG("StatsService::unsetBroadcastSubscriber called.");
1199     ConfigKey configKey(callingUid, configId);
1200     SubscriberReporter::getInstance()
1201             .unsetBroadcastSubscriber(configKey, subscriberId);
1202     return Status::ok();
1203 }
1204 
1205 Status StatsService::allPullersFromBootRegistered() {
1206     ENFORCE_UID(AID_SYSTEM);
1207 
1208     VLOG("StatsService::allPullersFromBootRegistered was called");
1209     mBootCompleteTrigger.markComplete(kAllPullersRegisteredTag);
1210     return Status::ok();
1211 }
1212 
1213 Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownMillis,
1214                                               int64_t timeoutMillis,
1215                                               const std::vector<int32_t>& additiveFields,
1216                                               const shared_ptr<IPullAtomCallback>& pullerCallback) {
1217     ENFORCE_UID(AID_SYSTEM);
1218     VLOG("StatsService::registerPullAtomCallback called.");
1219     mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
1220                                              MillisToNano(timeoutMillis), additiveFields,
1221                                              pullerCallback);
1222     return Status::ok();
1223 }
1224 
1225 Status StatsService::registerNativePullAtomCallback(
1226         int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
1227         const std::vector<int32_t>& additiveFields,
1228         const shared_ptr<IPullAtomCallback>& pullerCallback) {
1229     if (!checkPermission(kPermissionRegisterPullAtom)) {
1230         return exception(
1231                 EX_SECURITY,
1232                 StringPrintf("Uid %d does not have the %s permission when registering atom %d",
1233                              AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
1234     }
1235     VLOG("StatsService::registerNativePullAtomCallback called.");
1236     int32_t uid = AIBinder_getCallingUid();
1237     mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
1238                                              MillisToNano(timeoutMillis), additiveFields,
1239                                              pullerCallback);
1240     return Status::ok();
1241 }
1242 
1243 Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
1244     ENFORCE_UID(AID_SYSTEM);
1245     VLOG("StatsService::unregisterPullAtomCallback called.");
1246     mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
1247     return Status::ok();
1248 }
1249 
1250 Status StatsService::unregisterNativePullAtomCallback(int32_t atomTag) {
1251     if (!checkPermission(kPermissionRegisterPullAtom)) {
1252         return exception(
1253                 EX_SECURITY,
1254                 StringPrintf("Uid %d does not have the %s permission when unregistering atom %d",
1255                              AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
1256     }
1257     VLOG("StatsService::unregisterNativePullAtomCallback called.");
1258     int32_t uid = AIBinder_getCallingUid();
1259     mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
1260     return Status::ok();
1261 }
1262 
1263 Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
1264     ENFORCE_UID(AID_SYSTEM);
1265     // TODO: add verifier permission
1266 
1267     experimentIdsOut->clear();
1268     // Read the latest train info
1269     vector<InstallTrainInfo> trainInfoList = StorageManager::readAllTrainInfo();
1270     if (trainInfoList.empty()) {
1271         // No train info means no experiment IDs, return an empty list
1272         return Status::ok();
1273     }
1274 
1275     // Copy the experiment IDs to the out vector
1276     for (InstallTrainInfo& trainInfo : trainInfoList) {
1277         experimentIdsOut->insert(experimentIdsOut->end(),
1278                                  trainInfo.experimentIds.begin(),
1279                                  trainInfo.experimentIds.end());
1280     }
1281     return Status::ok();
1282 }
1283 
1284 void StatsService::statsCompanionServiceDied(void* cookie) {
1285     auto thiz = static_cast<StatsService*>(cookie);
1286     thiz->statsCompanionServiceDiedImpl();
1287 }
1288 
1289 void StatsService::statsCompanionServiceDiedImpl() {
1290     ALOGW("statscompanion service died");
1291     StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
1292     if (mProcessor != nullptr) {
1293         ALOGW("Reset statsd upon system server restarts.");
1294         int64_t systemServerRestartNs = getElapsedRealtimeNs();
1295         ProtoOutputStream activeConfigsProto;
1296         mProcessor->WriteActiveConfigsToProtoOutputStream(systemServerRestartNs,
1297                 STATSCOMPANION_DIED, &activeConfigsProto);
1298         metadata::StatsMetadataList metadataList;
1299         mProcessor->WriteMetadataToProto(getWallClockNs(),
1300                 systemServerRestartNs, &metadataList);
1301         mProcessor->WriteDataToDisk(STATSCOMPANION_DIED, FAST, systemServerRestartNs);
1302         mProcessor->resetConfigs();
1303 
1304         std::string serializedActiveConfigs;
1305         if (activeConfigsProto.serializeToString(&serializedActiveConfigs)) {
1306             ActiveConfigList activeConfigs;
1307             if (activeConfigs.ParseFromString(serializedActiveConfigs)) {
1308                 mProcessor->SetConfigsActiveState(activeConfigs, systemServerRestartNs);
1309             }
1310         }
1311         mProcessor->SetMetadataState(metadataList, getWallClockNs(), systemServerRestartNs);
1312     }
1313     mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
1314     mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
1315     mPullerManager->SetStatsCompanionService(nullptr);
1316 }
1317 
1318 }  // namespace statsd
1319 }  // namespace os
1320 }  // namespace android
1321