15dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato/*
20feae94babf0518ac28b7c529b4e16762d48e6deyro * Copyright (C) 2017 The Android Open Source Project
35dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato *
45dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
55dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * you may not use this file except in compliance with the License.
65dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * You may obtain a copy of the License at
75dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato *
85dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
95dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato *
105dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * Unless required by applicable law or agreed to in writing, software
115dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
125dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * See the License for the specific language governing permissions and
145dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato * limitations under the License.
155dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato */
165dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
17484524a246ffe453f8cd89b698a279c23b0bde1fTej Singh#define DEBUG false  // STOPSHIP if true
189fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato#include "Log.h"
195dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
205dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato#include "StatsService.h"
21330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac#include "stats_log_util.h"
228d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#include "android-base/stringprintf.h"
23adaf8b344e312853530e276ceff05783133ecf17David Chen#include "config/ConfigKey.h"
24adaf8b344e312853530e276ceff05783133ecf17David Chen#include "config/ConfigManager.h"
25b356151e63140085cb96fa16804ee18b3862a4fcYao Chen#include "guardrail/StatsdStats.h"
26947fbce521d9e8377df03e3c1c31884ed5577f32yro#include "storage/StorageManager.h"
27c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz#include "subscriber/SubscriberReporter.h"
285dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
290656b7a158f6f71989e76ba55423217e3e75d8b4David Chen#include <android-base/file.h>
306b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey#include <android-base/stringprintf.h>
315dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato#include <binder/IPCThreadState.h>
325dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato#include <binder/IServiceManager.h>
336b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey#include <binder/PermissionController.h>
3487d983cf6f609cf3467d05d92bba30329953fbdbyro#include <dirent.h>
350656b7a158f6f71989e76ba55423217e3e75d8b4David Chen#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
365dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato#include <private/android_filesystem_config.h>
375dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato#include <utils/Looper.h>
382cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato#include <utils/String16.h>
39b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz#include <statslog.h>
405dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato#include <stdio.h>
41482d272d7c94201206518d6b37d32647838b15d7Yao Chen#include <stdlib.h>
429fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato#include <sys/system_properties.h>
43ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen#include <unistd.h>
445dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
455dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onoratousing namespace android;
465dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
476b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeyusing android::base::StringPrintf;
486b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
49906a35c814817c8bd503c3f4df8af9a2f622169dBookatznamespace android {
50906a35c814817c8bd503c3f4df8af9a2f622169dBookatznamespace os {
51906a35c814817c8bd503c3f4df8af9a2f622169dBookatznamespace statsd {
52906a35c814817c8bd503c3f4df8af9a2f622169dBookatz
53adaf8b344e312853530e276ceff05783133ecf17David Chenconstexpr const char* kPermissionDump = "android.permission.DUMP";
546b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeyconstexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS";
556b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
566b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeyconstexpr const char* kOpUsage = "android:get_usage_stats";
576b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
5803faf093301847f0ac293ce8d6fcb0bce657a841yro#define STATS_SERVICE_DIR "/data/misc/stats-service"
59adaf8b344e312853530e276ceff05783133ecf17David Chen
606b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeystatic binder::Status ok() {
616b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    return binder::Status::ok();
626b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey}
636b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
646b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeystatic binder::Status exception(uint32_t code, const std::string& msg) {
656b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ALOGE("%s (%d)", msg.c_str(), code);
666b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
676b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey}
686b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
696b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeybinder::Status checkUid(uid_t expectedUid) {
706b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    uid_t uid = IPCThreadState::self()->getCallingUid();
716b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (uid == expectedUid || uid == AID_ROOT) {
726b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return ok();
736b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    } else {
746b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return exception(binder::Status::EX_SECURITY,
756b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
766b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }
776b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey}
786b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
796b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkeybinder::Status checkDumpAndUsageStats(const String16& packageName) {
806b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    pid_t pid = IPCThreadState::self()->getCallingPid();
816b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    uid_t uid = IPCThreadState::self()->getCallingUid();
826b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
836b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    // Root, system, and shell always have access
846b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (uid == AID_ROOT || uid == AID_SYSTEM || uid == AID_SHELL) {
856b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return ok();
866b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }
876b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
886b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    // Caller must be granted these permissions
896b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (!checkCallingPermission(String16(kPermissionDump))) {
906b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return exception(binder::Status::EX_SECURITY,
916b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, kPermissionDump));
926b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }
936b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (!checkCallingPermission(String16(kPermissionUsage))) {
946b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return exception(binder::Status::EX_SECURITY,
956b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, kPermissionUsage));
966b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }
976b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
986b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    // Caller must also have usage stats op granted
996b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    PermissionController pc;
1006b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    switch (pc.noteOp(String16(kOpUsage), uid, packageName)) {
1016b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        case PermissionController::MODE_ALLOWED:
1026b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        case PermissionController::MODE_DEFAULT:
1036b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey            return ok();
1046b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        default:
1056b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey            return exception(binder::Status::EX_SECURITY,
1066b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                    StringPrintf("UID %d / PID %d lacks app-op %s", uid, pid, kOpUsage));
1076b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }
1086b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey}
1096b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
1106b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey#define ENFORCE_UID(uid) {                                        \
1116b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    binder::Status status = checkUid((uid));                      \
1126b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (!status.isOk()) {                                         \
1136b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return status;                                            \
1146b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }                                                             \
1156b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey}
1166b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
1176b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey#define ENFORCE_DUMP_AND_USAGE_STATS(packageName) {               \
1186b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    binder::Status status = checkDumpAndUsageStats(packageName);  \
1196b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (!status.isOk()) {                                         \
1206b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return status;                                            \
1216b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }                                                             \
1226b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey}
1236b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
1245dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe OnoratoStatsService::StatsService(const sp<Looper>& handlerLooper)
125932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    : mAnomalyAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
126932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac       [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
127932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           if (sc != nullptr) {
128932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               sc->setAnomalyAlarm(timeMillis);
129932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
130932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           }
131932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac       },
132932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac       [](const sp<IStatsCompanionService>& sc) {
133932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           if (sc != nullptr) {
134932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               sc->cancelAnomalyAlarm();
135932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
136932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           }
137932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac       })),
138932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac   mPeriodicAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
139932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac      [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
140932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           if (sc != nullptr) {
141932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               sc->setAlarmForSubscriberTriggering(timeMillis);
142932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
143932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           }
144932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac      },
145932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac      [](const sp<IStatsCompanionService>& sc) {
146932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           if (sc != nullptr) {
147932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               sc->cancelAlarmForSubscriberTriggering();
148932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac               StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
149932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac           }
150932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac
151932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac      }))  {
1529fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    mUidMap = new UidMap();
15380f9112aecf08845ef0b2b132d721b7ce850970fChenjie Yu    StatsPuller::SetUidMap(mUidMap);
1549fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    mConfigManager = new ConfigManager();
155932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    mProcessor = new StatsLogProcessor(mUidMap, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
15615f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac                                       getElapsedRealtimeNs(), [this](const ConfigKey& key) {
157932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        sp<IStatsCompanionService> sc = getStatsCompanionService();
158932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        auto receiver = mConfigManager->GetConfigReceiver(key);
159932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        if (sc == nullptr) {
160932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac            VLOG("Could not find StatsCompanionService");
16148944901f7e6334724efadda6c6b27d9e88fc9e2David Chen            return false;
162932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        } else if (receiver == nullptr) {
163932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac            VLOG("Statscompanion could not find a broadcast receiver for %s",
164932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac                 key.ToString().c_str());
16548944901f7e6334724efadda6c6b27d9e88fc9e2David Chen            return false;
166932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        } else {
167d37bc23f5094ebb803abe93c9e3ca27698da35a9David Chen            sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
16848944901f7e6334724efadda6c6b27d9e88fc9e2David Chen            return true;
1691d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        }
170932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    }
171330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac    );
1729fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
1739fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    mConfigManager->AddListener(mProcessor);
1749fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
1759fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    init_system_properties();
1765dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato}
1775dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
178ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao ChenStatsService::~StatsService() {
1795dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato}
1805dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
1819fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratovoid StatsService::init_system_properties() {
1829fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    mEngBuild = false;
1839fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    const prop_info* buildType = __system_property_find("ro.build.type");
1849fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    if (buildType != NULL) {
1859fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato        __system_property_read_callback(buildType, init_build_type_callback, this);
1869fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    }
1870656b7a158f6f71989e76ba55423217e3e75d8b4David Chen}
1880656b7a158f6f71989e76ba55423217e3e75d8b4David Chen
1899fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratovoid StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
1909fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                                            uint32_t serial) {
191729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
1929fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato        reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
1939fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    }
1949fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato}
1959fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
1969fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato/**
1979fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato * Implement our own because the default binder implementation isn't
1989fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato * properly handling SHELL_COMMAND_TRANSACTION.
1999fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato */
200ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chenstatus_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
201ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen                                  uint32_t flags) {
2022cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato    switch (code) {
2032cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato        case SHELL_COMMAND_TRANSACTION: {
2042cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            int in = data.readFileDescriptor();
2052cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            int out = data.readFileDescriptor();
2062cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            int err = data.readFileDescriptor();
2072cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            int argc = data.readInt32();
2082cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            Vector<String8> args;
2092cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
2102cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                args.add(String8(data.readString16()));
2112cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            }
212ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen            sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
213ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen            sp<IResultReceiver> resultReceiver =
214ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen                    IResultReceiver::asInterface(data.readStrongBinder());
2152cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
2162cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            FILE* fin = fdopen(in, "r");
2172cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            FILE* fout = fdopen(out, "w");
2182cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            FILE* ferr = fdopen(err, "w");
2192cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
2202cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            if (fin == NULL || fout == NULL || ferr == NULL) {
2212cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                resultReceiver->send(NO_MEMORY);
2222cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            } else {
2232cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                err = command(fin, fout, ferr, args);
2242cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                resultReceiver->send(err);
2252cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            }
2262cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
2272cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            if (fin != NULL) {
2282cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                fflush(fin);
2292cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                fclose(fin);
2302cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            }
2312cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            if (fout != NULL) {
2322cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                fflush(fout);
2332cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                fclose(fout);
2342cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            }
2352cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            if (fout != NULL) {
2362cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                fflush(ferr);
2372cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato                fclose(ferr);
2382cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            }
2392cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
2402cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato            return NO_ERROR;
2412cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato        }
242ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen        default: { return BnStatsManager::onTransact(code, data, reply, flags); }
2432cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato    }
2442cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato}
2452cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
2469fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato/**
2479fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato * Write debugging data about statsd.
2489fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato */
249ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chenstatus_t StatsService::dump(int fd, const Vector<String16>& args) {
250dd83d703712bfa004a6bb71ddd19780b2d0b79baTej Singh    if (!checkCallingPermission(String16(kPermissionDump))) {
251dd83d703712bfa004a6bb71ddd19780b2d0b79baTej Singh        return PERMISSION_DENIED;
252dd83d703712bfa004a6bb71ddd19780b2d0b79baTej Singh    }
2535dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    FILE* out = fdopen(fd, "w");
2545dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    if (out == NULL) {
2555dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato        return NO_MEMORY;  // the fd is already open
2565dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    }
2575dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
258884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    bool verbose = false;
25941b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    bool proto = false;
260884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    if (args.size() > 0 && !args[0].compare(String16("-v"))) {
261884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen        verbose = true;
262884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    }
26341b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    if (args.size() > 0 && !args[args.size()-1].compare(String16("--proto"))) {
26441b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        proto = true;
26541b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    }
266884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen
26741b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    dump_impl(out, verbose, proto);
2685dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
2695dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    fclose(out);
2705dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    return NO_ERROR;
2715dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato}
2725dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
2739fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato/**
27441b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh * Write debugging data about statsd in text or proto format.
2759fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato */
27641b3f9a8cf74664126d56a05342fa604bf82a621Tej Singhvoid StatsService::dump_impl(FILE* out, bool verbose, bool proto) {
27741b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    if (proto) {
27841b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        vector<uint8_t> data;
27941b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
28041b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        for (size_t i = 0; i < data.size(); i ++) {
28141b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh            fprintf(out, "%c", data[i]);
28241b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        }
28341b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    } else {
28441b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        StatsdStats::getInstance().dumpStats(out);
28541b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        mProcessor->dumpStates(out, verbose);
28641b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    }
2879fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato}
2889fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
2899fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato/**
2909fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato * Implementation of the adb shell cmd stats command.
2919fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato */
292ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chenstatus_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
2936b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    uid_t uid = IPCThreadState::self()->getCallingUid();
2946b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    if (uid != AID_ROOT && uid != AID_SHELL) {
2956b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey        return PERMISSION_DENIED;
2966b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    }
2979fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
2989fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    const int argCount = args.size();
2999fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    if (argCount >= 1) {
3009fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato        // adb shell cmd stats config ...
3010656b7a158f6f71989e76ba55423217e3e75d8b4David Chen        if (!args[0].compare(String8("config"))) {
3029fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            return cmd_config(in, out, err, args);
3039fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato        }
3049fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
305de70169109c57787a23c732ec4b361ade2e9850eDavid Chen        if (!args[0].compare(String8("print-uid-map"))) {
306d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen            return cmd_print_uid_map(out, args);
307de70169109c57787a23c732ec4b361ade2e9850eDavid Chen        }
308729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
309729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        if (!args[0].compare(String8("dump-report"))) {
310729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            return cmd_dump_report(out, err, args);
311729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        }
3121481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen
3131481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen        if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
3141481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen            return cmd_print_pulled_metrics(out, args);
3151481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen        }
316adaf8b344e312853530e276ceff05783133ecf17David Chen
317adaf8b344e312853530e276ceff05783133ecf17David Chen        if (!args[0].compare(String8("send-broadcast"))) {
3181d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen            return cmd_trigger_broadcast(out, args);
3191d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        }
3201d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen
3211d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        if (!args[0].compare(String8("print-stats"))) {
322b356151e63140085cb96fa16804ee18b3862a4fcYao Chen            return cmd_print_stats(out, args);
323adaf8b344e312853530e276ceff05783133ecf17David Chen        }
32487d983cf6f609cf3467d05d92bba30329953fbdbyro
3258d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen        if (!args[0].compare(String8("meminfo"))) {
3268d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen            return cmd_dump_memory_info(out);
3278d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen        }
328947fbce521d9e8377df03e3c1c31884ed5577f32yro
329947fbce521d9e8377df03e3c1c31884ed5577f32yro        if (!args[0].compare(String8("write-to-disk"))) {
330947fbce521d9e8377df03e3c1c31884ed5577f32yro            return cmd_write_data_to_disk(out);
331947fbce521d9e8377df03e3c1c31884ed5577f32yro        }
332b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz
3330b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chen        if (!args[0].compare(String8("log-app-breadcrumb"))) {
3340b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chen            return cmd_log_app_breadcrumb(out, args);
335b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        }
336fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu
337fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu        if (!args[0].compare(String8("clear-puller-cache"))) {
338fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu            return cmd_clear_puller_cache(out);
339fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu        }
340876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen
341876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        if (!args[0].compare(String8("print-logs"))) {
342876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen            return cmd_print_logs(out, args);
343876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        }
3442cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato    }
3452cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
3469fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    print_cmd_help(out);
3472cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato    return NO_ERROR;
3482cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato}
3492cbc2cce80de4c98362c3b753e55c2478c18bd26Joe Onorato
3509fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratovoid StatsService::print_cmd_help(FILE* out) {
3519fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out,
3529fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            "usage: adb shell cmd stats print-stats-log [tag_required] "
3539fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            "[timestamp_nsec_optional]\n");
3549fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3559fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3568d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "usage: adb shell cmd stats meminfo\n");
3578d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "\n");
3588d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "  Prints the malloc debug information. You need to run the following first: \n");
3598d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "   # adb shell stop\n");
3608d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "   # adb shell setprop libc.debug.malloc.program statsd \n");
3618d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "   # adb shell setprop libc.debug.malloc.options backtrace \n");
3628d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "   # adb shell start\n");
3638d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "\n");
3648d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    fprintf(out, "\n");
365d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen    fprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
3669fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3679fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "  Prints the UID, app name, version mapping.\n");
368d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen    fprintf(out, "  PKG           Optional package name to print the uids of the package\n");
3699fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3709fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3713fca5ba3a7cb4a5090b0c9cd6c4710836afd9c3eyro    fprintf(out, "usage: adb shell cmd stats pull-source [int] \n");
3721481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen    fprintf(out, "\n");
3731481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen    fprintf(out, "  Prints the output of a pulled metrics source (int indicates source)\n");
3741481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen    fprintf(out, "\n");
3751481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen    fprintf(out, "\n");
376947fbce521d9e8377df03e3c1c31884ed5577f32yro    fprintf(out, "usage: adb shell cmd stats write-to-disk \n");
377947fbce521d9e8377df03e3c1c31884ed5577f32yro    fprintf(out, "\n");
378947fbce521d9e8377df03e3c1c31884ed5577f32yro    fprintf(out, "  Flushes all data on memory to disk.\n");
379947fbce521d9e8377df03e3c1c31884ed5577f32yro    fprintf(out, "\n");
380947fbce521d9e8377df03e3c1c31884ed5577f32yro    fprintf(out, "\n");
3810b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chen    fprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
3820b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chen    fprintf(out, "  Writes an AppBreadcrumbReported event to the statslog buffer.\n");
383b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "  UID           The uid to use. It is only possible to pass a UID\n");
384b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
385b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "                uid is used.\n");
386b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "  LABEL         Integer in [0, 15], as per atoms.proto.\n");
387b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "  STATE         Integer in [0, 3], as per atoms.proto.\n");
388b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "\n");
389b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    fprintf(out, "\n");
39074fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
3919fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
3929fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3939fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "  Adds, updates or removes a configuration. The proto should be in\n");
39474fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "  wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
39574fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "  provided, then all configs will be removed from memory and disk.\n");
3969fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "\n");
3979fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "  UID           The uid to use. It is only possible to pass the UID\n");
39874fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
3999fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "                uid is used.\n");
4009fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    fprintf(out, "  NAME          The per-uid name to use\n");
4015154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "\n");
40274fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "\n              *Note: If both UID and NAME are omitted then all configs will\n");
40374fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "\n                     be removed from memory and disk!\n");
4045154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "\n");
405b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu    fprintf(out, "usage: adb shell cmd stats dump-report [UID] NAME [--proto]\n");
4065154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "  Dump all metric data for a configuration.\n");
4075154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
4085154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
4095154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "                calling uid is used.\n");
4105154a379303ab90a2b2914676a4441917a329b5dYao Chen    fprintf(out, "  NAME          The name of the configuration\n");
411b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu    fprintf(out, "  --proto       Print proto binary.\n");
412adaf8b344e312853530e276ceff05783133ecf17David Chen    fprintf(out, "\n");
413adaf8b344e312853530e276ceff05783133ecf17David Chen    fprintf(out, "\n");
4141d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
4151d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "  Send a broadcast that triggers the subscriber to fetch metrics.\n");
4161d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
4171d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
4181d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "                calling uid is used.\n");
4191d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "  NAME          The name of the configuration\n");
4201d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "\n");
4211d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "\n");
422f5acabe9466af3571a4318852cdb26856e5ba100Yao Chen    fprintf(out, "usage: adb shell cmd stats print-stats\n");
4231d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    fprintf(out, "  Prints some basic stats.\n");
42441b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    fprintf(out, "  --proto       Print proto binary instead of string format.\n");
425fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    fprintf(out, "\n");
426fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    fprintf(out, "\n");
427fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    fprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
428fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    fprintf(out, "  Clear cached puller data.\n");
429876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    fprintf(out, "\n");
430876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    fprintf(out, "usage: adb shell cmd stats print-logs\n");
431876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    fprintf(out, "      Only works on eng build\n");
432adaf8b344e312853530e276ceff05783133ecf17David Chen}
433adaf8b344e312853530e276ceff05783133ecf17David Chen
4341d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chenstatus_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) {
4351d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    string name;
4361d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    bool good = false;
4371d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    int uid;
4381d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    const int argCount = args.size();
4391d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    if (argCount == 2) {
4401d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        // Automatically pick the UID
4411d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        uid = IPCThreadState::self()->getCallingUid();
4421d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        // TODO: What if this isn't a binder call? Should we fail?
4431d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        name.assign(args[1].c_str(), args[1].size());
4441d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        good = true;
4451d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    } else if (argCount == 3) {
4461d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        // If it's a userdebug or eng build, then the shell user can
4471d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        // impersonate other uids.
4481d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        if (mEngBuild) {
4491d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen            const char* s = args[1].c_str();
4501d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen            if (*s != '\0') {
4511d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                char* end = NULL;
4521d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                uid = strtol(s, &end, 0);
4531d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                if (*end == '\0') {
4541d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                    name.assign(args[2].c_str(), args[2].size());
4551d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                    good = true;
4561d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                }
4571d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen            }
4581d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        } else {
4591d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen            fprintf(out,
4601d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                    "The metrics can only be dumped for other UIDs on eng or userdebug "
4611d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen                            "builds.\n");
4621d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        }
4631d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    }
4641d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    if (!good) {
4651d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        print_cmd_help(out);
4661d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen        return UNKNOWN_ERROR;
4671d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    }
468d37bc23f5094ebb803abe93c9e3ca27698da35a9David Chen    ConfigKey key(uid, StrToInt64(name));
469d37bc23f5094ebb803abe93c9e3ca27698da35a9David Chen    auto receiver = mConfigManager->GetConfigReceiver(key);
4704d889e635d1def2a0475c509ef6f471d9371fcf0yro    sp<IStatsCompanionService> sc = getStatsCompanionService();
471661f791a2580515eee5882ab9498aef94a0d33a5David Chen    if (sc == nullptr) {
472661f791a2580515eee5882ab9498aef94a0d33a5David Chen        VLOG("Could not access statsCompanion");
473661f791a2580515eee5882ab9498aef94a0d33a5David Chen    } else if (receiver == nullptr) {
474661f791a2580515eee5882ab9498aef94a0d33a5David Chen        VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str())
475661f791a2580515eee5882ab9498aef94a0d33a5David Chen    } else {
476d37bc23f5094ebb803abe93c9e3ca27698da35a9David Chen        sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
47774fed9729fdabff8d2c5a3da89eac26b5aff21d4yro        VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
47874fed9729fdabff8d2c5a3da89eac26b5aff21d4yro             args[2].c_str());
4794d889e635d1def2a0475c509ef6f471d9371fcf0yro    }
4804d889e635d1def2a0475c509ef6f471d9371fcf0yro
481adaf8b344e312853530e276ceff05783133ecf17David Chen    return NO_ERROR;
4829fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato}
4839fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
4849fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratostatus_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
4859fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    const int argCount = args.size();
4869fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    if (argCount >= 2) {
4879fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato        if (args[1] == "update" || args[1] == "remove") {
4889fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            bool good = false;
4899fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            int uid = -1;
4909fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            string name;
4919fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
4929fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            if (argCount == 3) {
4939fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // Automatically pick the UID
4949fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                uid = IPCThreadState::self()->getCallingUid();
4959fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // TODO: What if this isn't a binder call? Should we fail?
4969fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                name.assign(args[2].c_str(), args[2].size());
4979fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                good = true;
4989fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            } else if (argCount == 4) {
4999fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // If it's a userdebug or eng build, then the shell user can
5009fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // impersonate other uids.
5019fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                if (mEngBuild) {
5029fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    const char* s = args[2].c_str();
5039fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    if (*s != '\0') {
5049fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                        char* end = NULL;
5059fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                        uid = strtol(s, &end, 0);
5069fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                        if (*end == '\0') {
5079fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                            name.assign(args[3].c_str(), args[3].size());
5089fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                            good = true;
5099fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                        }
5109fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    }
5119fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                } else {
512729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                    fprintf(err,
513729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                            "The config can only be set for other UIDs on eng or userdebug "
514729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                            "builds.\n");
5159fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                }
516e5f82927ae60fdff909e030434354a6ba164f333yro            } else if (argCount == 2 && args[1] == "remove") {
517e5f82927ae60fdff909e030434354a6ba164f333yro                good = true;
5189fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            }
5199fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
5209fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            if (!good) {
5219fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // If arg parsing failed, print the help text and return an error.
5229fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                print_cmd_help(out);
5239fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                return UNKNOWN_ERROR;
5249fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            }
5259fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
5269fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            if (args[1] == "update") {
527255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                char* endp;
528255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                int64_t configID = strtoll(name.c_str(), &endp, 10);
529255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                if (endp == name.c_str() || *endp != '\0') {
530255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                    fprintf(err, "Error parsing config ID.\n");
531255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                    return UNKNOWN_ERROR;
532255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                }
533255f72e73e23f79157faaf28fcea482c0fa2f5bdyro
5349fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // Read stream into buffer.
5359fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                string buffer;
5369fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                if (!android::base::ReadFdToString(fileno(in), &buffer)) {
5379fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    fprintf(err, "Error reading stream for StatsConfig.\n");
5389fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    return UNKNOWN_ERROR;
5399fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                }
5409fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
5419fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // Parse buffer.
5429fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                StatsdConfig config;
5439fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                if (!config.ParseFromString(buffer)) {
5449fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    fprintf(err, "Error parsing proto stream for StatsConfig.\n");
5459fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                    return UNKNOWN_ERROR;
5469fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                }
5479fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
5489fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato                // Add / update the config.
549255f72e73e23f79157faaf28fcea482c0fa2f5bdyro                mConfigManager->UpdateConfig(ConfigKey(uid, configID), config);
5509fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            } else {
55174fed9729fdabff8d2c5a3da89eac26b5aff21d4yro                if (argCount == 2) {
55274fed9729fdabff8d2c5a3da89eac26b5aff21d4yro                    cmd_remove_all_configs(out);
55374fed9729fdabff8d2c5a3da89eac26b5aff21d4yro                } else {
55474fed9729fdabff8d2c5a3da89eac26b5aff21d4yro                    // Remove the config.
55594e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac                    mConfigManager->RemoveConfig(ConfigKey(uid, StrToInt64(name)));
55674fed9729fdabff8d2c5a3da89eac26b5aff21d4yro                }
5579fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            }
5589fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
5599fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato            return NO_ERROR;
5609fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato        }
5610656b7a158f6f71989e76ba55423217e3e75d8b4David Chen    }
5629fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    print_cmd_help(out);
5639fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    return UNKNOWN_ERROR;
5649fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato}
5659fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato
566729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenstatus_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args) {
567729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    if (mProcessor != nullptr) {
568b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu        int argCount = args.size();
569729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        bool good = false;
570b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu        bool proto = false;
571729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        int uid;
572729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        string name;
573b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu        if (!std::strcmp("--proto", args[argCount-1].c_str())) {
574b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu            proto = true;
575b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu            argCount -= 1;
576b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu        }
577729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        if (argCount == 2) {
578729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            // Automatically pick the UID
579729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            uid = IPCThreadState::self()->getCallingUid();
580729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            // TODO: What if this isn't a binder call? Should we fail?
5815154a379303ab90a2b2914676a4441917a329b5dYao Chen            name.assign(args[1].c_str(), args[1].size());
582729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            good = true;
583729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        } else if (argCount == 3) {
584729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            // If it's a userdebug or eng build, then the shell user can
585729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            // impersonate other uids.
586729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            if (mEngBuild) {
587729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                const char* s = args[1].c_str();
588729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                if (*s != '\0') {
589729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                    char* end = NULL;
590729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                    uid = strtol(s, &end, 0);
591729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                    if (*end == '\0') {
592729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                        name.assign(args[2].c_str(), args[2].size());
593729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                        good = true;
594729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                    }
595729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                }
596729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            } else {
597729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                fprintf(out,
598729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                        "The metrics can only be dumped for other UIDs on eng or userdebug "
599729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                        "builds.\n");
600729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            }
601729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        }
602729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        if (good) {
6031d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen            vector<uint8_t> data;
604926fc7571a656b6ab7b758e4b108aee102029c94David Chen            mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
60556ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                                     false /* include_current_bucket*/, ADB_DUMP, &data);
606729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            // TODO: print the returned StatsLogReport to file instead of printing to logcat.
607b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu            if (proto) {
608b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu                for (size_t i = 0; i < data.size(); i ++) {
609b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu                    fprintf(out, "%c", data[i]);
610b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu                }
611b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu            } else {
612b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu                fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
613b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu                fprintf(out, "See the StatsLogReport in logcat...\n");
614b236c86b81a1e58fce6fe576dd336764138899d0Chenjie Yu            }
615729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            return android::OK;
616729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        } else {
617729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            // If arg parsing failed, print the help text and return an error.
618729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            print_cmd_help(out);
619729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen            return UNKNOWN_ERROR;
620729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        }
621729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    } else {
622729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        fprintf(out, "Log processor does not exist...\n");
623729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        return UNKNOWN_ERROR;
624729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
625729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}
626729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
627b356151e63140085cb96fa16804ee18b3862a4fcYao Chenstatus_t StatsService::cmd_print_stats(FILE* out, const Vector<String8>& args) {
62841b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    int argCount = args.size();
62941b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    bool proto = false;
63041b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    if (!std::strcmp("--proto", args[argCount-1].c_str())) {
63141b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        proto = true;
63241b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        argCount -= 1;
6331d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    }
634b356151e63140085cb96fa16804ee18b3862a4fcYao Chen    StatsdStats& statsdStats = StatsdStats::getInstance();
63541b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    if (proto) {
63641b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        vector<uint8_t> data;
63741b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        statsdStats.dumpStats(&data, false); // does not reset statsdStats.
63841b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        for (size_t i = 0; i < data.size(); i ++) {
63941b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh            fprintf(out, "%c", data[i]);
64041b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        }
64141b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh
64241b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    } else {
64341b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
64441b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        for (const ConfigKey& key : configs) {
64541b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh            fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
64641b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh                    mProcessor->GetMetricsSize(key));
64741b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        }
64841b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh        statsdStats.dumpStats(out);
64941b3f9a8cf74664126d56a05342fa604bf82a621Tej Singh    }
6501d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen    return NO_ERROR;
6511d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen}
6521d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chen
653d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chenstatus_t StatsService::cmd_print_uid_map(FILE* out, const Vector<String8>& args) {
654d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen    if (args.size() > 1) {
655d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        string pkg;
656d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        pkg.assign(args[1].c_str(), args[1].size());
657d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        auto uids = mUidMap->getAppUid(pkg);
658d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        fprintf(out, "%s -> [ ", pkg.c_str());
659d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        for (const auto& uid : uids) {
660d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen            fprintf(out, "%d ", uid);
661d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        }
662d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        fprintf(out, "]\n");
663d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen    } else {
664d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen        mUidMap->printUidMap(out);
665d10f7b1c7bdb1c66aa04148945cae9733ee4cadfYao Chen    }
6669fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    return NO_ERROR;
6670656b7a158f6f71989e76ba55423217e3e75d8b4David Chen}
6680656b7a158f6f71989e76ba55423217e3e75d8b4David Chen
669947fbce521d9e8377df03e3c1c31884ed5577f32yrostatus_t StatsService::cmd_write_data_to_disk(FILE* out) {
670947fbce521d9e8377df03e3c1c31884ed5577f32yro    fprintf(out, "Writing data to disk\n");
671892f3d32293b8358c72da4a94633827abbda640bYangster-mac    mProcessor->WriteDataToDisk(ADB_DUMP);
672947fbce521d9e8377df03e3c1c31884ed5577f32yro    return NO_ERROR;
673947fbce521d9e8377df03e3c1c31884ed5577f32yro}
674947fbce521d9e8377df03e3c1c31884ed5577f32yro
6750b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chenstatus_t StatsService::cmd_log_app_breadcrumb(FILE* out, const Vector<String8>& args) {
676b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    bool good = false;
677b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    int32_t uid;
678b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    int32_t label;
679b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    int32_t state;
680b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    const int argCount = args.size();
681b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    if (argCount == 3) {
682b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        // Automatically pick the UID
683b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        uid = IPCThreadState::self()->getCallingUid();
684b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        label = atoi(args[1].c_str());
685b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        state = atoi(args[2].c_str());
686b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        good = true;
687b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    } else if (argCount == 4) {
688b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        uid = atoi(args[1].c_str());
689b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        // If it's a userdebug or eng build, then the shell user can impersonate other uids.
690b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        // Otherwise, the uid must match the actual caller's uid.
691b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        if (mEngBuild || (uid >= 0 && (uid_t)uid == IPCThreadState::self()->getCallingUid())) {
692b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz            label = atoi(args[2].c_str());
693b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz            state = atoi(args[3].c_str());
694b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz            good = true;
695b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        } else {
696b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz            fprintf(out,
697b639d14f1a97b77c4e69de480a6d222265094bbaDavid Chen                    "Selecting a UID for writing AppBreadcrumb can only be done for other UIDs "
698b639d14f1a97b77c4e69de480a6d222265094bbaDavid Chen                            "on eng or userdebug builds.\n");
699b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        }
700b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    }
701b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    if (good) {
7020b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chen        fprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
7030b5c90cd8ce9ccc6cb1a431e52f18225d60a5cd6David Chen        android::util::stats_write(android::util::APP_BREADCRUMB_REPORTED, uid, label, state);
704b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    } else {
705b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        print_cmd_help(out);
706b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz        return UNKNOWN_ERROR;
707b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    }
708b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz    return NO_ERROR;
709b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz}
710b223c4ecae9a101ef820ad71bf89461b5447a34bBookatz
7111481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chenstatus_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) {
7121481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen    int s = atoi(args[1].c_str());
7135305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    vector<shared_ptr<LogEvent> > stats;
7141a0a941c20eb746868d0de52e3806f69c74d335fChenjie Yu    if (mStatsPullerManager.Pull(s, getElapsedRealtimeNs(), &stats)) {
7155305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        for (const auto& it : stats) {
7165305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu            fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
7175305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        }
7185305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
7195305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        return NO_ERROR;
7201481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen    }
7215305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    return UNKNOWN_ERROR;
7221481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen}
7231481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen
72474fed9729fdabff8d2c5a3da89eac26b5aff21d4yrostatus_t StatsService::cmd_remove_all_configs(FILE* out) {
72574fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    fprintf(out, "Removing all configs...\n");
72674fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    VLOG("StatsService::cmd_remove_all_configs was called");
72774fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    mConfigManager->RemoveAllConfigs();
728947fbce521d9e8377df03e3c1c31884ed5577f32yro    StorageManager::deleteAllFiles(STATS_SERVICE_DIR);
72987d983cf6f609cf3467d05d92bba30329953fbdbyro    return NO_ERROR;
73087d983cf6f609cf3467d05d92bba30329953fbdbyro}
73187d983cf6f609cf3467d05d92bba30329953fbdbyro
7328d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chenstatus_t StatsService::cmd_dump_memory_info(FILE* out) {
73320e9e6231a1aba79b4e5ae47f3ccfb066920e60fYao Chen    fprintf(out, "meminfo not available.\n");
7348d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen    return NO_ERROR;
7358d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen}
7368d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen
737e72252b6886096eef308164b830fe84dd3c6c01dChenjie Yustatus_t StatsService::cmd_clear_puller_cache(FILE* out) {
738fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    IPCThreadState* ipc = IPCThreadState::self();
739932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
740932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac            ipc->getCallingPid(), ipc->getCallingUid());
741fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    if (checkCallingPermission(String16(kPermissionDump))) {
742fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu        int cleared = mStatsPullerManager.ForceClearPullerCache();
743fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu        fprintf(out, "Puller removed %d cached data!\n", cleared);
744fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu        return NO_ERROR;
745fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    } else {
746fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu        return PERMISSION_DENIED;
747fa22d65f146c94873ba98b768b08c643424c4477Chenjie Yu    }
748e72252b6886096eef308164b830fe84dd3c6c01dChenjie Yu}
749e72252b6886096eef308164b830fe84dd3c6c01dChenjie Yu
750876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chenstatus_t StatsService::cmd_print_logs(FILE* out, const Vector<String8>& args) {
751876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    IPCThreadState* ipc = IPCThreadState::self();
752876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", ipc->getCallingPid(),
753876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen         ipc->getCallingUid());
754876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    if (checkCallingPermission(String16(kPermissionDump))) {
755876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        bool enabled = true;
756876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        if (args.size() >= 2) {
757876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen            enabled = atoi(args[1].c_str()) != 0;
758876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        }
759876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        mProcessor->setPrintLogs(enabled);
760876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        return NO_ERROR;
761876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    } else {
762876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen        return PERMISSION_DENIED;
763876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen    }
764876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen}
765876889cb760e99221c2fd77c7d67d5409bda0bc7Yao Chen
7663accca05ddcad9d0b1b313eae49f273e39121d3cDianne HackbornStatus StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version,
767de70169109c57787a23c732ec4b361ade2e9850eDavid Chen                                      const vector<String16>& app) {
7686b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
769de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
7706b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::informAllUidData was called");
771bd12527c90d55eefa657e6a71cfdd287ecdb4ab3David Chen    mUidMap->updateMap(getElapsedRealtimeNs(), uid, version, app);
77274fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    VLOG("StatsService::informAllUidData succeeded");
773de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
774de70169109c57787a23c732ec4b361ade2e9850eDavid Chen    return Status::ok();
775de70169109c57787a23c732ec4b361ade2e9850eDavid Chen}
776de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
7773accca05ddcad9d0b1b313eae49f273e39121d3cDianne HackbornStatus StatsService::informOnePackage(const String16& app, int32_t uid, int64_t version) {
7786b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
779de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
7806b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::informOnePackage was called");
781bd12527c90d55eefa657e6a71cfdd287ecdb4ab3David Chen    mUidMap->updateApp(getElapsedRealtimeNs(), app, uid, version);
782de70169109c57787a23c732ec4b361ade2e9850eDavid Chen    return Status::ok();
783de70169109c57787a23c732ec4b361ade2e9850eDavid Chen}
784de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
785de70169109c57787a23c732ec4b361ade2e9850eDavid ChenStatus StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
7866b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
787de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
7886b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::informOnePackageRemoved was called");
789bd12527c90d55eefa657e6a71cfdd287ecdb4ab3David Chen    mUidMap->removeApp(getElapsedRealtimeNs(), app, uid);
790019240235f99ace92ec05feadf3274cf0a0f7cfcyro    mConfigManager->RemoveConfigs(uid);
791de70169109c57787a23c732ec4b361ade2e9850eDavid Chen    return Status::ok();
792de70169109c57787a23c732ec4b361ade2e9850eDavid Chen}
793de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
794ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao ChenStatus StatsService::informAnomalyAlarmFired() {
7956b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
796932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac
7976b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::informAnomalyAlarmFired was called");
798b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    int64_t currentTimeSec = getElapsedRealtimeSec();
799932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
800932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac            mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
801932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    if (alarmSet.size() > 0) {
80266fe06183f3074554c524f6e2ee47ce6fd727941Bookatz        VLOG("Found an anomaly alarm that fired.");
803932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
80466fe06183f3074554c524f6e2ee47ce6fd727941Bookatz    } else {
80566fe06183f3074554c524f6e2ee47ce6fd727941Bookatz        VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled.");
80666fe06183f3074554c524f6e2ee47ce6fd727941Bookatz    }
8071b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz    return Status::ok();
8081b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz}
8091b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz
810932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-macStatus StatsService::informAlarmForSubscriberTriggeringFired() {
8116b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
812932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac
8136b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
814b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    int64_t currentTimeSec = getElapsedRealtimeSec();
815932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
816932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac            mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
817932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    if (alarmSet.size() > 0) {
818932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        VLOG("Found periodic alarm fired.");
819932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        mProcessor->onPeriodicAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
820932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    } else {
821932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
822932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    }
823932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    return Status::ok();
824932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac}
825932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac
826ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao ChenStatus StatsService::informPollAlarmFired() {
8276b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
8281b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz
8296b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::informPollAlarmFired was called");
83015f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    mProcessor->informPullAlarmFired(getElapsedRealtimeNs());
83174fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    VLOG("StatsService::informPollAlarmFired succeeded");
8321b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz    return Status::ok();
8331b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz}
8341b0b114abca0a7c7642b0b7de343e1e2f982ebf0Bookatz
835ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao ChenStatus StatsService::systemRunning() {
8366b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
8375dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
8385dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    // When system_server is up and running, schedule the dropbox task to run.
83974fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    VLOG("StatsService::systemRunning");
840b487b5533eba8635232009c7f32a54a0380a532dBookatz    sayHiToStatsCompanion();
8415dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato    return Status::ok();
8425dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato}
8435dcbc6c015fd56db9381cb7aff58506e8ebcc150Joe Onorato
844892f3d32293b8358c72da4a94633827abbda640bYangster-macStatus StatsService::informDeviceShutdown() {
8456b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
846e36018b2724b5ae40180f956b16c3e276855b99bChenjie Yu    VLOG("StatsService::informDeviceShutdown");
847892f3d32293b8358c72da4a94633827abbda640bYangster-mac    mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN);
848947fbce521d9e8377df03e3c1c31884ed5577f32yro    return Status::ok();
849947fbce521d9e8377df03e3c1c31884ed5577f32yro}
850947fbce521d9e8377df03e3c1c31884ed5577f32yro
851ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chenvoid StatsService::sayHiToStatsCompanion() {
852b487b5533eba8635232009c7f32a54a0380a532dBookatz    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
853b487b5533eba8635232009c7f32a54a0380a532dBookatz    if (statsCompanion != nullptr) {
85474fed9729fdabff8d2c5a3da89eac26b5aff21d4yro        VLOG("Telling statsCompanion that statsd is ready");
855b487b5533eba8635232009c7f32a54a0380a532dBookatz        statsCompanion->statsdReady();
856b487b5533eba8635232009c7f32a54a0380a532dBookatz    } else {
85774fed9729fdabff8d2c5a3da89eac26b5aff21d4yro        VLOG("Could not access statsCompanion");
858b487b5533eba8635232009c7f32a54a0380a532dBookatz    }
859b487b5533eba8635232009c7f32a54a0380a532dBookatz}
860b487b5533eba8635232009c7f32a54a0380a532dBookatz
861ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao ChenStatus StatsService::statsCompanionReady() {
8626b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_UID(AID_SYSTEM);
863b487b5533eba8635232009c7f32a54a0380a532dBookatz
8646b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    VLOG("StatsService::statsCompanionReady was called");
865b487b5533eba8635232009c7f32a54a0380a532dBookatz    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
866b487b5533eba8635232009c7f32a54a0380a532dBookatz    if (statsCompanion == nullptr) {
867ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen        return Status::fromExceptionCode(
868ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen                Status::EX_NULL_POINTER,
869ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen                "statscompanion unavailable despite it contacting statsd!");
870b487b5533eba8635232009c7f32a54a0380a532dBookatz    }
87174fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
872aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    IInterface::asBinder(statsCompanion)->linkToDeath(this);
873aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    mStatsPullerManager.SetStatsCompanionService(statsCompanion);
874932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
875932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
876c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz    SubscriberReporter::getInstance().setStatsCompanionService(statsCompanion);
877b487b5533eba8635232009c7f32a54a0380a532dBookatz    return Status::ok();
878b487b5533eba8635232009c7f32a54a0380a532dBookatz}
879b487b5533eba8635232009c7f32a54a0380a532dBookatz
8809fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onoratovoid StatsService::Startup() {
8819fc9edf95a308f5884bf541cac81ce1f41aba0baJoe Onorato    mConfigManager->Startup();
882de70169109c57787a23c732ec4b361ade2e9850eDavid Chen}
883de70169109c57787a23c732ec4b361ade2e9850eDavid Chen
884163d2602dbc79133096b3dec7920ee157ff1a88bYao Chenvoid StatsService::OnLogEvent(LogEvent* event, bool reconnectionStarts) {
885163d2602dbc79133096b3dec7920ee157ff1a88bYao Chen    mProcessor->OnLogEvent(event, reconnectionStarts);
886906a35c814817c8bd503c3f4df8af9a2f622169dBookatz}
887906a35c814817c8bd503c3f4df8af9a2f622169dBookatz
8886b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff SharkeyStatus StatsService::getData(int64_t key, const String16& packageName, vector<uint8_t>* output) {
8896b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
8906b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
891adaf8b344e312853530e276ceff05783133ecf17David Chen    IPCThreadState* ipc = IPCThreadState::self();
89274fed9729fdabff8d2c5a3da89eac26b5aff21d4yro    VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
8934f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    ConfigKey configKey(ipc->getCallingUid(), key);
89456ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
89556ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                             GET_DATA_CALLED, output);
8964f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
89731eb67b3498d326659b2b164ff367a01a793d641yro}
89831eb67b3498d326659b2b164ff367a01a793d641yro
8996b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff SharkeyStatus StatsService::getMetadata(const String16& packageName, vector<uint8_t>* output) {
9006b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9016b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
9022e8f3807379f5d5d151ad2cb434d8a7aca910238David Chen    IPCThreadState* ipc = IPCThreadState::self();
9032e8f3807379f5d5d151ad2cb434d8a7aca910238David Chen    VLOG("StatsService::getMetadata with Pid %i, Uid %i", ipc->getCallingPid(),
9042e8f3807379f5d5d151ad2cb434d8a7aca910238David Chen         ipc->getCallingUid());
9054f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
9064f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
9072e8f3807379f5d5d151ad2cb434d8a7aca910238David Chen}
9082e8f3807379f5d5d151ad2cb434d8a7aca910238David Chen
9096b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff SharkeyStatus StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config,
9106b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                      const String16& packageName) {
9116b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9126b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
913adaf8b344e312853530e276ceff05783133ecf17David Chen    IPCThreadState* ipc = IPCThreadState::self();
9144f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    if (addConfigurationChecked(ipc->getCallingUid(), key, config)) {
915661f791a2580515eee5882ab9498aef94a0d33a5David Chen        return Status::ok();
916661f791a2580515eee5882ab9498aef94a0d33a5David Chen    } else {
9174f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz        ALOGE("Could not parse malformatted StatsdConfig");
9184f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz        return Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT,
9194f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz                                         "config does not correspond to a StatsdConfig proto");
920661f791a2580515eee5882ab9498aef94a0d33a5David Chen    }
921661f791a2580515eee5882ab9498aef94a0d33a5David Chen}
922661f791a2580515eee5882ab9498aef94a0d33a5David Chen
9239fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chenbool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config) {
9249fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen    ConfigKey configKey(uid, key);
9259fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen    StatsdConfig cfg;
9269fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen    if (config.size() > 0) {  // If the config is empty, skip parsing.
9279fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen        if (!cfg.ParseFromArray(&config[0], config.size())) {
9289fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen            return false;
9299fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen        }
9309fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen    }
9319fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen    mConfigManager->UpdateConfig(configKey, cfg);
9329fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen    return true;
9339fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen}
9349fdd40302e0f4409b2fd4e5a418037c07b42bbe5David Chen
9356b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff SharkeyStatus StatsService::removeDataFetchOperation(int64_t key, const String16& packageName) {
9366b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9376b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
9384f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    IPCThreadState* ipc = IPCThreadState::self();
9394f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    ConfigKey configKey(ipc->getCallingUid(), key);
9404f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    mConfigManager->RemoveConfigReceiver(configKey);
9414f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
942661f791a2580515eee5882ab9498aef94a0d33a5David Chen}
943661f791a2580515eee5882ab9498aef94a0d33a5David Chen
9446b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff SharkeyStatus StatsService::setDataFetchOperation(int64_t key,
9456b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                           const sp<android::IBinder>& intentSender,
9466b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                           const String16& packageName) {
9476b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9486b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
9494f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    IPCThreadState* ipc = IPCThreadState::self();
9504f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    ConfigKey configKey(ipc->getCallingUid(), key);
9514f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    mConfigManager->SetConfigReceiver(configKey, intentSender);
95248944901f7e6334724efadda6c6b27d9e88fc9e2David Chen    if (StorageManager::hasConfigMetricsReport(configKey)) {
95348944901f7e6334724efadda6c6b27d9e88fc9e2David Chen        VLOG("StatsService::setDataFetchOperation marking configKey %s to dump reports on disk",
95448944901f7e6334724efadda6c6b27d9e88fc9e2David Chen             configKey.ToString().c_str());
95548944901f7e6334724efadda6c6b27d9e88fc9e2David Chen        mProcessor->noteOnDiskData(configKey);
95648944901f7e6334724efadda6c6b27d9e88fc9e2David Chen    }
9574f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
95831eb67b3498d326659b2b164ff367a01a793d641yro}
95931eb67b3498d326659b2b164ff367a01a793d641yro
9606b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff SharkeyStatus StatsService::removeConfiguration(int64_t key, const String16& packageName) {
9616b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9626b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
9634f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    IPCThreadState* ipc = IPCThreadState::self();
9644f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    ConfigKey configKey(ipc->getCallingUid(), key);
9654f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    mConfigManager->RemoveConfig(configKey);
9664f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    SubscriberReporter::getInstance().removeConfig(configKey);
9674f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
968c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz}
969c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz
970c697797d43b6932fc7cca1c8d7d850c3fb4d1452BookatzStatus StatsService::setBroadcastSubscriber(int64_t configId,
971c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz                                            int64_t subscriberId,
9726b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                            const sp<android::IBinder>& intentSender,
9736b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                            const String16& packageName) {
9746b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9756b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
976c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz    VLOG("StatsService::setBroadcastSubscriber called.");
9774f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    IPCThreadState* ipc = IPCThreadState::self();
9784f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    ConfigKey configKey(ipc->getCallingUid(), configId);
9794f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    SubscriberReporter::getInstance()
9804f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz            .setBroadcastSubscriber(configKey, subscriberId, intentSender);
9814f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
98231eb67b3498d326659b2b164ff367a01a793d641yro}
98331eb67b3498d326659b2b164ff367a01a793d641yro
984c697797d43b6932fc7cca1c8d7d850c3fb4d1452BookatzStatus StatsService::unsetBroadcastSubscriber(int64_t configId,
9856b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                              int64_t subscriberId,
9866b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey                                              const String16& packageName) {
9876b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
9886b649257377b4ba2dd8a2a02b8dd692a72a2cc1eJeff Sharkey
989c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz    VLOG("StatsService::unsetBroadcastSubscriber called.");
9904f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    IPCThreadState* ipc = IPCThreadState::self();
9914f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    ConfigKey configKey(ipc->getCallingUid(), configId);
9924f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    SubscriberReporter::getInstance()
9934f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz            .unsetBroadcastSubscriber(configKey, subscriberId);
9944f71629002ae1da22ca1c07ce11b9cca9b272d97Bookatz    return Status::ok();
995c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz}
996c697797d43b6932fc7cca1c8d7d850c3fb4d1452Bookatz
997be6d7f90e8487f16e9459011f3b85ca354429f14yroStatus StatsService::sendAppBreadcrumbAtom(int32_t label, int32_t state) {
998be6d7f90e8487f16e9459011f3b85ca354429f14yro    // Permission check not necessary as it's meant for applications to write to
999be6d7f90e8487f16e9459011f3b85ca354429f14yro    // statsd.
1000be6d7f90e8487f16e9459011f3b85ca354429f14yro    android::util::stats_write(util::APP_BREADCRUMB_REPORTED,
1001be6d7f90e8487f16e9459011f3b85ca354429f14yro                               IPCThreadState::self()->getCallingUid(), label,
1002be6d7f90e8487f16e9459011f3b85ca354429f14yro                               state);
1003be6d7f90e8487f16e9459011f3b85ca354429f14yro    return Status::ok();
1004be6d7f90e8487f16e9459011f3b85ca354429f14yro}
1005be6d7f90e8487f16e9459011f3b85ca354429f14yro
10061d7b0cd6b54e3b3ec8efdffd47b40cdd54c4e8d7David Chenvoid StatsService::binderDied(const wp <IBinder>& who) {
1007aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    ALOGW("statscompanion service died");
1008892f3d32293b8358c72da4a94633827abbda640bYangster-mac    StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
1009892f3d32293b8358c72da4a94633827abbda640bYangster-mac    if (mProcessor != nullptr) {
1010892f3d32293b8358c72da4a94633827abbda640bYangster-mac        ALOGW("Reset statsd upon system server restars.");
1011892f3d32293b8358c72da4a94633827abbda640bYangster-mac        mProcessor->WriteDataToDisk(STATSCOMPANION_DIED);
1012892f3d32293b8358c72da4a94633827abbda640bYangster-mac        mProcessor->resetConfigs();
1013892f3d32293b8358c72da4a94633827abbda640bYangster-mac    }
1014aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
1015aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
1016aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    SubscriberReporter::getInstance().setStatsCompanionService(nullptr);
1017aa5b2010152c4042786b558a44a89d25229d8962Chenjie Yu    mStatsPullerManager.SetStatsCompanionService(nullptr);
101831eb67b3498d326659b2b164ff367a01a793d641yro}
101931eb67b3498d326659b2b164ff367a01a793d641yro
1020ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen}  // namespace statsd
1021ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen}  // namespace os
1022ef99c4fa23b42fe6e58db706b9f4780018b6bf3eYao Chen}  // namespace android
1023