Loading cmds/statsd/src/atom_field_options.proto +12 −0 Original line number Diff line number Diff line Loading @@ -64,10 +64,22 @@ message StateAtomFieldOption { optional StateField option = 1 [default = STATE_FIELD_UNSET]; } // Used to generate StatsLog.write APIs. enum LogMode { MODE_UNSET = 0; // Log fields as their actual types e.g., all primary data types. // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode MODE_AUTOMATIC = 1; // Log fields in their proto binary format. These fields will not be parsed in statsd MODE_BYTES = 2; } extend google.protobuf.FieldOptions { // Flags to decorate an atom that presents a state change. optional StateAtomFieldOption stateFieldOption = 50000; // Flags to decorate the uid fields in an atom. optional bool is_uid = 50001 [default = false]; optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC]; } No newline at end of file cmds/statsd/src/atoms.proto +11 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import "frameworks/base/core/proto/android/app/job/enums.proto"; import "frameworks/base/core/proto/android/bluetooth/enums.proto"; import "frameworks/base/core/proto/android/os/enums.proto"; import "frameworks/base/core/proto/android/server/enums.proto"; import "frameworks/base/core/proto/android/stats/launcher/launcher.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/view/enums.proto"; Loading Loading @@ -59,7 +60,8 @@ message Atom { LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 11; MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12; WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13; // 14 - 19 are available // 14 - 18 are available LauncherUIChanged launcher_event = 19; BatterySaverModeStateChanged battery_saver_mode_state_changed = 20; DeviceIdleModeStateChanged device_idle_mode_state_changed = 21; DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22; Loading Loading @@ -1185,6 +1187,14 @@ message PhoneStateChanged { optional State state = 1; } message LauncherUIChanged { optional android.stats.launcher.LauncherAction action = 1; optional android.stats.launcher.LauncherState src_state = 2; optional android.stats.launcher.LauncherState dst_state = 3; optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES]; optional bool is_swipe_up_enabled = 5; } /** * Logs that a setting was updated. * Logged from: Loading cmds/statsd/src/logd/LogEvent.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -379,7 +379,7 @@ float LogEvent::GetFloat(size_t key, status_t* err) const { string LogEvent::ToString() const { string result; result += StringPrintf("{ %lld %lld (%d)", (long long)mLogdTimestampNs, result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs, (long long)mElapsedTimestampNs, mTagId); for (const auto& value : mValues) { result += Loading cmds/statsd/src/stats_log_util.cpp +34 −8 Original line number Diff line number Diff line Loading @@ -25,15 +25,16 @@ #include <utils/Log.h> #include <utils/SystemClock.h> using android::util::AtomsInfo; using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_FIXED64; using android::util::FIELD_TYPE_FLOAT; using android::util::FIELD_TYPE_INT32; using android::util::FIELD_TYPE_INT64; using android::util::FIELD_TYPE_UINT64; using android::util::FIELD_TYPE_FIXED64; using android::util::FIELD_TYPE_MESSAGE; using android::util::FIELD_TYPE_STRING; using android::util::FIELD_TYPE_UINT64; using android::util::ProtoOutputStream; namespace android { Loading Loading @@ -294,8 +295,9 @@ void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers, // } // // void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size_t* index, int depth, int prefix, ProtoOutputStream* protoOutput) { void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims, size_t* index, int depth, int prefix, ProtoOutputStream* protoOutput) { size_t count = dims.size(); while (*index < count) { const auto& dim = dims[*index]; Loading @@ -319,9 +321,33 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size case FLOAT: protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value); break; case STRING: case STRING: { bool isBytesField = false; // Bytes field is logged via string format in log_msg format. So here we check // if this string field is a byte field. std::map<int, std::vector<int>>::const_iterator itr; if (depth == 0 && (itr = AtomsInfo::kBytesFieldAtoms.find(tagId)) != AtomsInfo::kBytesFieldAtoms.end()) { const std::vector<int>& bytesFields = itr->second; for (int bytesField : bytesFields) { if (bytesField == fieldNum) { // This is a bytes field isBytesField = true; break; } } } if (isBytesField) { if (dim.mValue.str_value.length() > 0) { protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum, (const char*)dim.mValue.str_value.c_str(), dim.mValue.str_value.length()); } } else { protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value); } break; } default: break; } Loading @@ -337,7 +363,7 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size } // Directly jump to the leaf value because the repeated position field is implied // by the position of the sub msg in the parent field. writeFieldValueTreeToStreamHelper(dims, index, valueDepth, writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth, dim.mField.getPrefix(valueDepth), protoOutput); if (msg_token != 0) { protoOutput->end(msg_token); Loading @@ -354,7 +380,7 @@ void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& value uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId); size_t index = 0; writeFieldValueTreeToStreamHelper(values, &index, 0, 0, protoOutput); writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput); protoOutput->end(atomToken); } Loading cmds/statsd/tests/LogEvent_test.cpp +94 −1 Original line number Diff line number Diff line Loading @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "src/logd/LogEvent.h" #include <gtest/gtest.h> #include <log/log_event_list.h> #include "src/logd/LogEvent.h" #include "frameworks/base/cmds/statsd/src/atoms.pb.h" #include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h" #ifdef __ANDROID__ Loading @@ -22,6 +24,9 @@ namespace android { namespace os { namespace statsd { using std::string; using util::ProtoOutputStream; TEST(LogEventTest, TestLogParsing) { LogEvent event1(1, 2000); Loading Loading @@ -159,6 +164,94 @@ TEST(LogEventTest, TestLogParsing2) { } TEST(LogEventTest, TestBinaryFieldAtom) { Atom launcherAtom; auto launcher_event = launcherAtom.mutable_launcher_event(); launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS); launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW); launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS); auto extension = launcher_event->mutable_extension(); auto src_target = extension->add_src_target(); src_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE); src_target->set_item(stats::launcher::LauncherTarget_Item_FOLDER_ICON); auto dst_target = extension->add_dst_target(); dst_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE); dst_target->set_item(stats::launcher::LauncherTarget_Item_WIDGET); string extension_str; extension->SerializeToString(&extension_str); LogEvent event1(Atom::kLauncherEventFieldNumber, 1000); event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS); event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW); event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS); event1.write(extension_str); event1.init(); ProtoOutputStream proto; event1.ToProto(proto); std::vector<uint8_t> outData; outData.resize(proto.size()); size_t pos = 0; auto iter = proto.data(); while (iter.readBuffer() != NULL) { size_t toRead = iter.currentToRead(); std::memcpy(&(outData[pos]), iter.readBuffer(), toRead); pos += toRead; iter.rp()->move(toRead); } std::string result_str(outData.begin(), outData.end()); std::string orig_str; launcherAtom.SerializeToString(&orig_str); EXPECT_EQ(orig_str, result_str); } TEST(LogEventTest, TestBinaryFieldAtom_empty) { Atom launcherAtom; auto launcher_event = launcherAtom.mutable_launcher_event(); launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS); launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW); launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS); // empty string. string extension_str; LogEvent event1(Atom::kLauncherEventFieldNumber, 1000); event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS); event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW); event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS); event1.write(extension_str); event1.init(); ProtoOutputStream proto; event1.ToProto(proto); std::vector<uint8_t> outData; outData.resize(proto.size()); size_t pos = 0; auto iter = proto.data(); while (iter.readBuffer() != NULL) { size_t toRead = iter.currentToRead(); std::memcpy(&(outData[pos]), iter.readBuffer(), toRead); pos += toRead; iter.rp()->move(toRead); } std::string result_str(outData.begin(), outData.end()); std::string orig_str; launcherAtom.SerializeToString(&orig_str); EXPECT_EQ(orig_str, result_str); } } // namespace statsd } // namespace os } // namespace android Loading Loading
cmds/statsd/src/atom_field_options.proto +12 −0 Original line number Diff line number Diff line Loading @@ -64,10 +64,22 @@ message StateAtomFieldOption { optional StateField option = 1 [default = STATE_FIELD_UNSET]; } // Used to generate StatsLog.write APIs. enum LogMode { MODE_UNSET = 0; // Log fields as their actual types e.g., all primary data types. // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode MODE_AUTOMATIC = 1; // Log fields in their proto binary format. These fields will not be parsed in statsd MODE_BYTES = 2; } extend google.protobuf.FieldOptions { // Flags to decorate an atom that presents a state change. optional StateAtomFieldOption stateFieldOption = 50000; // Flags to decorate the uid fields in an atom. optional bool is_uid = 50001 [default = false]; optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC]; } No newline at end of file
cmds/statsd/src/atoms.proto +11 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import "frameworks/base/core/proto/android/app/job/enums.proto"; import "frameworks/base/core/proto/android/bluetooth/enums.proto"; import "frameworks/base/core/proto/android/os/enums.proto"; import "frameworks/base/core/proto/android/server/enums.proto"; import "frameworks/base/core/proto/android/stats/launcher/launcher.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/view/enums.proto"; Loading Loading @@ -59,7 +60,8 @@ message Atom { LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 11; MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12; WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13; // 14 - 19 are available // 14 - 18 are available LauncherUIChanged launcher_event = 19; BatterySaverModeStateChanged battery_saver_mode_state_changed = 20; DeviceIdleModeStateChanged device_idle_mode_state_changed = 21; DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22; Loading Loading @@ -1185,6 +1187,14 @@ message PhoneStateChanged { optional State state = 1; } message LauncherUIChanged { optional android.stats.launcher.LauncherAction action = 1; optional android.stats.launcher.LauncherState src_state = 2; optional android.stats.launcher.LauncherState dst_state = 3; optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES]; optional bool is_swipe_up_enabled = 5; } /** * Logs that a setting was updated. * Logged from: Loading
cmds/statsd/src/logd/LogEvent.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -379,7 +379,7 @@ float LogEvent::GetFloat(size_t key, status_t* err) const { string LogEvent::ToString() const { string result; result += StringPrintf("{ %lld %lld (%d)", (long long)mLogdTimestampNs, result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs, (long long)mElapsedTimestampNs, mTagId); for (const auto& value : mValues) { result += Loading
cmds/statsd/src/stats_log_util.cpp +34 −8 Original line number Diff line number Diff line Loading @@ -25,15 +25,16 @@ #include <utils/Log.h> #include <utils/SystemClock.h> using android::util::AtomsInfo; using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_FIXED64; using android::util::FIELD_TYPE_FLOAT; using android::util::FIELD_TYPE_INT32; using android::util::FIELD_TYPE_INT64; using android::util::FIELD_TYPE_UINT64; using android::util::FIELD_TYPE_FIXED64; using android::util::FIELD_TYPE_MESSAGE; using android::util::FIELD_TYPE_STRING; using android::util::FIELD_TYPE_UINT64; using android::util::ProtoOutputStream; namespace android { Loading Loading @@ -294,8 +295,9 @@ void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers, // } // // void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size_t* index, int depth, int prefix, ProtoOutputStream* protoOutput) { void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims, size_t* index, int depth, int prefix, ProtoOutputStream* protoOutput) { size_t count = dims.size(); while (*index < count) { const auto& dim = dims[*index]; Loading @@ -319,9 +321,33 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size case FLOAT: protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value); break; case STRING: case STRING: { bool isBytesField = false; // Bytes field is logged via string format in log_msg format. So here we check // if this string field is a byte field. std::map<int, std::vector<int>>::const_iterator itr; if (depth == 0 && (itr = AtomsInfo::kBytesFieldAtoms.find(tagId)) != AtomsInfo::kBytesFieldAtoms.end()) { const std::vector<int>& bytesFields = itr->second; for (int bytesField : bytesFields) { if (bytesField == fieldNum) { // This is a bytes field isBytesField = true; break; } } } if (isBytesField) { if (dim.mValue.str_value.length() > 0) { protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum, (const char*)dim.mValue.str_value.c_str(), dim.mValue.str_value.length()); } } else { protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value); } break; } default: break; } Loading @@ -337,7 +363,7 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size } // Directly jump to the leaf value because the repeated position field is implied // by the position of the sub msg in the parent field. writeFieldValueTreeToStreamHelper(dims, index, valueDepth, writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth, dim.mField.getPrefix(valueDepth), protoOutput); if (msg_token != 0) { protoOutput->end(msg_token); Loading @@ -354,7 +380,7 @@ void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& value uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId); size_t index = 0; writeFieldValueTreeToStreamHelper(values, &index, 0, 0, protoOutput); writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput); protoOutput->end(atomToken); } Loading
cmds/statsd/tests/LogEvent_test.cpp +94 −1 Original line number Diff line number Diff line Loading @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "src/logd/LogEvent.h" #include <gtest/gtest.h> #include <log/log_event_list.h> #include "src/logd/LogEvent.h" #include "frameworks/base/cmds/statsd/src/atoms.pb.h" #include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h" #ifdef __ANDROID__ Loading @@ -22,6 +24,9 @@ namespace android { namespace os { namespace statsd { using std::string; using util::ProtoOutputStream; TEST(LogEventTest, TestLogParsing) { LogEvent event1(1, 2000); Loading Loading @@ -159,6 +164,94 @@ TEST(LogEventTest, TestLogParsing2) { } TEST(LogEventTest, TestBinaryFieldAtom) { Atom launcherAtom; auto launcher_event = launcherAtom.mutable_launcher_event(); launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS); launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW); launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS); auto extension = launcher_event->mutable_extension(); auto src_target = extension->add_src_target(); src_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE); src_target->set_item(stats::launcher::LauncherTarget_Item_FOLDER_ICON); auto dst_target = extension->add_dst_target(); dst_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE); dst_target->set_item(stats::launcher::LauncherTarget_Item_WIDGET); string extension_str; extension->SerializeToString(&extension_str); LogEvent event1(Atom::kLauncherEventFieldNumber, 1000); event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS); event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW); event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS); event1.write(extension_str); event1.init(); ProtoOutputStream proto; event1.ToProto(proto); std::vector<uint8_t> outData; outData.resize(proto.size()); size_t pos = 0; auto iter = proto.data(); while (iter.readBuffer() != NULL) { size_t toRead = iter.currentToRead(); std::memcpy(&(outData[pos]), iter.readBuffer(), toRead); pos += toRead; iter.rp()->move(toRead); } std::string result_str(outData.begin(), outData.end()); std::string orig_str; launcherAtom.SerializeToString(&orig_str); EXPECT_EQ(orig_str, result_str); } TEST(LogEventTest, TestBinaryFieldAtom_empty) { Atom launcherAtom; auto launcher_event = launcherAtom.mutable_launcher_event(); launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS); launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW); launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS); // empty string. string extension_str; LogEvent event1(Atom::kLauncherEventFieldNumber, 1000); event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS); event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW); event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS); event1.write(extension_str); event1.init(); ProtoOutputStream proto; event1.ToProto(proto); std::vector<uint8_t> outData; outData.resize(proto.size()); size_t pos = 0; auto iter = proto.data(); while (iter.readBuffer() != NULL) { size_t toRead = iter.currentToRead(); std::memcpy(&(outData[pos]), iter.readBuffer(), toRead); pos += toRead; iter.rp()->move(toRead); } std::string result_str(outData.begin(), outData.end()); std::string orig_str; launcherAtom.SerializeToString(&orig_str); EXPECT_EQ(orig_str, result_str); } } // namespace statsd } // namespace os } // namespace android Loading