summaryrefslogtreecommitdiff
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/incidentd/src/Section.cpp28
-rw-r--r--cmds/statsd/src/FieldValue.cpp27
-rw-r--r--cmds/statsd/src/FieldValue.h8
-rw-r--r--cmds/statsd/src/atoms.proto84
-rw-r--r--cmds/statsd/src/external/StatsCompanionServicePuller.cpp14
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp21
-rw-r--r--cmds/statsd/src/logd/LogEvent.cpp38
-rw-r--r--cmds/statsd/src/logd/LogEvent.h3
-rw-r--r--cmds/statsd/src/stats_log_util.cpp5
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;
}