Loading cmds/statsd/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -141,10 +141,12 @@ LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) \ LOCAL_MODULE_CLASS := EXECUTABLES # Enable sanitizer on eng builds # Enable sanitizer and allow very verbose printing on eng builds ifeq ($(TARGET_BUILD_VARIANT),eng) LOCAL_CLANG := true LOCAL_SANITIZE := address LOCAL_CFLAGS += \ -DVERY_VERBOSE_PRINTING endif LOCAL_INIT_RC := statsd.rc Loading cmds/statsd/src/StatsLogProcessor.cpp +33 −15 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #define DEBUG true // STOPSHIP if true #define DEBUG false // STOPSHIP if true #include "Log.h" #include "statslog.h" Loading Loading @@ -162,8 +162,27 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event) { OnLogEvent(event, false); } void StatsLogProcessor::resetConfigs() { std::lock_guard<std::mutex> lock(mMetricsMutex); resetConfigsLocked(getElapsedRealtimeNs()); } void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) { std::vector<ConfigKey> configKeys; for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) { configKeys.push_back(it->first); } resetConfigsLocked(timestampNs, configKeys); } void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { std::lock_guard<std::mutex> lock(mMetricsMutex); #ifdef VERY_VERBOSE_PRINTING if (mPrintAllLogs) { ALOGI("%s", event->ToString().c_str()); } #endif const int64_t currentTimestampNs = event->GetElapsedTimestampNs(); if (reconnected && mLastTimestampSeen != 0) { Loading @@ -188,11 +207,7 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { WriteDataToDiskLocked(CONFIG_RESET); // We see fresher event before we see the checkpoint. We might have lost data. // The best we can do is to reset. std::vector<ConfigKey> configKeys; for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) { configKeys.push_back(it->first); } resetConfigsLocked(currentTimestampNs, configKeys); resetConfigsLocked(currentTimestampNs); } else { // Still in search of the CP. Keep going. return; Loading Loading @@ -242,6 +257,7 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) { std::lock_guard<std::mutex> lock(mMetricsMutex); WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED); OnConfigUpdatedLocked(timestampNs, key, config); } Loading @@ -251,10 +267,6 @@ void StatsLogProcessor::OnConfigUpdatedLocked( sp<MetricsManager> newMetricsManager = new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { WriteDataToDiskLocked(it->first, CONFIG_UPDATED); } if (newMetricsManager->isConfigValid()) { mUidMap->OnConfigUpdated(key); if (newMetricsManager->shouldAddUidMapListener()) { Loading Loading @@ -419,6 +431,7 @@ void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) } } if (configKeysTtlExpired.size() > 0) { WriteDataToDiskLocked(CONFIG_RESET); resetConfigsLocked(timestampNs, configKeysTtlExpired); } } Loading @@ -427,7 +440,7 @@ void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) { std::lock_guard<std::mutex> lock(mMetricsMutex); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { WriteDataToDiskLocked(key, CONFIG_REMOVED); WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED); mMetricsManagers.erase(it); mUidMap->OnConfigRemoved(key); } Loading Loading @@ -474,9 +487,13 @@ void StatsLogProcessor::flushIfNecessaryLocked( } void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs, const DumpReportReason dumpReportReason) { if (mMetricsManagers.find(key) == mMetricsManagers.end()) { return; } ProtoOutputStream proto; onConfigMetricsReportLocked(key, getElapsedRealtimeNs(), onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/, false /* include strings */, dumpReportReason, &proto); string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, Loading @@ -491,14 +508,15 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, } void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason) { const int64_t timeNs = getElapsedRealtimeNs(); for (auto& pair : mMetricsManagers) { WriteDataToDiskLocked(pair.first, dumpReportReason); WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason); } } void StatsLogProcessor::WriteDataToDisk(bool isShutdown) { void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason) { std::lock_guard<std::mutex> lock(mMetricsMutex); WriteDataToDiskLocked(DEVICE_SHUTDOWN); WriteDataToDiskLocked(dumpReportReason); } void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) { Loading cmds/statsd/src/StatsLogProcessor.h +21 −3 Original line number Diff line number Diff line Loading @@ -77,7 +77,10 @@ public: unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); /* Flushes data to disk. Data on memory will be gone after written to disk. */ void WriteDataToDisk(bool shutdown); void WriteDataToDisk(const DumpReportReason dumpReportReason); // Reset all configs. void resetConfigs(); inline sp<UidMap> getUidMap() { return mUidMap; Loading @@ -89,6 +92,13 @@ public: int64_t getLastReportTimeNs(const ConfigKey& key); inline void setPrintLogs(bool enabled) { #ifdef VERY_VERBOSE_PRINTING std::lock_guard<std::mutex> lock(mMetricsMutex); mPrintAllLogs = enabled; #endif } private: // For testing only. inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const { Loading Loading @@ -121,8 +131,9 @@ private: void OnConfigUpdatedLocked( const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config); void WriteDataToDiskLocked(DumpReportReason dumpReportReason); void WriteDataToDiskLocked(const ConfigKey& key, DumpReportReason dumpReportReason); void WriteDataToDiskLocked(const DumpReportReason dumpReportReason); void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs, const DumpReportReason dumpReportReason); void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, Loading @@ -141,6 +152,9 @@ private: // Handler over the isolated uid change event. void onIsolatedUidChangedEventLocked(const LogEvent& event); // Reset all configs. void resetConfigsLocked(const int64_t timestampNs); // Reset the specified configs. void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs); // Function used to send a broadcast so that receiver for the config key can call getData Loading @@ -164,6 +178,10 @@ private: long mLastPullerCacheClearTimeSec = 0; #ifdef VERY_VERBOSE_PRINTING bool mPrintAllLogs = false; #endif FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs); FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize); FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast); Loading cmds/statsd/src/StatsService.cpp +32 −4 Original line number Diff line number Diff line Loading @@ -334,6 +334,10 @@ status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& if (!args[0].compare(String8("clear-puller-cache"))) { return cmd_clear_puller_cache(out); } if (!args[0].compare(String8("print-logs"))) { return cmd_print_logs(out, args); } } print_cmd_help(out); Loading Loading @@ -419,6 +423,9 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats clear-puller-cache\n"); fprintf(out, " Clear cached puller data.\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats print-logs\n"); fprintf(out, " Only works on eng build\n"); } status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) { Loading Loading @@ -659,7 +666,7 @@ status_t StatsService::cmd_print_uid_map(FILE* out, const Vector<String8>& args) status_t StatsService::cmd_write_data_to_disk(FILE* out) { fprintf(out, "Writing data to disk\n"); mProcessor->WriteDataToDisk(false); mProcessor->WriteDataToDisk(ADB_DUMP); return NO_ERROR; } Loading Loading @@ -738,6 +745,22 @@ status_t StatsService::cmd_clear_puller_cache(FILE* out) { } } status_t StatsService::cmd_print_logs(FILE* out, const Vector<String8>& args) { IPCThreadState* ipc = IPCThreadState::self(); VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); if (checkCallingPermission(String16(kPermissionDump))) { bool enabled = true; if (args.size() >= 2) { enabled = atoi(args[1].c_str()) != 0; } mProcessor->setPrintLogs(enabled); return NO_ERROR; } else { return PERMISSION_DENIED; } } Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version, const vector<String16>& app) { ENFORCE_UID(AID_SYSTEM); Loading Loading @@ -816,10 +839,10 @@ Status StatsService::systemRunning() { return Status::ok(); } Status StatsService::informDeviceShutdown(bool isShutdown) { Status StatsService::informDeviceShutdown() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::informDeviceShutdown"); mProcessor->WriteDataToDisk(isShutdown); mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN); return Status::ok(); } Loading Loading @@ -967,7 +990,12 @@ Status StatsService::unsetBroadcastSubscriber(int64_t configId, void StatsService::binderDied(const wp <IBinder>& who) { ALOGW("statscompanion service died"); StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec()); if (mProcessor != nullptr) { ALOGW("Reset statsd upon system server restars."); mProcessor->WriteDataToDisk(STATSCOMPANION_DIED); mProcessor->resetConfigs(); } mAnomalyAlarmMonitor->setStatsCompanionService(nullptr); mPeriodicAlarmMonitor->setStatsCompanionService(nullptr); SubscriberReporter::getInstance().setStatsCompanionService(nullptr); Loading cmds/statsd/src/StatsService.h +6 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public: const vector<String16>& app); virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version); virtual Status informOnePackageRemoved(const String16& app, int32_t uid); virtual Status informDeviceShutdown(bool isShutdown); virtual Status informDeviceShutdown(); /** * Called right before we start processing events. Loading Loading @@ -220,6 +220,11 @@ private: */ status_t cmd_clear_puller_cache(FILE* out); /** * Print all stats logs received to logcat. */ status_t cmd_print_logs(FILE* out, const Vector<String8>& args); /** * Adds a configuration after checking permissions and obtaining UID from binder call. */ Loading Loading
cmds/statsd/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -141,10 +141,12 @@ LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) \ LOCAL_MODULE_CLASS := EXECUTABLES # Enable sanitizer on eng builds # Enable sanitizer and allow very verbose printing on eng builds ifeq ($(TARGET_BUILD_VARIANT),eng) LOCAL_CLANG := true LOCAL_SANITIZE := address LOCAL_CFLAGS += \ -DVERY_VERBOSE_PRINTING endif LOCAL_INIT_RC := statsd.rc Loading
cmds/statsd/src/StatsLogProcessor.cpp +33 −15 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ #define DEBUG true // STOPSHIP if true #define DEBUG false // STOPSHIP if true #include "Log.h" #include "statslog.h" Loading Loading @@ -162,8 +162,27 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event) { OnLogEvent(event, false); } void StatsLogProcessor::resetConfigs() { std::lock_guard<std::mutex> lock(mMetricsMutex); resetConfigsLocked(getElapsedRealtimeNs()); } void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) { std::vector<ConfigKey> configKeys; for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) { configKeys.push_back(it->first); } resetConfigsLocked(timestampNs, configKeys); } void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { std::lock_guard<std::mutex> lock(mMetricsMutex); #ifdef VERY_VERBOSE_PRINTING if (mPrintAllLogs) { ALOGI("%s", event->ToString().c_str()); } #endif const int64_t currentTimestampNs = event->GetElapsedTimestampNs(); if (reconnected && mLastTimestampSeen != 0) { Loading @@ -188,11 +207,7 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { WriteDataToDiskLocked(CONFIG_RESET); // We see fresher event before we see the checkpoint. We might have lost data. // The best we can do is to reset. std::vector<ConfigKey> configKeys; for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) { configKeys.push_back(it->first); } resetConfigsLocked(currentTimestampNs, configKeys); resetConfigsLocked(currentTimestampNs); } else { // Still in search of the CP. Keep going. return; Loading Loading @@ -242,6 +257,7 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) { std::lock_guard<std::mutex> lock(mMetricsMutex); WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED); OnConfigUpdatedLocked(timestampNs, key, config); } Loading @@ -251,10 +267,6 @@ void StatsLogProcessor::OnConfigUpdatedLocked( sp<MetricsManager> newMetricsManager = new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { WriteDataToDiskLocked(it->first, CONFIG_UPDATED); } if (newMetricsManager->isConfigValid()) { mUidMap->OnConfigUpdated(key); if (newMetricsManager->shouldAddUidMapListener()) { Loading Loading @@ -419,6 +431,7 @@ void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) } } if (configKeysTtlExpired.size() > 0) { WriteDataToDiskLocked(CONFIG_RESET); resetConfigsLocked(timestampNs, configKeysTtlExpired); } } Loading @@ -427,7 +440,7 @@ void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) { std::lock_guard<std::mutex> lock(mMetricsMutex); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { WriteDataToDiskLocked(key, CONFIG_REMOVED); WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED); mMetricsManagers.erase(it); mUidMap->OnConfigRemoved(key); } Loading Loading @@ -474,9 +487,13 @@ void StatsLogProcessor::flushIfNecessaryLocked( } void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs, const DumpReportReason dumpReportReason) { if (mMetricsManagers.find(key) == mMetricsManagers.end()) { return; } ProtoOutputStream proto; onConfigMetricsReportLocked(key, getElapsedRealtimeNs(), onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/, false /* include strings */, dumpReportReason, &proto); string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, Loading @@ -491,14 +508,15 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, } void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason) { const int64_t timeNs = getElapsedRealtimeNs(); for (auto& pair : mMetricsManagers) { WriteDataToDiskLocked(pair.first, dumpReportReason); WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason); } } void StatsLogProcessor::WriteDataToDisk(bool isShutdown) { void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason) { std::lock_guard<std::mutex> lock(mMetricsMutex); WriteDataToDiskLocked(DEVICE_SHUTDOWN); WriteDataToDiskLocked(dumpReportReason); } void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) { Loading
cmds/statsd/src/StatsLogProcessor.h +21 −3 Original line number Diff line number Diff line Loading @@ -77,7 +77,10 @@ public: unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); /* Flushes data to disk. Data on memory will be gone after written to disk. */ void WriteDataToDisk(bool shutdown); void WriteDataToDisk(const DumpReportReason dumpReportReason); // Reset all configs. void resetConfigs(); inline sp<UidMap> getUidMap() { return mUidMap; Loading @@ -89,6 +92,13 @@ public: int64_t getLastReportTimeNs(const ConfigKey& key); inline void setPrintLogs(bool enabled) { #ifdef VERY_VERBOSE_PRINTING std::lock_guard<std::mutex> lock(mMetricsMutex); mPrintAllLogs = enabled; #endif } private: // For testing only. inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const { Loading Loading @@ -121,8 +131,9 @@ private: void OnConfigUpdatedLocked( const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config); void WriteDataToDiskLocked(DumpReportReason dumpReportReason); void WriteDataToDiskLocked(const ConfigKey& key, DumpReportReason dumpReportReason); void WriteDataToDiskLocked(const DumpReportReason dumpReportReason); void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs, const DumpReportReason dumpReportReason); void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, Loading @@ -141,6 +152,9 @@ private: // Handler over the isolated uid change event. void onIsolatedUidChangedEventLocked(const LogEvent& event); // Reset all configs. void resetConfigsLocked(const int64_t timestampNs); // Reset the specified configs. void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs); // Function used to send a broadcast so that receiver for the config key can call getData Loading @@ -164,6 +178,10 @@ private: long mLastPullerCacheClearTimeSec = 0; #ifdef VERY_VERBOSE_PRINTING bool mPrintAllLogs = false; #endif FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs); FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize); FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast); Loading
cmds/statsd/src/StatsService.cpp +32 −4 Original line number Diff line number Diff line Loading @@ -334,6 +334,10 @@ status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& if (!args[0].compare(String8("clear-puller-cache"))) { return cmd_clear_puller_cache(out); } if (!args[0].compare(String8("print-logs"))) { return cmd_print_logs(out, args); } } print_cmd_help(out); Loading Loading @@ -419,6 +423,9 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats clear-puller-cache\n"); fprintf(out, " Clear cached puller data.\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats print-logs\n"); fprintf(out, " Only works on eng build\n"); } status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) { Loading Loading @@ -659,7 +666,7 @@ status_t StatsService::cmd_print_uid_map(FILE* out, const Vector<String8>& args) status_t StatsService::cmd_write_data_to_disk(FILE* out) { fprintf(out, "Writing data to disk\n"); mProcessor->WriteDataToDisk(false); mProcessor->WriteDataToDisk(ADB_DUMP); return NO_ERROR; } Loading Loading @@ -738,6 +745,22 @@ status_t StatsService::cmd_clear_puller_cache(FILE* out) { } } status_t StatsService::cmd_print_logs(FILE* out, const Vector<String8>& args) { IPCThreadState* ipc = IPCThreadState::self(); VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); if (checkCallingPermission(String16(kPermissionDump))) { bool enabled = true; if (args.size() >= 2) { enabled = atoi(args[1].c_str()) != 0; } mProcessor->setPrintLogs(enabled); return NO_ERROR; } else { return PERMISSION_DENIED; } } Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version, const vector<String16>& app) { ENFORCE_UID(AID_SYSTEM); Loading Loading @@ -816,10 +839,10 @@ Status StatsService::systemRunning() { return Status::ok(); } Status StatsService::informDeviceShutdown(bool isShutdown) { Status StatsService::informDeviceShutdown() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::informDeviceShutdown"); mProcessor->WriteDataToDisk(isShutdown); mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN); return Status::ok(); } Loading Loading @@ -967,7 +990,12 @@ Status StatsService::unsetBroadcastSubscriber(int64_t configId, void StatsService::binderDied(const wp <IBinder>& who) { ALOGW("statscompanion service died"); StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec()); if (mProcessor != nullptr) { ALOGW("Reset statsd upon system server restars."); mProcessor->WriteDataToDisk(STATSCOMPANION_DIED); mProcessor->resetConfigs(); } mAnomalyAlarmMonitor->setStatsCompanionService(nullptr); mPeriodicAlarmMonitor->setStatsCompanionService(nullptr); SubscriberReporter::getInstance().setStatsCompanionService(nullptr); Loading
cmds/statsd/src/StatsService.h +6 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public: const vector<String16>& app); virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version); virtual Status informOnePackageRemoved(const String16& app, int32_t uid); virtual Status informDeviceShutdown(bool isShutdown); virtual Status informDeviceShutdown(); /** * Called right before we start processing events. Loading Loading @@ -220,6 +220,11 @@ private: */ status_t cmd_clear_puller_cache(FILE* out); /** * Print all stats logs received to logcat. */ status_t cmd_print_logs(FILE* out, const Vector<String8>& args); /** * Adds a configuration after checking permissions and obtaining UID from binder call. */ Loading