diff options
Diffstat (limited to 'cmds')
| -rw-r--r-- | cmds/incidentd/src/Section.cpp | 28 | ||||
| -rw-r--r-- | cmds/statsd/src/FieldValue.cpp | 27 | ||||
| -rw-r--r-- | cmds/statsd/src/FieldValue.h | 8 | ||||
| -rw-r--r-- | cmds/statsd/src/atoms.proto | 84 | ||||
| -rw-r--r-- | cmds/statsd/src/external/StatsCompanionServicePuller.cpp | 14 | ||||
| -rw-r--r-- | cmds/statsd/src/external/StatsPullerManager.cpp | 21 | ||||
| -rw-r--r-- | cmds/statsd/src/logd/LogEvent.cpp | 38 | ||||
| -rw-r--r-- | cmds/statsd/src/logd/LogEvent.h | 3 | ||||
| -rw-r--r-- | cmds/statsd/src/stats_log_util.cpp | 5 |
9 files changed, 197 insertions, 31 deletions
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 87799b38906c..cd48af95d08a 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -407,7 +407,19 @@ WorkerThreadSection::WorkerThreadSection(int id, const int64_t timeoutMs, bool u WorkerThreadSection::~WorkerThreadSection() {} +void sigpipe_handler(int signum) { + if (signum == SIGPIPE) { + ALOGE("Wrote to a broken pipe\n"); + } else { + ALOGE("Received unexpected signal: %d\n", signum); + } +} + static void* worker_thread_func(void* cookie) { + // Don't crash the service if we write to a closed pipe (which can happen if + // dumping times out). + signal(SIGPIPE, sigpipe_handler); + WorkerThreadData* data = (WorkerThreadData*)cookie; status_t err = data->section->BlockingCall(data->pipe.writeFd().get()); @@ -486,6 +498,7 @@ status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const { } } } + write_section_stats(requests->sectionStats(this->id), buffer); if (timedOut || buffer.timedOut()) { ALOGW("[%s] timed out", this->name.string()); @@ -773,7 +786,10 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const { } } gLastLogsRetrieved[mLogID] = lastTimestamp; - proto.flush(pipeWriteFd); + if (!proto.flush(pipeWriteFd) && errno == EPIPE) { + ALOGE("[%s] wrote to a broken pipe\n", this->name.string()); + return EPIPE; + } return NO_ERROR; } @@ -875,7 +891,7 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const { break; } if (cStatus != NO_ERROR) { - ALOGE("TombstoneSection '%s' child had an issue: %s\n", this->name.string(), strerror(-cStatus)); + ALOGE("[%s] child had an issue: %s\n", this->name.string(), strerror(-cStatus)); } auto dump = std::make_unique<char[]>(buffer.size()); @@ -894,7 +910,13 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const { dumpPipe.readFd().reset(); } - proto.flush(pipeWriteFd); + if (!proto.flush(pipeWriteFd) && errno == EPIPE) { + ALOGE("[%s] wrote to a broken pipe\n", this->name.string()); + if (err != NO_ERROR) { + return EPIPE; + } + } + return err; } diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index 7b6d29b905bd..fc1a61cac558 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -147,6 +147,9 @@ Value::Value(const Value& from) { case STRING: str_value = from.str_value; break; + case STORAGE: + storage_value = from.storage_value; + break; default: break; } @@ -164,6 +167,8 @@ std::string Value::toString() const { return std::to_string(double_value) + "[D]"; case STRING: return str_value + "[S]"; + case STORAGE: + return "bytes of size " + std::to_string(storage_value.size()) + "[ST]"; default: return "[UNKNOWN]"; } @@ -183,6 +188,8 @@ bool Value::operator==(const Value& that) const { return double_value == that.double_value; case STRING: return str_value == that.str_value; + case STORAGE: + return storage_value == that.storage_value; default: return false; } @@ -201,6 +208,8 @@ bool Value::operator!=(const Value& that) const { return double_value != that.double_value; case STRING: return str_value != that.str_value; + case STORAGE: + return storage_value != that.storage_value; default: return false; } @@ -220,6 +229,8 @@ bool Value::operator<(const Value& that) const { return double_value < that.double_value; case STRING: return str_value < that.str_value; + case STORAGE: + return storage_value < that.storage_value; default: return false; } @@ -239,6 +250,8 @@ bool Value::operator>(const Value& that) const { return double_value > that.double_value; case STRING: return str_value > that.str_value; + case STORAGE: + return storage_value > that.storage_value; default: return false; } @@ -258,6 +271,8 @@ bool Value::operator>=(const Value& that) const { return double_value >= that.double_value; case STRING: return str_value >= that.str_value; + case STORAGE: + return storage_value >= that.storage_value; default: return false; } @@ -274,6 +289,11 @@ Value Value::operator-(const Value& that) const { return v; } + if (type == STORAGE) { + ALOGE("Can't operate on storage value type"); + return v; + } + switch (type) { case INT: v.setInt(int_value - that.int_value); @@ -311,6 +331,9 @@ Value& Value::operator=(const Value& that) { case STRING: str_value = that.str_value; break; + case STORAGE: + storage_value = that.storage_value; + break; default: break; } @@ -326,6 +349,10 @@ Value& Value::operator+=(const Value& that) { ALOGE("Can't operate on string value type"); return *this; } + if (type == STORAGE) { + ALOGE("Can't operate on storage value type"); + return *this; + } switch (type) { case INT: diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h index b1b885ec4efa..77163f9d8619 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -32,7 +32,7 @@ const int32_t kLastBitMask = 0x80; const int32_t kClearLastBitDeco = 0x7f; const int32_t kClearAllPositionMatcherMask = 0xffff00ff; -enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING }; +enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE }; int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth); @@ -293,6 +293,11 @@ struct Value { type = STRING; } + Value(const std::vector<uint8_t>& v) { + storage_value = v; + type = STORAGE; + } + void setInt(int32_t v) { int_value = v; type = INT; @@ -320,6 +325,7 @@ struct Value { double double_value; }; std::string str_value; + std::vector<uint8_t> storage_value; Type type; diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 786e76c9d1cf..b8f19ee0d558 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -133,6 +133,9 @@ message Atom { VibratorStateChanged vibrator_state_changed = 84; DeferredJobStatsReported deferred_job_stats_reported = 85; ThermalThrottlingStateChanged thermal_throttling = 86; + FingerprintAcquired fingerprint_acquired = 87; + FingerprintAuthenticated fingerprint_authenticated = 88; + FingerprintErrorOccurred fingerprint_error_occurred = 89; } // Pulled events will start at field 10000. @@ -167,8 +170,9 @@ message Atom { DirectoryUsage directory_usage = 10026; AppSize app_size = 10027; CategorySize category_size = 10028; - android.service.procstats.ProcessStatsSectionProto proc_stats = 10029; BatteryVoltage battery_voltage = 10030; + NumFingerprints num_fingerprints = 10031; + ProcStats proc_stats = 10029; } // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above @@ -432,9 +436,9 @@ message BleScanStateChanged { * Logs reporting of a ble scan finding results. * * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java + * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java */ -// TODO: Consider changing to tracking per-scanner-id (log from AppScanStats). +// TODO: Consider also tracking per-scanner-id. message BleScanResultReceived { repeated AttributionNode attribution_node = 1; @@ -1832,6 +1836,60 @@ message GenericAtom { optional android.os.statsd.EventType event_id = 2; } +/** + * Logs when a fingerprint acquire event occurs. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java + */ +message FingerprintAcquired { + // The associated user. Eg: 0 for owners, 10+ for others. + // Defined in android/os/UserHandle.java + optional int32 user = 1; + // If this acquire is for a crypto fingerprint. + // e.g. Secure purchases, unlock password storage. + optional bool is_crypto = 2; +} + +/** + * Logs when a fingerprint authentication event occurs. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java + */ +message FingerprintAuthenticated { + // The associated user. Eg: 0 for owners, 10+ for others. + // Defined in android/os/UserHandle.java + optional int32 user = 1; + // If this authentication is for a crypto fingerprint. + // e.g. Secure purchases, unlock password storage. + optional bool is_crypto = 2; + // Whether or not this authentication was successful. + optional bool is_authenticated = 3; +} + +/** + * Logs when a fingerprint error occurs. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java + */ +message FingerprintErrorOccurred { + // The associated user. Eg: 0 for owners, 10+ for others. + // Defined in android/os/UserHandle.java + optional int32 user = 1; + // If this error is for a crypto fingerprint. + // e.g. Secure purchases, unlock password storage. + optional bool is_crypto = 2; + + enum Error { + UNKNOWN = 0; + LOCKOUT = 1; + PERMANENT_LOCKOUT = 2; + } + // The type of error. + optional Error error = 3; +} ////////////////////////////////////////////////////////////////////// // Pulled atoms below this line // ////////////////////////////////////////////////////////////////////// @@ -2408,3 +2466,23 @@ message CategorySize { // Uses System.currentTimeMillis(), which is wall clock time. optional int64 cache_time_millis = 3; } + +/** + * Pulls the number of fingerprints for each user. + * + * Pulled from StatsCompanionService, which queries FingerprintManager. + */ +message NumFingerprints { + // The associated user. Eg: 0 for owners, 10+ for others. + // Defined in android/os/UserHandle.java + optional int32 user = 1; + // Number of fingerprints registered to that user. + optional int32 num_fingerprints = 2; +} + +/** + * Pulled from ProcessStatsService.java + */ +message ProcStats { + optional android.service.procstats.ProcessStatsSectionProto proc_stats_section = 1; +} diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp index d953f50bb5d8..6d7bba028974 100644 --- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp +++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp @@ -36,8 +36,6 @@ namespace android { namespace os { namespace statsd { -const int kLogMsgHeaderSize = 28; - // The reading and parsing are implemented in Java. It is not difficult to port over. But for now // let StatsCompanionService handle that and send the data back. StatsCompanionServicePuller::StatsCompanionServicePuller(int tagId) : StatsPuller(tagId) { @@ -56,20 +54,12 @@ bool StatsCompanionServicePuller::PullInternal(vector<shared_ptr<LogEvent> >* da vector<StatsLogEventWrapper> returned_value; Status status = statsCompanionServiceCopy->pullData(mTagId, &returned_value); if (!status.isOk()) { - ALOGW("error pulling for %d", mTagId); + ALOGW("StatsCompanionServicePuller::pull failed to pull for %d", mTagId); return false; } data->clear(); - int32_t timestampSec = getWallClockSec(); for (const StatsLogEventWrapper& it : returned_value) { - log_msg tmp; - tmp.entry_v1.len = it.bytes.size(); - // Manually set the header size to 28 bytes to match the pushed log events. - tmp.entry.hdr_size = kLogMsgHeaderSize; - tmp.entry_v1.sec = timestampSec; - // And set the received bytes starting after the 28 bytes reserved for header. - std::copy(it.bytes.begin(), it.bytes.end(), tmp.buf + kLogMsgHeaderSize); - data->push_back(make_shared<LogEvent>(tmp)); + data->push_back(make_shared<LogEvent>(it)); } VLOG("StatsCompanionServicePuller::pull succeeded for %d", mTagId); return true; diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 745ff74c2623..5a0172b22301 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -195,28 +195,25 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { new StatsCompanionServicePuller(android::util::LOOPER_STATS)}}, // Disk Stats {android::util::DISK_STATS, - {{}, - {}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::DISK_STATS)}}, + {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DISK_STATS)}}, // Directory usage {android::util::DIRECTORY_USAGE, - {{}, - {}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}}, + {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}}, // Size of app's code, data, and cache {android::util::APP_SIZE, - {{}, - {}, - 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::APP_SIZE)}}, + {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::APP_SIZE)}}, // Size of specific categories of files. Eg. Music. {android::util::CATEGORY_SIZE, {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, + // Number of fingerprints registered to each user. + {android::util::NUM_FINGERPRINTS, + {{}, + {}, + 1 * NS_PER_SEC, + new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS)}}, }; StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) { diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index cf04ee3e17ec..f9f1b387279a 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -41,6 +41,44 @@ LogEvent::LogEvent(log_msg& msg) { } } +LogEvent::LogEvent(const StatsLogEventWrapper& statsLogEventWrapper) { + mTagId = statsLogEventWrapper.getTagId(); + mLogdTimestampNs = statsLogEventWrapper.getWallClockTimeNs(); + mElapsedTimestampNs = statsLogEventWrapper.getElapsedRealTimeNs(); + mLogUid = 0; + for (int i = 0; i < (int)statsLogEventWrapper.getElements().size(); i++) { + Field field(statsLogEventWrapper.getTagId(), getSimpleField(i + 1)); + switch (statsLogEventWrapper.getElements()[i].type) { + case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::INT: + mValues.push_back( + FieldValue(field, Value(statsLogEventWrapper.getElements()[i].int_value))); + break; + case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::LONG: + mValues.push_back( + FieldValue(field, Value(statsLogEventWrapper.getElements()[i].long_value))); + break; + case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::FLOAT: + mValues.push_back(FieldValue( + field, Value(statsLogEventWrapper.getElements()[i].float_value))); + break; + case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::DOUBLE: + mValues.push_back(FieldValue( + field, Value(statsLogEventWrapper.getElements()[i].double_value))); + break; + case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STRING: + mValues.push_back( + FieldValue(field, Value(statsLogEventWrapper.getElements()[i].str_value))); + break; + case android::os::StatsLogValue::STATS_LOG_VALUE_TYPE::STORAGE: + mValues.push_back(FieldValue( + field, Value(statsLogEventWrapper.getElements()[i].storage_value))); + break; + default: + break; + } + } +} + LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) { mLogdTimestampNs = wallClockTimestampNs; mTagId = tagId; diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 2ee6bdf7c7ba..9ef0bf469c14 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -18,6 +18,7 @@ #include "FieldValue.h" +#include <android/os/StatsLogEventWrapper.h> #include <android/util/ProtoOutputStream.h> #include <log/log_event_list.h> #include <log/log_read.h> @@ -61,6 +62,8 @@ public: */ explicit LogEvent(log_msg& msg); + explicit LogEvent(const StatsLogEventWrapper& statsLogEventWrapper); + /** * Constructs a LogEvent with synthetic data for testing. Must call init() before reading. */ diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index a0ab3e46e719..805e5833c1eb 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -322,6 +322,11 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size case STRING: protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value); break; + case STORAGE: + protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum, + (const char*)dim.mValue.storage_value.data(), + dim.mValue.storage_value.size()); + break; default: break; } |