diff options
author | Chenjie Yu <cjyu@google.com> | 2018-09-14 15:54:59 -0700 |
---|---|---|
committer | Chenjie Yu <cjyu@google.com> | 2018-09-18 16:29:52 -0700 |
commit | 12e5e6755f0aca0fbd03419f6b11987c2d8be3c8 (patch) | |
tree | 3d5449ee015d4ba8bdf0cf3fe4110b95df66cb66 | |
parent | cbf34a2318cf633c1b47601edd9f888d1d36eacb (diff) |
use custom Parcel format to pull data
When statsd pulls data from StatsCompanionService, the data is put into
log_msg format on java side and expanded into LogEvent on cpp side.
There is a lot of dependency on log_msg and liblog to add new types.
There is pending bug to rewrite thta part of the code in statsd to
completely rid the legacy of logd and liblog. But that may not happen
soon.
Now we can support new storage type.
Also no need to specify number of fields in StatsLogEventWrapper cstr,
which is a source of bug in P.
Bug: 115775035
Test: manual test and cts test
Change-Id: Id1f0b033885da6f3bcebe043968061821db48f35
-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 | 9 | ||||
-rw-r--r-- | cmds/statsd/src/external/StatsCompanionServicePuller.cpp | 14 | ||||
-rw-r--r-- | cmds/statsd/src/external/StatsPullerManager.cpp | 15 | ||||
-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 | ||||
-rw-r--r-- | core/java/android/os/StatsLogEventWrapper.java | 148 | ||||
-rw-r--r-- | libs/services/include/android/os/StatsLogEventWrapper.h | 70 | ||||
-rw-r--r-- | libs/services/src/os/StatsLogEventWrapper.cpp | 65 | ||||
-rw-r--r-- | services/core/java/com/android/server/stats/StatsCompanionService.java | 326 |
12 files changed, 487 insertions, 241 deletions
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 13ae41df63f1..b8f19ee0d558 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -170,9 +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 @@ -2479,3 +2479,10 @@ message NumFingerprints { // 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 c23d65e2d146..5a0172b22301 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -195,22 +195,13 @@ 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, {{}, 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; } diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java index b13bcac699ed..051ab75c857c 100644 --- a/core/java/android/os/StatsLogEventWrapper.java +++ b/core/java/android/os/StatsLogEventWrapper.java @@ -15,8 +15,10 @@ */ package android.os; -import java.io.ByteArrayOutputStream; -import java.nio.charset.StandardCharsets; +import android.util.Slog; + +import java.util.ArrayList; +import java.util.List; /** * Wrapper class for sending data from Android OS to StatsD. @@ -24,39 +26,28 @@ import java.nio.charset.StandardCharsets; * @hide */ public final class StatsLogEventWrapper implements Parcelable { - private ByteArrayOutputStream mStorage = new ByteArrayOutputStream(); + static final boolean DEBUG = false; + static final String TAG = "StatsLogEventWrapper"; - // Below are constants copied from log/log.h - private static final int EVENT_TYPE_INT = 0; /* int32_t */ - private static final int EVENT_TYPE_LONG = 1; /* int64_t */ - private static final int EVENT_TYPE_STRING = 2; - private static final int EVENT_TYPE_LIST = 3; - private static final int EVENT_TYPE_FLOAT = 4; + // Keep in sync with FieldValue.h enums + private static final int EVENT_TYPE_UNKNOWN = 0; + private static final int EVENT_TYPE_INT = 1; /* int32_t */ + private static final int EVENT_TYPE_LONG = 2; /* int64_t */ + private static final int EVENT_TYPE_FLOAT = 3; + private static final int EVENT_TYPE_DOUBLE = 4; + private static final int EVENT_TYPE_STRING = 5; + private static final int EVENT_TYPE_STORAGE = 6; - // Keep this in sync with system/core/logcat/event.logtags - private static final int STATS_BUFFER_TAG_ID = 1937006964; - /** - * Creates a log_event that is binary-encoded as implemented in - * system/core/liblog/log_event_list.c; this allows us to use the same parsing logic in statsd - * for pushed and pulled data. The write* methods must be called in the same order as their - * field number. There is no checking that the correct number of write* methods is called. - * We also write an END_LIST character before beginning to write to parcel, but this END_LIST - * may be unnecessary. - * - * @param tag The integer representing the tag for this event. - * @param fields The number of fields specified in this event. - */ - public StatsLogEventWrapper(long elapsedNanos, int tag, int fields) { - // Write four bytes from tag, starting with least-significant bit. - // For pulled data, this tag number is not really used. We use the same tag number as - // pushed ones to be consistent. - write4Bytes(STATS_BUFFER_TAG_ID); - mStorage.write(EVENT_TYPE_LIST); // This is required to start the log entry. - mStorage.write(fields + 2); // Indicate number of elements in this list. +1 for the tag - // The first element is the elapsed realtime. - writeLong(elapsedNanos); - // The second element is the real atom tag number - writeInt(tag); + List<Integer> mTypes = new ArrayList<>(); + List<Object> mValues = new ArrayList<>(); + int mTag; + long mElapsedTimeNs; + long mWallClockTimeNs; + + public StatsLogEventWrapper(int tag, long elapsedTimeNs, long wallClockTimeNs) { + this.mTag = tag; + this.mElapsedTimeNs = elapsedTimeNs; + this.mWallClockTimeNs = wallClockTimeNs; } /** @@ -79,69 +70,80 @@ public final class StatsLogEventWrapper implements Parcelable { } }; - private void write4Bytes(int val) { - mStorage.write(val); - mStorage.write(val >>> 8); - mStorage.write(val >>> 16); - mStorage.write(val >>> 24); - } - - private void write8Bytes(long val) { - write4Bytes((int) (val & 0xFFFFFFFF)); // keep the lowe 32-bits - write4Bytes((int) (val >>> 32)); // Write the high 32-bits. - } - - /** - * Adds 32-bit integer to output. - */ public void writeInt(int val) { - mStorage.write(EVENT_TYPE_INT); - write4Bytes(val); + mTypes.add(EVENT_TYPE_INT); + mValues.add(val); } - /** - * Adds 64-bit long to output. - */ public void writeLong(long val) { - mStorage.write(EVENT_TYPE_LONG); - write8Bytes(val); + mTypes.add(EVENT_TYPE_LONG); + mValues.add(val); } /** - * Adds a 4-byte floating point value to output. + * Write a string value. */ + public void writeString(String val) { + mTypes.add(EVENT_TYPE_STRING); + // use empty string for null + mValues.add(val == null ? "" : val); + } + public void writeFloat(float val) { - int v = Float.floatToIntBits(val); - mStorage.write(EVENT_TYPE_FLOAT); - write4Bytes(v); + mTypes.add(EVENT_TYPE_FLOAT); + mValues.add(val); } /** - * Adds a string to the output. + * Write a storage value. */ - public void writeString(String val) { - mStorage.write(EVENT_TYPE_STRING); - write4Bytes(val.length()); - byte[] bytes = val.getBytes(StandardCharsets.UTF_8); - mStorage.write(bytes, 0, bytes.length); + public void writeStorage(byte[] val) { + mTypes.add(EVENT_TYPE_STORAGE); + mValues.add(val); } - /** - * Adds a boolean by adding either a 1 or 0 to the output. - */ public void writeBoolean(boolean val) { - int toWrite = val ? 1 : 0; - mStorage.write(EVENT_TYPE_INT); - write4Bytes(toWrite); + mTypes.add(EVENT_TYPE_INT); + mValues.add(val ? 1 : 0); } /** * Writes the stored fields to a byte array. Will first write a new-line character to denote * END_LIST before writing contents to byte array. */ + public void writeToParcel(Parcel out, int flags) { - mStorage.write(10); // new-line character is same as END_LIST - out.writeByteArray(mStorage.toByteArray()); + if (DEBUG) { + Slog.d(TAG, + "Writing " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs + " and " + + mTypes.size() + " elements."); + } + out.writeInt(mTag); + out.writeLong(mElapsedTimeNs); + out.writeLong(mWallClockTimeNs); + out.writeInt(mTypes.size()); + for (int i = 0; i < mTypes.size(); i++) { + out.writeInt(mTypes.get(i)); + switch (mTypes.get(i)) { + case EVENT_TYPE_INT: + out.writeInt((int) mValues.get(i)); + break; + case EVENT_TYPE_LONG: + out.writeLong((long) mValues.get(i)); + break; + case EVENT_TYPE_FLOAT: + out.writeFloat((float) mValues.get(i)); + break; + case EVENT_TYPE_STRING: + out.writeString((String) mValues.get(i)); + break; + case EVENT_TYPE_STORAGE: + out.writeByteArray((byte[]) mValues.get(i)); + break; + default: + break; + } + } } /** diff --git a/libs/services/include/android/os/StatsLogEventWrapper.h b/libs/services/include/android/os/StatsLogEventWrapper.h index 255619c6226c..52cb75e8e639 100644 --- a/libs/services/include/android/os/StatsLogEventWrapper.h +++ b/libs/services/include/android/os/StatsLogEventWrapper.h @@ -25,6 +25,58 @@ namespace android { namespace os { +/** + * A wrapper for a union type to contain multiple types of values. + * + */ +struct StatsLogValue { + // Keep in sync with FieldValue.h + enum STATS_LOG_VALUE_TYPE { + UNKNOWN = 0, + INT = 1, + LONG = 2, + FLOAT = 3, + DOUBLE = 4, + STRING = 5, + STORAGE = 6 + }; + + StatsLogValue() : type(UNKNOWN) {} + + StatsLogValue(int32_t v) { + int_value = v; + type = INT; + } + + StatsLogValue(int64_t v) { + long_value = v; + type = LONG; + } + + StatsLogValue(float v) { + float_value = v; + type = FLOAT; + } + + StatsLogValue(const std::string& v) { + str_value = v; + type = STRING; + } + + void setType(STATS_LOG_VALUE_TYPE t) { type = t; } + + union { + int32_t int_value; + int64_t long_value; + float float_value; + double double_value; + }; + std::string str_value; + std::vector<uint8_t> storage_value; + + STATS_LOG_VALUE_TYPE type; +}; + // Represents a parcelable object. Only used to send data from Android OS to statsd. class StatsLogEventWrapper : public android::Parcelable { public: @@ -36,8 +88,22 @@ class StatsLogEventWrapper : public android::Parcelable { android::status_t readFromParcel(const android::Parcel* in); - // These are public for ease of conversion. - std::vector<uint8_t> bytes; + int getTagId() const { return mTagId; } + + int64_t getElapsedRealTimeNs() const { return mElapsedRealTimeNs; } + + int64_t getWallClockTimeNs() const { return mWallClockTimeNs; } + + std::vector<StatsLogValue> getElements() const { return mElements; } + + private: + int mTagId; + + int64_t mElapsedRealTimeNs; + + int64_t mWallClockTimeNs; + + std::vector<StatsLogValue> mElements; }; } // Namespace os } // Namespace android diff --git a/libs/services/src/os/StatsLogEventWrapper.cpp b/libs/services/src/os/StatsLogEventWrapper.cpp index 8b3aa9ab4257..04c4629b5432 100644 --- a/libs/services/src/os/StatsLogEventWrapper.cpp +++ b/libs/services/src/os/StatsLogEventWrapper.cpp @@ -32,13 +32,70 @@ namespace os { StatsLogEventWrapper::StatsLogEventWrapper(){}; status_t StatsLogEventWrapper::writeToParcel(Parcel* out) const { - out->writeByteVector(bytes); - return ::android::NO_ERROR; + // Implement me if desired. We don't currently use this. + ALOGE( + "Cannot do c++ StatsLogEventWrapper.writeToParcel(); it is not " + "implemented."); + (void)out; // To prevent compile error of unused parameter 'in' + return UNKNOWN_ERROR; }; status_t StatsLogEventWrapper::readFromParcel(const Parcel* in) { - in->readByteVector(&bytes); - return ::android::NO_ERROR; + status_t res = OK; + if (in == NULL) { + ALOGE("statsd received parcel argument was NULL."); + return BAD_VALUE; + } + if ((res = in->readInt32(&mTagId)) != OK) { + ALOGE("statsd could not read tagId from parcel"); + return res; + } + if ((res = in->readInt64(&mElapsedRealTimeNs)) != OK) { + ALOGE("statsd could not read elapsed real time from parcel"); + return res; + } + if ((res = in->readInt64(&mWallClockTimeNs)) != OK) { + ALOGE("statsd could not read wall clock time from parcel"); + return res; + } + int dataSize = 0; + if ((res = in->readInt32(&dataSize)) != OK) { + ALOGE("statsd could not read data size from parcel"); + return res; + } + if (mTagId <= 0 || mElapsedRealTimeNs <= 0 || mWallClockTimeNs <= 0 || + dataSize <= 0) { + ALOGE("statsd received invalid parcel"); + return BAD_VALUE; + } + + for (int i = 0; i < dataSize; i++) { + int type = in->readInt32(); + switch (type) { + case StatsLogValue::INT: + mElements.push_back(StatsLogValue(in->readInt32())); + break; + case StatsLogValue::LONG: + mElements.push_back(StatsLogValue(in->readInt64())); + break; + case StatsLogValue::STRING: + mElements.push_back( + StatsLogValue(std::string(String8(in->readString16()).string()))); + break; + case StatsLogValue::FLOAT: + mElements.push_back(StatsLogValue(in->readFloat())); + break; + case StatsLogValue::STORAGE: + mElements.push_back(StatsLogValue()); + mElements.back().setType(StatsLogValue::STORAGE); + in->readByteVector(&(mElements.back().storage_value)); + break; + default: + ALOGE("unrecognized data type: %d", type); + return BAD_TYPE; + } + } + return NO_ERROR; }; } // Namespace os diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 444ac2c041d5..5e3fe0a119ff 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -123,7 +123,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { public static final String CONFIG_DIR = "/data/misc/stats-service"; static final String TAG = "StatsCompanionService"; - static final boolean DEBUG = false; + static final boolean DEBUG = true; public static final int CODE_DATA_BROADCAST = 1; public static final int CODE_SUBSCRIBER_BROADCAST = 1; @@ -254,34 +254,38 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { @Override public void sendSubscriberBroadcast(IBinder intentSenderBinder, long configUid, long configKey, - long subscriptionId, long subscriptionRuleId, - String[] cookies, - StatsDimensionsValue dimensionsValue) { + long subscriptionId, long subscriptionRuleId, String[] cookies, + StatsDimensionsValue dimensionsValue) { enforceCallingPermission(); IntentSender intentSender = new IntentSender(intentSenderBinder); - Intent intent = new Intent() - .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid) - .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configKey) - .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId) - .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID, subscriptionRuleId) - .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue); + Intent intent = + new Intent() + .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid) + .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configKey) + .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId) + .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID, subscriptionRuleId) + .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue); ArrayList<String> cookieList = new ArrayList<>(cookies.length); - for (String cookie : cookies) { cookieList.add(cookie); } + for (String cookie : cookies) { + cookieList.add(cookie); + } intent.putStringArrayListExtra( StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList); if (DEBUG) { - Slog.d(TAG, String.format( - "Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}", - configUid, configKey, subscriptionId, subscriptionRuleId, - Arrays.toString(cookies), dimensionsValue)); + Slog.d(TAG, + String.format("Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}", + configUid, configKey, subscriptionId, subscriptionRuleId, + Arrays.toString(cookies), + dimensionsValue)); } try { intentSender.sendIntent(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null); } catch (IntentSender.SendIntentException e) { - Slog.w(TAG, "Unable to send using IntentSender from uid " + configUid - + "; presumably it had been cancelled."); + Slog.w(TAG, + "Unable to send using IntentSender from uid " + configUid + + "; presumably it had been cancelled."); } } @@ -318,7 +322,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Add in all the apps for every user/profile. for (UserInfo profile : users) { List<PackageInfo> pi = - pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id); + pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id); for (int j = 0; j < pi.size(); j++) { if (pi.get(j).applicationInfo != null) { uids.add(pi.get(j).applicationInfo.uid); @@ -403,8 +407,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { public final static class PullingAlarmListener implements OnAlarmListener { @Override public void onAlarm() { - if (DEBUG) + if (DEBUG) { Slog.d(TAG, "Time to poll something."); + } synchronized (sStatsdLock) { if (sStatsd == null) { Slog.w(TAG, "Could not access statsd to inform it of pulling alarm firing."); @@ -423,8 +428,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { public final static class PeriodicAlarmListener implements OnAlarmListener { @Override public void onAlarm() { - if (DEBUG) + if (DEBUG) { Slog.d(TAG, "Time to trigger periodic alarm."); + } synchronized (sStatsdLock) { if (sStatsd == null) { Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing."); @@ -460,7 +466,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return; } try { - sStatsd.informDeviceShutdown(); + sStatsd.informDeviceShutdown(); } catch (Exception e) { Slog.w(TAG, "Failed to inform statsd of a shutdown event.", e); } @@ -499,9 +505,11 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { @Override // Binder call public void setAlarmForSubscriberTriggering(long timestampMs) { enforceCallingPermission(); - if (DEBUG) - Slog.d(TAG, "Setting periodic alarm in about " + - (timestampMs - SystemClock.elapsedRealtime())); + if (DEBUG) { + Slog.d(TAG, + "Setting periodic alarm in about " + (timestampMs + - SystemClock.elapsedRealtime())); + } final long callingToken = Binder.clearCallingIdentity(); try { // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will @@ -516,8 +524,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { @Override // Binder call public void cancelAlarmForSubscriberTriggering() { enforceCallingPermission(); - if (DEBUG) + if (DEBUG) { Slog.d(TAG, "Cancelling periodic alarm"); + } final long callingToken = Binder.clearCallingIdentity(); try { mAlarmManager.cancel(mPeriodicAlarmListener); @@ -547,8 +556,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { @Override // Binder call public void cancelPullingAlarm() { enforceCallingPermission(); - if (DEBUG) + if (DEBUG) { Slog.d(TAG, "Cancelling pulling alarm"); + } final long callingToken = Binder.clearCallingIdentity(); try { mAlarmManager.cancel(mPullingAlarmListener); @@ -561,10 +571,11 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG) { int size = stats.size(); long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + long wallClockNanos = SystemClock.currentTimeMicro() * 1000L; NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling for (int j = 0; j < size; j++) { stats.getValues(j, entry); - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tag, withFGBG ? 6 : 5); + StatsLogEventWrapper e = new StatsLogEventWrapper(tag, elapsedNanos, wallClockNanos); e.writeInt(entry.uid); if (withFGBG) { e.writeInt(entry.set); @@ -640,14 +651,15 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return null; } - private void pullKernelWakelock(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullKernelWakelock( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats); - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { String name = ent.getKey(); KernelWakelockStats.Entry kws = ent.getValue(); - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 4); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeString(name); e.writeInt(kws.mCount); e.writeInt(kws.mVersion); @@ -656,7 +668,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullWifiBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullWifiBytesTransfer( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { long token = Binder.clearCallingIdentity(); try { // TODO: Consider caching the following call to get BatteryStatsInternal. @@ -668,7 +682,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { NetworkStatsFactory nsf = new NetworkStatsFactory(); // Combine all the metrics per Uid into one record. NetworkStats stats = - nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null) + nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, + null) .groupedByUid(); addNetworkStats(tagId, pulledData, stats, false); } catch (java.io.IOException e) { @@ -678,7 +693,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullWifiBytesTransferByFgBg(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullWifiBytesTransferByFgBg( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { long token = Binder.clearCallingIdentity(); try { BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); @@ -688,7 +705,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } NetworkStatsFactory nsf = new NetworkStatsFactory(); NetworkStats stats = rollupNetworkStatsByFGBG( - nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)); + nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, + null)); addNetworkStats(tagId, pulledData, stats, true); } catch (java.io.IOException e) { Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e); @@ -697,7 +715,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullMobileBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullMobileBytesTransfer( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { long token = Binder.clearCallingIdentity(); try { BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); @@ -708,7 +728,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { NetworkStatsFactory nsf = new NetworkStatsFactory(); // Combine all the metrics per Uid into one record. NetworkStats stats = - nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null) + nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, + null) .groupedByUid(); addNetworkStats(tagId, pulledData, stats, false); } catch (java.io.IOException e) { @@ -718,12 +739,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullBluetoothBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullBluetoothBytesTransfer( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { BluetoothActivityEnergyInfo info = pullBluetoothData(); - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); if (info.getUidTraffic() != null) { for (UidTraffic traffic : info.getUidTraffic()) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, + wallClockNanos); e.writeInt(traffic.getUid()); e.writeLong(traffic.getRxBytes()); e.writeLong(traffic.getTxBytes()); @@ -732,7 +755,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullMobileBytesTransferByFgBg(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullMobileBytesTransferByFgBg( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { long token = Binder.clearCallingIdentity(); try { BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); @@ -742,7 +767,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } NetworkStatsFactory nsf = new NetworkStatsFactory(); NetworkStats stats = rollupNetworkStatsByFGBG( - nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)); + nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, + null)); addNetworkStats(tagId, pulledData, stats, true); } catch (java.io.IOException e) { Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e); @@ -751,13 +777,15 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullCpuTimePerFreq(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullCpuTimePerFreq( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute(); if (clusterTimeMs != null) { for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, + wallClockNanos); e.writeInt(cluster); e.writeInt(speed); e.writeLong(clusterTimeMs[speed]); @@ -767,10 +795,11 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullKernelUidCpuTime(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullKernelUidCpuTime( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { mKernelUidCpuTimeReader.readAbsolute((uid, userTimeUs, systemTimeUs) -> { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(uid); e.writeLong(userTimeUs); e.writeLong(systemTimeUs); @@ -778,12 +807,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { }); } - private void pullKernelUidCpuFreqTime(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullKernelUidCpuFreqTime( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { mKernelUidCpuFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> { for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) { - if(cpuFreqTimeMs[freqIndex] != 0) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + if (cpuFreqTimeMs[freqIndex] != 0) { + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, + wallClockNanos); e.writeInt(uid); e.writeInt(freqIndex); e.writeLong(cpuFreqTimeMs[freqIndex]); @@ -793,11 +824,13 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { }); } - private void pullKernelUidCpuClusterTime(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullKernelUidCpuClusterTime( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { mKernelUidCpuClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> { for (int i = 0; i < cpuClusterTimesMs.length; i++) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, + wallClockNanos); e.writeInt(uid); e.writeInt(i); e.writeLong(cpuClusterTimesMs[i]); @@ -806,17 +839,20 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { }); } - private void pullKernelUidCpuActiveTime(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullKernelUidCpuActiveTime( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { mKernelUidCpuActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(uid); - e.writeLong((long)cpuActiveTimesMs); + e.writeLong((long) cpuActiveTimesMs); pulledData.add(e); }); } - private void pullWifiActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullWifiActivityInfo( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { long token = Binder.clearCallingIdentity(); if (mWifiManager == null) { mWifiManager = @@ -827,7 +863,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi"); mWifiManager.requestActivityInfo(wifiReceiver); final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); - StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, + wallClockNanos); e.writeLong(wifiInfo.getTimeStamp()); e.writeInt(wifiInfo.getStackState()); e.writeLong(wifiInfo.getControllerTxTimeMillis()); @@ -836,14 +873,18 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { e.writeLong(wifiInfo.getControllerEnergyUsed()); pulledData.add(e); } catch (RemoteException e) { - Slog.e(TAG, "Pulling wifiManager for wifi controller activity energy info has error", e); + Slog.e(TAG, + "Pulling wifiManager for wifi controller activity energy info has error", + e); } finally { Binder.restoreCallingIdentity(token); } } } - private void pullModemActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullModemActivityInfo( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { long token = Binder.clearCallingIdentity(); if (mTelephony == null) { mTelephony = TelephonyManager.from(mContext); @@ -852,7 +893,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony"); mTelephony.requestModemActivityInfo(modemReceiver); final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver); - StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 10); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(modemInfo.getTimestamp()); e.writeLong(modemInfo.getSleepTimeMillis()); e.writeLong(modemInfo.getIdleTimeMillis()); @@ -867,9 +908,11 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullBluetoothActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullBluetoothActivityInfo( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { BluetoothActivityEnergyInfo info = pullBluetoothData(); - StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(info.getTimeStamp()); e.writeInt(info.getBluetoothStackState()); e.writeLong(info.getControllerTxTimeMillis()); @@ -882,7 +925,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private synchronized BluetoothActivityEnergyInfo pullBluetoothData() { final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { - SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver("bluetooth"); + SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver( + "bluetooth"); adapter.requestControllerActivityEnergyInfo(bluetoothReceiver); return awaitControllerInfo(bluetoothReceiver); } else { @@ -891,25 +935,29 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullSystemElapsedRealtime(int tagId, List<StatsLogEventWrapper> pulledData) { - StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1); + private void pullSystemElapsedRealtime( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(SystemClock.elapsedRealtime()); pulledData.add(e); } - private void pullSystemUpTime(int tagId, List<StatsLogEventWrapper> pulledData) { - StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1); + private void pullSystemUpTime(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(SystemClock.uptimeMillis()); pulledData.add(e); } - private void pullProcessMemoryState(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullProcessMemoryState( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { List<ProcessMemoryState> processMemoryStates = - LocalServices.getService(ActivityManagerInternal.class) - .getMemoryStateForProcesses(); - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + LocalServices.getService( + ActivityManagerInternal.class).getMemoryStateForProcesses(); for (ProcessMemoryState processMemoryState : processMemoryStates) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 8 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(processMemoryState.uid); e.writeString(processMemoryState.processName); e.writeInt(processMemoryState.oomScore); @@ -922,7 +970,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullBinderCallsStats(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullBinderCallsStats( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { BinderCallsStatsService.Internal binderStats = LocalServices.getService(BinderCallsStatsService.Internal.class); if (binderStats == null) { @@ -931,9 +981,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { List<ExportedCallStat> callStats = binderStats.getExportedCallStats(); binderStats.reset(); - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (ExportedCallStat callStat : callStats) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 13 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(callStat.uid); e.writeString(callStat.className); e.writeString(callStat.methodName); @@ -951,7 +1000,9 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullBinderCallsStatsExceptions(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullBinderCallsStatsExceptions( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { BinderCallsStatsService.Internal binderStats = LocalServices.getService(BinderCallsStatsService.Internal.class); if (binderStats == null) { @@ -961,16 +1012,16 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats(); // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we // can reset the exception stats. - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (Entry<String, Integer> entry : exceptionStats.entrySet()) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeString(entry.getKey()); e.writeInt(entry.getValue()); pulledData.add(e); } } - private void pullLooperStats(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { LooperStats looperStats = LocalServices.getService(LooperStats.class); if (looperStats == null) { return; @@ -978,9 +1029,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { List<LooperStats.ExportedEntry> entries = looperStats.getEntries(); looperStats.reset(); - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (LooperStats.ExportedEntry entry : entries) { - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 10 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(1000); // uid collection not implemented yet e.writeString(entry.handlerClassName); e.writeString(entry.threadName); @@ -995,7 +1045,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullDiskStats(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { // Run a quick-and-dirty performance test: write 512 bytes byte[] junk = new byte[512]; for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes @@ -1042,41 +1093,40 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } // Add info pulledData. - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(latency); e.writeBoolean(fileBased); e.writeInt(writeSpeed); pulledData.add(e); } - private void pullDirectoryUsage(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath()); StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath()); StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath()); - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA); e.writeLong(statFsData.getAvailableBytes()); e.writeLong(statFsData.getTotalBytes()); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE); e.writeLong(statFsCache.getAvailableBytes()); e.writeLong(statFsCache.getTotalBytes()); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM); e.writeLong(statFsSystem.getAvailableBytes()); e.writeLong(statFsSystem.getTotalBytes()); pulledData.add(e); } - private void pullAppSize(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullAppSize(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { try { String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); JSONObject json = new JSONObject(jsonStr); @@ -1094,7 +1144,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } for (int i = 0; i < length; i++) { StatsLogEventWrapper e = - new StatsLogEventWrapper(elapsedNanos, tagId, 5 /* fields */); + new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeString(pkg_names.getString(i)); e.writeLong(app_sizes.optLong(i, -1L)); e.writeLong(app_data_sizes.optLong(i, -1L)); @@ -1107,62 +1157,62 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullCategorySize(int tagId, List<StatsLogEventWrapper> pulledData) { - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + private void pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { try { String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); JSONObject json = new JSONObject(jsonStr); long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L); - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE); e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE); e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE); e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS); e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS); e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO); e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS); e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM); e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L)); e.writeLong(cacheTime); pulledData.add(e); - e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER); e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L)); e.writeLong(cacheTime); @@ -1172,7 +1222,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullNumFingerprints(int tagId, List<StatsLogEventWrapper> pulledData) { + private void pullNumFingerprints(int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class); if (fingerprintManager == null) { return; @@ -1182,11 +1233,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return; } final long token = Binder.clearCallingIdentity(); - long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (UserInfo user : userManager.getUsers()) { final int userId = user.getUserHandle().getIdentifier(); final int numFingerprints = fingerprintManager.getEnrolledFingerprints(userId).size(); - StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(userId); e.writeInt(numFingerprints); pulledData.add(e); @@ -1200,108 +1250,111 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { @Override // Binder call public StatsLogEventWrapper[] pullData(int tagId) { enforceCallingPermission(); - if (DEBUG) + if (DEBUG) { Slog.d(TAG, "Pulling " + tagId); + } List<StatsLogEventWrapper> ret = new ArrayList<>(); + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + long wallClockNanos = SystemClock.currentTimeMicro() * 1000L; switch (tagId) { case StatsLog.WIFI_BYTES_TRANSFER: { - pullWifiBytesTransfer(tagId, ret); + pullWifiBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.MOBILE_BYTES_TRANSFER: { - pullMobileBytesTransfer(tagId, ret); + pullMobileBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: { - pullWifiBytesTransferByFgBg(tagId, ret); + pullWifiBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: { - pullMobileBytesTransferByFgBg(tagId, ret); + pullMobileBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.BLUETOOTH_BYTES_TRANSFER: { - pullBluetoothBytesTransfer(tagId, ret); + pullBluetoothBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.KERNEL_WAKELOCK: { - pullKernelWakelock(tagId, ret); + pullKernelWakelock(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.CPU_TIME_PER_FREQ: { - pullCpuTimePerFreq(tagId, ret); + pullCpuTimePerFreq(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.CPU_TIME_PER_UID: { - pullKernelUidCpuTime(tagId, ret); + pullKernelUidCpuTime(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.CPU_TIME_PER_UID_FREQ: { - pullKernelUidCpuFreqTime(tagId, ret); + pullKernelUidCpuFreqTime(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.CPU_CLUSTER_TIME: { - pullKernelUidCpuClusterTime(tagId, ret); + pullKernelUidCpuClusterTime(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.CPU_ACTIVE_TIME: { - pullKernelUidCpuActiveTime(tagId, ret); + pullKernelUidCpuActiveTime(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.WIFI_ACTIVITY_INFO: { - pullWifiActivityInfo(tagId, ret); + pullWifiActivityInfo(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.MODEM_ACTIVITY_INFO: { - pullModemActivityInfo(tagId, ret); + pullModemActivityInfo(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.BLUETOOTH_ACTIVITY_INFO: { - pullBluetoothActivityInfo(tagId, ret); + pullBluetoothActivityInfo(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.SYSTEM_UPTIME: { - pullSystemUpTime(tagId, ret); + pullSystemUpTime(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.SYSTEM_ELAPSED_REALTIME: { - pullSystemElapsedRealtime(tagId, ret); + pullSystemElapsedRealtime(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.PROCESS_MEMORY_STATE: { - pullProcessMemoryState(tagId, ret); + pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.BINDER_CALLS: { - pullBinderCallsStats(tagId, ret); + pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.BINDER_CALLS_EXCEPTIONS: { - pullBinderCallsStatsExceptions(tagId, ret); + pullBinderCallsStatsExceptions(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.LOOPER_STATS: { - pullLooperStats(tagId, ret); + pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.DISK_STATS: { - pullDiskStats(tagId, ret); + pullDiskStats(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.DIRECTORY_USAGE: { - pullDirectoryUsage(tagId, ret); + pullDirectoryUsage(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.APP_SIZE: { - pullAppSize(tagId, ret); + pullAppSize(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.CATEGORY_SIZE: { - pullCategorySize(tagId, ret); + pullCategorySize(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.NUM_FINGERPRINTS: { - pullNumFingerprints(tagId, ret); + pullNumFingerprints(tagId, elapsedNanos, wallClockNanos, ret); break; } default: @@ -1513,7 +1566,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Thermal event received from vendor thermal management subsystem private static final class ThermalEventListener extends IThermalEventListener.Stub { - @Override public void notifyThrottling(boolean isThrottling, Temperature temp) { + @Override + public void notifyThrottling(boolean isThrottling, Temperature temp) { StatsLog.write(StatsLog.THERMAL_THROTTLING, temp.getType(), isThrottling ? 1 : 0, temp.getValue()); } |