Loading api/system-current.txt +7 −0 Original line number Original line Diff line number Diff line Loading @@ -9668,6 +9668,7 @@ package android.content { field public static final java.lang.String SEARCH_SERVICE = "search"; field public static final java.lang.String SEARCH_SERVICE = "search"; field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String STATS_MANAGER = "stats"; field public static final java.lang.String STORAGE_SERVICE = "storage"; field public static final java.lang.String STORAGE_SERVICE = "storage"; field public static final java.lang.String STORAGE_STATS_SERVICE = "storagestats"; field public static final java.lang.String STORAGE_STATS_SERVICE = "storagestats"; field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; Loading Loading @@ -48178,6 +48179,12 @@ package android.util { field public static final int[] WILD_CARD; field public static final int[] WILD_CARD; } } public final class StatsManager { method public byte[] getData(java.lang.String); method public boolean addConfiguration(java.lang.String, byte[], java.lang.String, java.lang.String); method public boolean removeConfiguration(java.lang.String); } public class StringBuilderPrinter implements android.util.Printer { public class StringBuilderPrinter implements android.util.Printer { ctor public StringBuilderPrinter(java.lang.StringBuilder); ctor public StringBuilderPrinter(java.lang.StringBuilder); method public void println(java.lang.String); method public void println(java.lang.String); cmds/statsd/src/StatsService.cpp +62 −19 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include "Log.h" #include "Log.h" #include "StatsService.h" #include "StatsService.h" #include "config/ConfigKey.h" #include "config/ConfigManager.h" #include "storage/DropboxReader.h" #include "storage/DropboxReader.h" #include <android-base/file.h> #include <android-base/file.h> Loading @@ -39,6 +41,8 @@ namespace android { namespace os { namespace os { namespace statsd { namespace statsd { constexpr const char* kPermissionDump = "android.permission.DUMP"; // ====================================================================== // ====================================================================== /** /** * Watches for the death of the stats companion (system process). * Watches for the death of the stats companion (system process). Loading Loading @@ -67,8 +71,8 @@ StatsService::StatsService(const sp<Looper>& handlerLooper) { { mUidMap = new UidMap(); mUidMap = new UidMap(); mConfigManager = new ConfigManager(); mConfigManager = new ConfigManager(); mProcessor = new StatsLogProcessor(mUidMap, [this](const vector<uint8_t>& log) { mProcessor = new StatsLogProcessor(mUidMap, [](const vector<uint8_t>& log) { pushLog(log); // TODO: Update how we send data out of StatsD. }); }); mConfigManager->AddListener(mProcessor); mConfigManager->AddListener(mProcessor); Loading Loading @@ -198,6 +202,10 @@ status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& if (!args[0].compare(String8("pull-source")) && args.size() > 1) { if (!args[0].compare(String8("pull-source")) && args.size() > 1) { return cmd_print_pulled_metrics(out, args); return cmd_print_pulled_metrics(out, args); } } if (!args[0].compare(String8("send-broadcast"))) { return cmd_trigger_broadcast(args); } } } print_cmd_help(out); print_cmd_help(out); Loading Loading @@ -238,6 +246,19 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, " the UID parameter on eng builds. If UID is omitted the\n"); fprintf(out, " the UID parameter on eng builds. If UID is omitted the\n"); fprintf(out, " calling uid is used.\n"); fprintf(out, " calling uid is used.\n"); fprintf(out, " NAME The name of the configuration\n"); fprintf(out, " NAME The name of the configuration\n"); fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats send-broadcast PACKAGE CLASS\n"); fprintf(out, " Send a broadcast that triggers one subscriber to fetch metrics.\n"); fprintf(out, " PACKAGE The name of the package to receive the broadcast.\n"); fprintf(out, " CLASS The name of the class to receive the broadcast.\n"); } status_t StatsService::cmd_trigger_broadcast(Vector<String8>& args) { auto sc = getStatsCompanionService(); sc->sendBroadcast(String16(args[1]), String16(args[2])); ALOGD("StatsService::trigger broadcast succeeded"); return NO_ERROR; } } status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { Loading Loading @@ -520,29 +541,51 @@ void StatsService::OnLogEvent(const LogEvent& event) { mProcessor->OnLogEvent(event); mProcessor->OnLogEvent(event); } } Status StatsService::requestPush() { Status StatsService::getData(const String16& key, vector<uint8_t>* output) { mProcessor->flush(); IPCThreadState* ipc = IPCThreadState::self(); if (checkCallingPermission(String16(kPermissionDump), reinterpret_cast<int32_t*>(ipc->getCallingPid()), reinterpret_cast<int32_t*>(ipc->getCallingUid()))) { // TODO: Implement this. return Status::ok(); return Status::ok(); } } else { return Status::fromExceptionCode(binder::Status::EX_SECURITY); Status StatsService::pushLog(const vector<uint8_t>& log) { } std::lock_guard<std::mutex> lock(mLock); } for (size_t i = 0; i < mCallbacks.size(); i++) { mCallbacks[i]->onReceiveLogs((vector<uint8_t>*)&log); Status StatsService::addConfiguration(const String16& key, } const vector <uint8_t>& config, const String16& package, const String16& cls, bool* success) { IPCThreadState* ipc = IPCThreadState::self(); int32_t* uid = reinterpret_cast<int32_t*>(ipc->getCallingUid()); if (checkCallingPermission(String16(kPermissionDump), reinterpret_cast<int32_t*>(ipc->getCallingPid()), uid)) { string keyString = string(String8(key).string()); ConfigKey configKey(*uid, keyString); StatsdConfig cfg; cfg.ParseFromArray(&config[0], config.size()); mConfigManager->UpdateConfig(configKey, cfg); mConfigManager->SetConfigReceiver(configKey, string(String8(package).string()), string(String8(cls).string())); *success = true; return Status::ok(); return Status::ok(); } } else { return Status::fromExceptionCode(binder::Status::EX_SECURITY); Status StatsService::subscribeStatsLog(const sp<IStatsCallbacks>& callback) { std::lock_guard<std::mutex> lock(mLock); for (size_t i = 0; i < mCallbacks.size(); i++) { if (mCallbacks[i] == callback) { return Status::fromStatusT(-errno); } } } } mCallbacks.add(callback); IInterface::asBinder(callback)->linkToDeath(this); Status StatsService::removeConfiguration(const String16& key, bool* success) { IPCThreadState* ipc = IPCThreadState::self(); if (checkCallingPermission(String16(kPermissionDump), reinterpret_cast<int32_t*>(ipc->getCallingPid()), reinterpret_cast<int32_t*>(ipc->getCallingUid()))) { // TODO: Implement this. return Status::ok(); return Status::ok(); } else { *success = false; return Status::fromExceptionCode(binder::Status::EX_SECURITY); } } } void StatsService::binderDied(const wp<IBinder>& who) { void StatsService::binderDied(const wp<IBinder>& who) { Loading cmds/statsd/src/StatsService.h +14 −7 Original line number Original line Diff line number Diff line Loading @@ -71,20 +71,22 @@ public: virtual void OnLogEvent(const LogEvent& event); virtual void OnLogEvent(const LogEvent& event); /** /** * Binder call to force trigger pushLog. This would be called by callback * Binder call for clients to request data for this configuration key. * clients. */ */ virtual Status requestPush() override; virtual Status getData(const String16& key, vector<uint8_t>* output) override; /** /** * Pushes stats log entries from statsd to callback clients. * Binder call to let clients send a configuration and indicate they're interested when they * should requestData for this configuration. */ */ Status pushLog(const vector<uint8_t>& log); virtual Status addConfiguration(const String16& key, const vector <uint8_t>& config, const String16& package, const String16& cls, bool* success) override; /** /** * Binder call to listen to statsd to send stats log entries. * Binder call to allow clients to remove the specified configuration. */ */ virtual Status subscribeStatsLog(const sp<IStatsCallbacks>& callbacks) override; virtual Status removeConfiguration(const String16& key, bool* success) override; // TODO: public for testing since statsd doesn't run when system starts. Change to private // TODO: public for testing since statsd doesn't run when system starts. Change to private // later. // later. Loading Loading @@ -119,6 +121,11 @@ private: */ */ void print_cmd_help(FILE* out); void print_cmd_help(FILE* out); /** * Trigger a broadcast. */ status_t cmd_trigger_broadcast(Vector<String8>& args); /** /** * Handle the config sub-command. * Handle the config sub-command. */ */ Loading cmds/statsd/src/config/ConfigManager.cpp +9 −0 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,14 @@ void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& confi } } } } void ConfigManager::SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls) { mConfigReceivers[key] = pair<string, string>(pkg, cls); } void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) { mConfigReceivers.erase(key); } void ConfigManager::RemoveConfig(const ConfigKey& key) { void ConfigManager::RemoveConfig(const ConfigKey& key) { unordered_map<ConfigKey, StatsdConfig>::iterator it = mConfigs.find(key); unordered_map<ConfigKey, StatsdConfig>::iterator it = mConfigs.find(key); if (it != mConfigs.end()) { if (it != mConfigs.end()) { Loading @@ -85,6 +93,7 @@ void ConfigManager::RemoveConfigs(int uid) { if (it->first.GetUid() == uid) { if (it->first.GetUid() == uid) { removed.push_back(it->first); removed.push_back(it->first); it = mConfigs.erase(it); it = mConfigs.erase(it); mConfigReceivers.erase(it->first); } else { } else { it++; it++; } } Loading cmds/statsd/src/config/ConfigManager.h +18 −1 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ using android::RefBase; using std::string; using std::string; using std::unordered_map; using std::unordered_map; using std::vector; using std::vector; using std::pair; /** /** * Keeps track of which configurations have been set from various sources. * Keeps track of which configurations have been set from various sources. Loading Loading @@ -63,6 +64,16 @@ public: */ */ void UpdateConfig(const ConfigKey& key, const StatsdConfig& data); void UpdateConfig(const ConfigKey& key, const StatsdConfig& data); /** * Sets the broadcast receiver for a configuration key. */ void SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls); /** * Erase any broadcast receiver associated with this config key. */ void RemoveConfigReceiver(const ConfigKey& key); /** /** * A configuration was removed. * A configuration was removed. * * Loading @@ -87,10 +98,16 @@ private: void update_saved_configs(); void update_saved_configs(); /** /** * The Configs that have been set * The Configs that have been set. Each config should */ */ unordered_map<ConfigKey, StatsdConfig> mConfigs; unordered_map<ConfigKey, StatsdConfig> mConfigs; /** * Each config key can be subscribed by up to one receiver, specified as the package name and * class name. */ unordered_map<ConfigKey, pair<string, string>> mConfigReceivers; /** /** * The ConfigListeners that will be told about changes. * The ConfigListeners that will be told about changes. */ */ Loading Loading
api/system-current.txt +7 −0 Original line number Original line Diff line number Diff line Loading @@ -9668,6 +9668,7 @@ package android.content { field public static final java.lang.String SEARCH_SERVICE = "search"; field public static final java.lang.String SEARCH_SERVICE = "search"; field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String STATS_MANAGER = "stats"; field public static final java.lang.String STORAGE_SERVICE = "storage"; field public static final java.lang.String STORAGE_SERVICE = "storage"; field public static final java.lang.String STORAGE_STATS_SERVICE = "storagestats"; field public static final java.lang.String STORAGE_STATS_SERVICE = "storagestats"; field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; Loading Loading @@ -48178,6 +48179,12 @@ package android.util { field public static final int[] WILD_CARD; field public static final int[] WILD_CARD; } } public final class StatsManager { method public byte[] getData(java.lang.String); method public boolean addConfiguration(java.lang.String, byte[], java.lang.String, java.lang.String); method public boolean removeConfiguration(java.lang.String); } public class StringBuilderPrinter implements android.util.Printer { public class StringBuilderPrinter implements android.util.Printer { ctor public StringBuilderPrinter(java.lang.StringBuilder); ctor public StringBuilderPrinter(java.lang.StringBuilder); method public void println(java.lang.String); method public void println(java.lang.String);
cmds/statsd/src/StatsService.cpp +62 −19 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include "Log.h" #include "Log.h" #include "StatsService.h" #include "StatsService.h" #include "config/ConfigKey.h" #include "config/ConfigManager.h" #include "storage/DropboxReader.h" #include "storage/DropboxReader.h" #include <android-base/file.h> #include <android-base/file.h> Loading @@ -39,6 +41,8 @@ namespace android { namespace os { namespace os { namespace statsd { namespace statsd { constexpr const char* kPermissionDump = "android.permission.DUMP"; // ====================================================================== // ====================================================================== /** /** * Watches for the death of the stats companion (system process). * Watches for the death of the stats companion (system process). Loading Loading @@ -67,8 +71,8 @@ StatsService::StatsService(const sp<Looper>& handlerLooper) { { mUidMap = new UidMap(); mUidMap = new UidMap(); mConfigManager = new ConfigManager(); mConfigManager = new ConfigManager(); mProcessor = new StatsLogProcessor(mUidMap, [this](const vector<uint8_t>& log) { mProcessor = new StatsLogProcessor(mUidMap, [](const vector<uint8_t>& log) { pushLog(log); // TODO: Update how we send data out of StatsD. }); }); mConfigManager->AddListener(mProcessor); mConfigManager->AddListener(mProcessor); Loading Loading @@ -198,6 +202,10 @@ status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& if (!args[0].compare(String8("pull-source")) && args.size() > 1) { if (!args[0].compare(String8("pull-source")) && args.size() > 1) { return cmd_print_pulled_metrics(out, args); return cmd_print_pulled_metrics(out, args); } } if (!args[0].compare(String8("send-broadcast"))) { return cmd_trigger_broadcast(args); } } } print_cmd_help(out); print_cmd_help(out); Loading Loading @@ -238,6 +246,19 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, " the UID parameter on eng builds. If UID is omitted the\n"); fprintf(out, " the UID parameter on eng builds. If UID is omitted the\n"); fprintf(out, " calling uid is used.\n"); fprintf(out, " calling uid is used.\n"); fprintf(out, " NAME The name of the configuration\n"); fprintf(out, " NAME The name of the configuration\n"); fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats send-broadcast PACKAGE CLASS\n"); fprintf(out, " Send a broadcast that triggers one subscriber to fetch metrics.\n"); fprintf(out, " PACKAGE The name of the package to receive the broadcast.\n"); fprintf(out, " CLASS The name of the class to receive the broadcast.\n"); } status_t StatsService::cmd_trigger_broadcast(Vector<String8>& args) { auto sc = getStatsCompanionService(); sc->sendBroadcast(String16(args[1]), String16(args[2])); ALOGD("StatsService::trigger broadcast succeeded"); return NO_ERROR; } } status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { Loading Loading @@ -520,29 +541,51 @@ void StatsService::OnLogEvent(const LogEvent& event) { mProcessor->OnLogEvent(event); mProcessor->OnLogEvent(event); } } Status StatsService::requestPush() { Status StatsService::getData(const String16& key, vector<uint8_t>* output) { mProcessor->flush(); IPCThreadState* ipc = IPCThreadState::self(); if (checkCallingPermission(String16(kPermissionDump), reinterpret_cast<int32_t*>(ipc->getCallingPid()), reinterpret_cast<int32_t*>(ipc->getCallingUid()))) { // TODO: Implement this. return Status::ok(); return Status::ok(); } } else { return Status::fromExceptionCode(binder::Status::EX_SECURITY); Status StatsService::pushLog(const vector<uint8_t>& log) { } std::lock_guard<std::mutex> lock(mLock); } for (size_t i = 0; i < mCallbacks.size(); i++) { mCallbacks[i]->onReceiveLogs((vector<uint8_t>*)&log); Status StatsService::addConfiguration(const String16& key, } const vector <uint8_t>& config, const String16& package, const String16& cls, bool* success) { IPCThreadState* ipc = IPCThreadState::self(); int32_t* uid = reinterpret_cast<int32_t*>(ipc->getCallingUid()); if (checkCallingPermission(String16(kPermissionDump), reinterpret_cast<int32_t*>(ipc->getCallingPid()), uid)) { string keyString = string(String8(key).string()); ConfigKey configKey(*uid, keyString); StatsdConfig cfg; cfg.ParseFromArray(&config[0], config.size()); mConfigManager->UpdateConfig(configKey, cfg); mConfigManager->SetConfigReceiver(configKey, string(String8(package).string()), string(String8(cls).string())); *success = true; return Status::ok(); return Status::ok(); } } else { return Status::fromExceptionCode(binder::Status::EX_SECURITY); Status StatsService::subscribeStatsLog(const sp<IStatsCallbacks>& callback) { std::lock_guard<std::mutex> lock(mLock); for (size_t i = 0; i < mCallbacks.size(); i++) { if (mCallbacks[i] == callback) { return Status::fromStatusT(-errno); } } } } mCallbacks.add(callback); IInterface::asBinder(callback)->linkToDeath(this); Status StatsService::removeConfiguration(const String16& key, bool* success) { IPCThreadState* ipc = IPCThreadState::self(); if (checkCallingPermission(String16(kPermissionDump), reinterpret_cast<int32_t*>(ipc->getCallingPid()), reinterpret_cast<int32_t*>(ipc->getCallingUid()))) { // TODO: Implement this. return Status::ok(); return Status::ok(); } else { *success = false; return Status::fromExceptionCode(binder::Status::EX_SECURITY); } } } void StatsService::binderDied(const wp<IBinder>& who) { void StatsService::binderDied(const wp<IBinder>& who) { Loading
cmds/statsd/src/StatsService.h +14 −7 Original line number Original line Diff line number Diff line Loading @@ -71,20 +71,22 @@ public: virtual void OnLogEvent(const LogEvent& event); virtual void OnLogEvent(const LogEvent& event); /** /** * Binder call to force trigger pushLog. This would be called by callback * Binder call for clients to request data for this configuration key. * clients. */ */ virtual Status requestPush() override; virtual Status getData(const String16& key, vector<uint8_t>* output) override; /** /** * Pushes stats log entries from statsd to callback clients. * Binder call to let clients send a configuration and indicate they're interested when they * should requestData for this configuration. */ */ Status pushLog(const vector<uint8_t>& log); virtual Status addConfiguration(const String16& key, const vector <uint8_t>& config, const String16& package, const String16& cls, bool* success) override; /** /** * Binder call to listen to statsd to send stats log entries. * Binder call to allow clients to remove the specified configuration. */ */ virtual Status subscribeStatsLog(const sp<IStatsCallbacks>& callbacks) override; virtual Status removeConfiguration(const String16& key, bool* success) override; // TODO: public for testing since statsd doesn't run when system starts. Change to private // TODO: public for testing since statsd doesn't run when system starts. Change to private // later. // later. Loading Loading @@ -119,6 +121,11 @@ private: */ */ void print_cmd_help(FILE* out); void print_cmd_help(FILE* out); /** * Trigger a broadcast. */ status_t cmd_trigger_broadcast(Vector<String8>& args); /** /** * Handle the config sub-command. * Handle the config sub-command. */ */ Loading
cmds/statsd/src/config/ConfigManager.cpp +9 −0 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,14 @@ void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& confi } } } } void ConfigManager::SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls) { mConfigReceivers[key] = pair<string, string>(pkg, cls); } void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) { mConfigReceivers.erase(key); } void ConfigManager::RemoveConfig(const ConfigKey& key) { void ConfigManager::RemoveConfig(const ConfigKey& key) { unordered_map<ConfigKey, StatsdConfig>::iterator it = mConfigs.find(key); unordered_map<ConfigKey, StatsdConfig>::iterator it = mConfigs.find(key); if (it != mConfigs.end()) { if (it != mConfigs.end()) { Loading @@ -85,6 +93,7 @@ void ConfigManager::RemoveConfigs(int uid) { if (it->first.GetUid() == uid) { if (it->first.GetUid() == uid) { removed.push_back(it->first); removed.push_back(it->first); it = mConfigs.erase(it); it = mConfigs.erase(it); mConfigReceivers.erase(it->first); } else { } else { it++; it++; } } Loading
cmds/statsd/src/config/ConfigManager.h +18 −1 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ using android::RefBase; using std::string; using std::string; using std::unordered_map; using std::unordered_map; using std::vector; using std::vector; using std::pair; /** /** * Keeps track of which configurations have been set from various sources. * Keeps track of which configurations have been set from various sources. Loading Loading @@ -63,6 +64,16 @@ public: */ */ void UpdateConfig(const ConfigKey& key, const StatsdConfig& data); void UpdateConfig(const ConfigKey& key, const StatsdConfig& data); /** * Sets the broadcast receiver for a configuration key. */ void SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls); /** * Erase any broadcast receiver associated with this config key. */ void RemoveConfigReceiver(const ConfigKey& key); /** /** * A configuration was removed. * A configuration was removed. * * Loading @@ -87,10 +98,16 @@ private: void update_saved_configs(); void update_saved_configs(); /** /** * The Configs that have been set * The Configs that have been set. Each config should */ */ unordered_map<ConfigKey, StatsdConfig> mConfigs; unordered_map<ConfigKey, StatsdConfig> mConfigs; /** * Each config key can be subscribed by up to one receiver, specified as the package name and * class name. */ unordered_map<ConfigKey, pair<string, string>> mConfigReceivers; /** /** * The ConfigListeners that will be told about changes. * The ConfigListeners that will be told about changes. */ */ Loading