diff options
Diffstat (limited to 'cmds')
100 files changed, 1376 insertions, 2340 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 520366f518ab..a1278f358380 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -42,10 +42,10 @@ #include <android-base/properties.h> +#include <ui/DisplayConfig.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> #include <ui/Region.h> -#include <ui/DisplayInfo.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> @@ -283,16 +283,19 @@ status_t BootAnimation::readyToRun() { mDisplayToken = SurfaceComposerClient::getInternalDisplayToken(); if (mDisplayToken == nullptr) - return -1; + return NAME_NOT_FOUND; - DisplayInfo dinfo; - status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo); - if (status) - return -1; + DisplayConfig displayConfig; + const status_t error = + SurfaceComposerClient::getActiveDisplayConfig(mDisplayToken, &displayConfig); + if (error != NO_ERROR) + return error; + + const ui::Size& resolution = displayConfig.resolution; // create the native surface sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), - dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); + resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565); SurfaceComposerClient::Transaction t; diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index de1dbc90eb2d..c643b0e8800c 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -37,6 +37,10 @@ typedef uint16_t EntryId; // eeee in 0xpptteeee namespace utils { +// Returns whether the Res_value::data_type represents a dynamic or regular resource reference. +bool IsReference(uint8_t data_type); + +// Converts the Res_value::data_type to a human-readable string representation. StringPiece DataTypeToString(uint8_t data_type); struct OverlayManifestInfo { diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp index 407478945151..43cfec3f9cf9 100644 --- a/cmds/idmap2/libidmap2/ResourceMapping.cpp +++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp @@ -27,6 +27,7 @@ #include "idmap2/ResourceUtils.h" using android::base::StringPrintf; +using android::idmap2::utils::IsReference; using android::idmap2::utils::ResToTypeEntryName; namespace android::idmap2 { @@ -200,8 +201,7 @@ Result<ResourceMapping> ResourceMapping::CreateResourceMapping(const AssetManage // Only rewrite resources defined within the overlay package to their corresponding target // resource ids at runtime. bool rewrite_overlay_reference = - (overlay_resource->dataType == Res_value::TYPE_REFERENCE || - overlay_resource->dataType == Res_value::TYPE_DYNAMIC_REFERENCE) + IsReference(overlay_resource->dataType) ? overlay_package_id == EXTRACT_PACKAGE(overlay_resource->data) : false; @@ -331,8 +331,13 @@ Result<ResourceMapping> ResourceMapping::FromApkAssets(const ApkAssets& target_a std::unique_ptr<uint8_t[]> string_pool_data; Result<ResourceMapping> resource_mapping = {{}}; if (overlay_info.resource_mapping != 0U) { + // Use the dynamic reference table to find the assigned resource id of the map xml. + const auto& ref_table = overlay_asset_manager.GetDynamicRefTableForCookie(0); + uint32_t resource_mapping_id = overlay_info.resource_mapping; + ref_table->lookupResourceId(&resource_mapping_id); + // Load the overlay resource mappings from the file specified using android:resourcesMap. - auto asset = OpenNonAssetFromResource(overlay_info.resource_mapping, overlay_asset_manager); + auto asset = OpenNonAssetFromResource(resource_mapping_id, overlay_asset_manager); if (!asset) { return Error("failed opening xml for android:resourcesMap: %s", asset.GetErrorMessage().c_str()); @@ -404,8 +409,7 @@ Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource, target_map_.insert(std::make_pair(target_resource, TargetValue{data_type, data_value})); - if (rewrite_overlay_reference && - (data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE)) { + if (rewrite_overlay_reference && IsReference(data_type)) { overlay_map_.insert(std::make_pair(data_value, target_resource)); } @@ -421,8 +425,7 @@ void ResourceMapping::RemoveMapping(ResourceId target_resource) { const TargetValue value = target_iter->second; target_map_.erase(target_iter); - if (value.data_type != Res_value::TYPE_REFERENCE && - value.data_type != Res_value::TYPE_DYNAMIC_REFERENCE) { + if (!IsReference(value.data_type)) { return; } diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp index a5df746ca733..98d026bc70dc 100644 --- a/cmds/idmap2/libidmap2/ResourceUtils.cpp +++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp @@ -33,6 +33,10 @@ using android::util::Utf16ToUtf8; namespace android::idmap2::utils { +bool IsReference(uint8_t data_type) { + return data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE; +} + StringPiece DataTypeToString(uint8_t data_type) { switch (data_type) { case Res_value::TYPE_NULL: @@ -133,7 +137,7 @@ Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path, } if (auto result_value = overlay_it->GetAttributeValue("resourcesMap")) { - if ((*result_value).dataType == Res_value::TYPE_REFERENCE) { + if (IsReference((*result_value).dataType)) { info.resource_mapping = (*result_value).data; } else { return Error("android:resourcesMap is not a reference in AndroidManifest.xml of %s", diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp index f55acee029dc..8af4037be954 100644 --- a/cmds/idmap2/tests/FileUtilsTests.cpp +++ b/cmds/idmap2/tests/FileUtilsTests.cpp @@ -56,12 +56,12 @@ TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) { return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0; }); ASSERT_THAT(v, NotNull()); - ASSERT_EQ(v->size(), 10U); + ASSERT_EQ(v->size(), 11U); ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>( {root + "/target/target.apk", root + "/target/target-no-overlayable.apk", root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk", - root + "/overlay/overlay-no-name-static.apk", + root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-shared.apk", root + "/overlay/overlay-static-1.apk", root + "/overlay/overlay-static-2.apk", root + "/signature-overlay/signature-overlay.apk", root + "/system-overlay/system-overlay.apk", diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index 4bc625565144..a2c156063757 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -247,6 +247,43 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) { ASSERT_OVERLAY_ENTRY(overlay_entries[3], 0x7f020002, 0x7f02000f); } +TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) { + std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; + std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-shared.apk"; + + std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); + ASSERT_THAT(target_apk, NotNull()); + + std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); + ASSERT_THAT(overlay_apk, NotNull()); + + auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC, + /* enforce_overlayable */ true); + ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage(); + auto& idmap = *idmap_result; + ASSERT_THAT(idmap, NotNull()); + + const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); + ASSERT_EQ(dataBlocks.size(), 1U); + + const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; + ASSERT_THAT(data, NotNull()); + + const auto& target_entries = data->GetTargetEntries(); + ASSERT_EQ(target_entries.size(), 4U); + ASSERT_TARGET_ENTRY(target_entries[0], 0x7f010000, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00010000); + ASSERT_TARGET_ENTRY(target_entries[1], 0x7f02000c, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020000); + ASSERT_TARGET_ENTRY(target_entries[2], 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020001); + ASSERT_TARGET_ENTRY(target_entries[3], 0x7f02000f, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020002); + + const auto& overlay_entries = data->GetOverlayEntries(); + ASSERT_EQ(target_entries.size(), 4U); + ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x00010000, 0x7f010000); + ASSERT_OVERLAY_ENTRY(overlay_entries[1], 0x00020000, 0x7f02000c); + ASSERT_OVERLAY_ENTRY(overlay_entries[2], 0x00020001, 0x7f02000e); + ASSERT_OVERLAY_ENTRY(overlay_entries[3], 0x00020002, 0x7f02000f); +} + TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) { OverlayManifestInfo info{}; info.target_package = "test.target"; diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build index b921b0d3d3ad..114b099598fa 100755 --- a/cmds/idmap2/tests/data/overlay/build +++ b/cmds/idmap2/tests/data/overlay/build @@ -51,4 +51,12 @@ aapt2 link \ -o overlay-static-2.apk \ compiled.flata +aapt2 link \ + --no-resource-removal \ + --shared-lib \ + -I "$FRAMEWORK_RES_APK" \ + --manifest AndroidManifest.xml \ + -o overlay-shared.apk \ + compiled.flata + rm compiled.flata diff --git a/cmds/idmap2/tests/data/overlay/overlay-shared.apk b/cmds/idmap2/tests/data/overlay/overlay-shared.apk Binary files differnew file mode 100644 index 000000000000..93dcc82f9358 --- /dev/null +++ b/cmds/idmap2/tests/data/overlay/overlay-shared.apk diff --git a/cmds/incident/Android.bp b/cmds/incident/Android.bp index 9e9dac14c802..94855aa0311f 100644 --- a/cmds/incident/Android.bp +++ b/cmds/incident/Android.bp @@ -26,7 +26,7 @@ cc_binary { "libcutils", "liblog", "libutils", - "libincident", + "libincidentpriv", ], static_libs: [ diff --git a/cmds/incident_helper/Android.bp b/cmds/incident_helper/Android.bp index 64f4c667820d..f07743ec2ee6 100644 --- a/cmds/incident_helper/Android.bp +++ b/cmds/incident_helper/Android.bp @@ -44,7 +44,7 @@ cc_defaults { "src/ih_util.cpp", ], - generated_headers: ["gen-platform-proto-constants"], + generated_headers: ["framework-cppstream-protos"], shared_libs: [ "libbase", diff --git a/cmds/incidentd/Android.bp b/cmds/incidentd/Android.bp index 25e0328b4f38..c47526abad53 100644 --- a/cmds/incidentd/Android.bp +++ b/cmds/incidentd/Android.bp @@ -43,7 +43,7 @@ cc_binary { ], local_include_dirs: ["src"], - generated_headers: ["gen-platform-proto-constants"], + generated_headers: ["framework-cppstream-protos"], proto: { type: "lite", @@ -54,7 +54,7 @@ cc_binary { "libbinder", "libdebuggerd_client", "libdumputils", - "libincident", + "libincidentpriv", "liblog", "libprotoutil", "libservices", @@ -98,7 +98,7 @@ cc_test { ], local_include_dirs: ["src"], - generated_headers: ["gen-platform-proto-constants"], + generated_headers: ["framework-cppstream-protos"], srcs: [ "tests/**/*.cpp", @@ -128,7 +128,7 @@ cc_test { "libbinder", "libdebuggerd_client", "libdumputils", - "libincident", + "libincidentpriv", "liblog", "libprotobuf-cpp-full", "libprotoutil", diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index ac24a553b555..956fd29205cb 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -44,12 +44,8 @@ cc_library_host_shared { cc_defaults { name: "statsd_defaults", - aidl: { - include_dirs: ["frameworks/base/core/java"], - }, srcs: [ - ":statsd_aidl", "src/active_config_list.proto", "src/anomaly/AlarmMonitor.cpp", "src/anomaly/AlarmTracker.cpp", @@ -64,16 +60,13 @@ cc_defaults { "src/config/ConfigKey.cpp", "src/config/ConfigListener.cpp", "src/config/ConfigManager.cpp", - "src/external/GpuStatsPuller.cpp", + "src/experiment_ids.proto", "src/external/Perfetto.cpp", - "src/external/PowerStatsPuller.cpp", "src/external/PullResultReceiver.cpp", "src/external/puller_util.cpp", - "src/external/ResourceHealthManagerPuller.cpp", "src/external/StatsCallbackPuller.cpp", "src/external/StatsPuller.cpp", "src/external/StatsPullerManager.cpp", - "src/external/SubsystemSleepStatePuller.cpp", "src/external/TrainInfoPuller.cpp", "src/FieldValue.cpp", "src/guardrail/StatsdStats.cpp", @@ -113,7 +106,7 @@ cc_defaults { ], cflags: [ - // "-DNEW_ENCODING_SCHEME", + "-DNEW_ENCODING_SCHEME", ], local_include_dirs: [ @@ -121,29 +114,20 @@ cc_defaults { ], static_libs: [ - "android.frameworks.stats@1.0", - "android.hardware.power.stats@1.0", - "android.hardware.power@1.0", - "android.hardware.power@1.1", "libbase", "libcutils", - "libhealthhalutils", - "liblog", - "libplatformprotos", "libprotoutil", "libstatslog", - "libstatssocket", + "libstatsmetadata", "libsysutils", + "libutils", ], shared_libs: [ - "android.hardware.health@2.0", "libbinder", - "libgraphicsenv", - "libhidlbase", "libincident", - "libservices", - "libstatsmetadata", - "libutils", + "liblog", + "libstatssocket", + "statsd-aidl-cpp", ], } @@ -169,7 +153,7 @@ genrule { ], } -cc_library_shared { +cc_library_static { name: "libstatsmetadata", host_supported: true, generated_sources: [ @@ -232,8 +216,6 @@ cc_binary { shared_libs: ["libgtest_prod"], - vintf_fragments: ["android.frameworks.stats@1.0-service.xml"], - init_rc: ["statsd.rc"], } @@ -286,8 +268,6 @@ cc_test { "tests/e2e/PartialBucket_e2e_test.cpp", "tests/e2e/ValueMetric_pull_e2e_test.cpp", "tests/e2e/WakelockDuration_e2e_test.cpp", - "tests/external/GpuStatsPuller_test.cpp", - "tests/external/IncidentReportArgs_test.cpp", "tests/external/puller_util_test.cpp", "tests/external/StatsCallbackPuller_test.cpp", "tests/external/StatsPuller_test.cpp", diff --git a/cmds/statsd/android.frameworks.stats@1.0-service.xml b/cmds/statsd/android.frameworks.stats@1.0-service.xml deleted file mode 100644 index bb02f66a28b1..000000000000 --- a/cmds/statsd/android.frameworks.stats@1.0-service.xml +++ /dev/null @@ -1,11 +0,0 @@ -<manifest version="1.0" type="framework"> - <hal> - <name>android.frameworks.stats</name> - <transport>hwbinder</transport> - <version>1.0</version> - <interface> - <name>IStats</name> - <instance>default</instance> - </interface> - </hal> -</manifest> diff --git a/cmds/statsd/benchmark/log_event_benchmark.cpp b/cmds/statsd/benchmark/log_event_benchmark.cpp index bdfdb2e00ac0..8b687438ca27 100644 --- a/cmds/statsd/benchmark/log_event_benchmark.cpp +++ b/cmds/statsd/benchmark/log_event_benchmark.cpp @@ -23,14 +23,14 @@ namespace os { namespace statsd { static size_t createAndParseStatsEvent(uint8_t* msg) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); - stats_event_write_int32(event, 2); - stats_event_write_float(event, 2.0); - stats_event_build(event); + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + AStatsEvent_writeInt32(event, 2); + AStatsEvent_writeFloat(event, 2.0); + AStatsEvent_build(event); size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); + uint8_t* buf = AStatsEvent_getBuffer(event, &size); memcpy(msg, buf, size); return size; } @@ -39,7 +39,7 @@ static void BM_LogEventCreation(benchmark::State& state) { uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD]; size_t size = createAndParseStatsEvent(msg); while (state.KeepRunning()) { - benchmark::DoNotOptimize(LogEvent(msg, size, /*uid=*/ 1000)); + benchmark::DoNotOptimize(LogEvent(msg, size, /*uid=*/ 1000, /*pid=*/ 1001)); } } BENCHMARK(BM_LogEventCreation); diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp index 109785f649e4..6b9d0e4fdac0 100644 --- a/cmds/statsd/src/HashableDimensionKey.cpp +++ b/cmds/statsd/src/HashableDimensionKey.cpp @@ -16,8 +16,6 @@ #define DEBUG false // STOPSHIP if true #include "Log.h" -#include <mutex> - #include "HashableDimensionKey.h" #include "FieldValue.h" @@ -28,6 +26,86 @@ namespace statsd { using std::string; using std::vector; +// These constants must be kept in sync with those in StatsDimensionsValue.java +const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2; +const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3; +const static int STATS_DIMENSIONS_VALUE_LONG_TYPE = 4; +// const static int STATS_DIMENSIONS_VALUE_BOOL_TYPE = 5; (commented out because +// unused -- statsd does not correctly support bool types) +const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6; +const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7; + +/** + * Recursive helper function that populates a parent StatsDimensionsValueParcel + * with children StatsDimensionsValueParcels. + * + * \param dims vector of FieldValues stored by HashableDimensionKey + * \param index positions in dims vector to start reading children from + * \param depth level of parent parcel in the full StatsDimensionsValueParcel + * tree + */ +static void populateStatsDimensionsValueParcelChildren(StatsDimensionsValueParcel &parentParcel, + const vector<FieldValue>& dims, size_t& index, + int depth, int prefix) { + while (index < dims.size()) { + const FieldValue& dim = dims[index]; + int fieldDepth = dim.mField.getDepth(); + int fieldPrefix = dim.mField.getPrefix(depth); + StatsDimensionsValueParcel childParcel; + childParcel.field = dim.mField.getPosAtDepth(depth); + if (depth > 2) { + ALOGE("Depth > 2 not supported by StatsDimensionsValueParcel."); + return; + } + if (depth == fieldDepth && prefix == fieldPrefix) { + switch (dim.mValue.getType()) { + case INT: + childParcel.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE; + childParcel.intValue = dim.mValue.int_value; + break; + case LONG: + childParcel.valueType = STATS_DIMENSIONS_VALUE_LONG_TYPE; + childParcel.longValue = dim.mValue.long_value; + break; + case FLOAT: + childParcel.valueType = STATS_DIMENSIONS_VALUE_FLOAT_TYPE; + childParcel.floatValue = dim.mValue.float_value; + break; + case STRING: + childParcel.valueType = STATS_DIMENSIONS_VALUE_STRING_TYPE; + childParcel.stringValue = String16(dim.mValue.str_value.c_str()); + break; + default: + ALOGE("Encountered FieldValue with unsupported value type."); + break; + } + index++; + parentParcel.tupleValue.push_back(childParcel); + } else if (fieldDepth > depth && fieldPrefix == prefix) { + childParcel.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE; + populateStatsDimensionsValueParcelChildren(childParcel, dims, index, depth + 1, + dim.mField.getPrefix(depth + 1)); + parentParcel.tupleValue.push_back(childParcel); + } else { + return; + } + } +} + +StatsDimensionsValueParcel HashableDimensionKey::toStatsDimensionsValueParcel() const { + StatsDimensionsValueParcel parcel; + if (mValues.size() == 0) { + return parcel; + } + + parcel.field = mValues[0].mField.getTag(); + parcel.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE; + + size_t index = 0; + populateStatsDimensionsValueParcelChildren(parcel, mValues, index, /*depth=*/0, /*prefix=*/0); + return parcel; +} + android::hash_t hashDimension(const HashableDimensionKey& value) { android::hash_t hash = 0; for (const auto& fieldValue : value.getValues()) { diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h index 654e1358f2a1..4adcf967555e 100644 --- a/cmds/statsd/src/HashableDimensionKey.h +++ b/cmds/statsd/src/HashableDimensionKey.h @@ -16,10 +16,11 @@ #pragma once +#include <android/os/StatsDimensionsValueParcel.h> #include <utils/JenkinsHash.h> #include <vector> -#include "FieldValue.h" #include "android-base/stringprintf.h" +#include "FieldValue.h" #include "logd/LogEvent.h" namespace android { @@ -69,6 +70,8 @@ public: return nullptr; } + StatsDimensionsValueParcel toStatsDimensionsValueParcel() const; + std::string toString() const; bool operator!=(const HashableDimensionKey& that) const; diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 34818145a922..6e7f08135f1e 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -20,17 +20,17 @@ #include "StatsLogProcessor.h" #include <android-base/file.h> -#include <dirent.h> +#include <cutils/multiuser.h> #include <frameworks/base/cmds/statsd/src/active_config_list.pb.h> -#include <log/log_event_list.h> -#include <utils/Errors.h> -#include <utils/SystemClock.h> +#include <frameworks/base/cmds/statsd/src/experiment_ids.pb.h> #include "android-base/stringprintf.h" #include "atoms_info.h" #include "external/StatsPullerManager.h" #include "guardrail/StatsdStats.h" +#include "logd/LogEvent.h" #include "metrics/CountMetricProducer.h" +#include "StatsService.h" #include "state/StateManager.h" #include "stats_log_util.h" #include "stats_util.h" @@ -47,8 +47,6 @@ using android::util::FIELD_TYPE_INT64; using android::util::FIELD_TYPE_MESSAGE; using android::util::FIELD_TYPE_STRING; using android::util::ProtoOutputStream; -using std::make_unique; -using std::unique_ptr; using std::vector; namespace android { @@ -74,6 +72,10 @@ const int FIELD_ID_STRINGS = 9; // for ActiveConfigList const int FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG = 1; +// for permissions checks +constexpr const char* kPermissionDump = "android.permission.DUMP"; +constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS"; + #define NS_PER_HOUR 3600 * NS_PER_SEC #define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric" @@ -187,6 +189,196 @@ void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) { } } +void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) { + pid_t pid = event->GetPid(); + uid_t uid = event->GetUid(); + if (!checkPermissionForIds(kPermissionDump, pid, uid) || + !checkPermissionForIds(kPermissionUsage, pid, uid)) { + return; + } + // The Get* functions don't modify the status on success, they only write in + // failure statuses, so we can use one status variable for all calls then + // check if it is no longer NO_ERROR. + status_t err = NO_ERROR; + InstallTrainInfo trainInfo; + trainInfo.trainName = string(event->GetString(1 /*train name field id*/, &err)); + trainInfo.trainVersionCode = event->GetLong(2 /*train version field id*/, &err); + trainInfo.requiresStaging = event->GetBool(3 /*requires staging field id*/, &err); + trainInfo.rollbackEnabled = event->GetBool(4 /*rollback enabled field id*/, &err); + trainInfo.requiresLowLatencyMonitor = + event->GetBool(5 /*requires low latency monitor field id*/, &err); + trainInfo.status = int32_t(event->GetLong(6 /*state field id*/, &err)); +#ifdef NEW_ENCODING_SCHEME + std::vector<uint8_t> trainExperimentIdBytes = + event->GetStorage(7 /*experiment ids field id*/, &err); +#else + string trainExperimentIdString = event->GetString(7 /*experiment ids field id*/, &err); +#endif + bool is_rollback = event->GetBool(10 /*is rollback field id*/, &err); + + if (err != NO_ERROR) { + ALOGE("Failed to parse fields in binary push state changed log event"); + return; + } + ExperimentIds trainExperimentIds; +#ifdef NEW_ENCODING_SCHEME + if (!trainExperimentIds.ParseFromArray(trainExperimentIdBytes.data(), + trainExperimentIdBytes.size())) { +#else + if (!trainExperimentIds.ParseFromString(trainExperimentIdString)) { +#endif + ALOGE("Failed to parse experimentids in binary push state changed."); + return; + } + trainInfo.experimentIds = {trainExperimentIds.experiment_id().begin(), + trainExperimentIds.experiment_id().end()}; + + // Update the train info on disk and get any data the logevent is missing. + getAndUpdateTrainInfoOnDisk(is_rollback, &trainInfo); + + std::vector<uint8_t> trainExperimentIdProto; + writeExperimentIdsToProto(trainInfo.experimentIds, &trainExperimentIdProto); + int32_t userId = multiuser_get_user_id(uid); + + event->updateValue(2 /*train version field id*/, trainInfo.trainVersionCode, LONG); +#ifdef NEW_ENCODING_SCHEME + event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STORAGE); +#else + event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STRING); +#endif + event->updateValue(8 /*user id field id*/, userId, INT); + + if (is_rollback) { + int bit = trainInfo.requiresStaging ? 1 : 0; + event->updateValue(3 /*requires staging field id*/, bit, INT); + bit = trainInfo.rollbackEnabled ? 1 : 0; + event->updateValue(4 /*rollback enabled field id*/, bit, INT); + bit = trainInfo.requiresLowLatencyMonitor ? 1 : 0; + event->updateValue(5 /*requires low latency monitor field id*/, bit, INT); + } +} + +void StatsLogProcessor::getAndUpdateTrainInfoOnDisk(bool is_rollback, + InstallTrainInfo* trainInfo) { + // If the train name is empty, we don't know which train to attribute the + // event to, so return early. + if (trainInfo->trainName.empty()) { + return; + } + bool readTrainInfoSuccess = false; + InstallTrainInfo trainInfoOnDisk; + readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfo->trainName, trainInfoOnDisk); + + bool resetExperimentIds = false; + if (readTrainInfoSuccess) { + // Keep the old train version if we received an empty version. + if (trainInfo->trainVersionCode == -1) { + trainInfo->trainVersionCode = trainInfoOnDisk.trainVersionCode; + } else if (trainInfo->trainVersionCode != trainInfoOnDisk.trainVersionCode) { + // Reset experiment ids if we receive a new non-empty train version. + resetExperimentIds = true; + } + + // Reset if we received a different experiment id. + if (!trainInfo->experimentIds.empty() && + (trainInfoOnDisk.experimentIds.empty() || + trainInfo->experimentIds.at(0) != trainInfoOnDisk.experimentIds[0])) { + resetExperimentIds = true; + } + } + + // Find the right experiment IDs + if ((!resetExperimentIds || is_rollback) && readTrainInfoSuccess) { + trainInfo->experimentIds = trainInfoOnDisk.experimentIds; + } + + if (!trainInfo->experimentIds.empty()) { + int64_t firstId = trainInfo->experimentIds.at(0); + switch (trainInfo->status) { + case android::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALL_SUCCESS: + trainInfo->experimentIds.push_back(firstId + 1); + break; + case android::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_INITIATED: + trainInfo->experimentIds.push_back(firstId + 2); + break; + case android::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_SUCCESS: + trainInfo->experimentIds.push_back(firstId + 3); + break; + } + } + + if (is_rollback) { + trainInfo->requiresStaging = trainInfoOnDisk.requiresStaging; + trainInfo->rollbackEnabled = trainInfoOnDisk.rollbackEnabled; + trainInfo->requiresLowLatencyMonitor = trainInfoOnDisk.requiresLowLatencyMonitor; + } + + StorageManager::writeTrainInfo(*trainInfo); +} + +void StatsLogProcessor::onWatchdogRollbackOccurredLocked(LogEvent* event) { + pid_t pid = event->GetPid(); + uid_t uid = event->GetUid(); + if (!checkPermissionForIds(kPermissionDump, pid, uid) || + !checkPermissionForIds(kPermissionUsage, pid, uid)) { + return; + } + // The Get* functions don't modify the status on success, they only write in + // failure statuses, so we can use one status variable for all calls then + // check if it is no longer NO_ERROR. + status_t err = NO_ERROR; + int32_t rollbackType = int32_t(event->GetInt(1 /*rollback type field id*/, &err)); + string packageName = string(event->GetString(2 /*package name field id*/, &err)); + + if (err != NO_ERROR) { + ALOGE("Failed to parse fields in watchdog rollback occurred log event"); + return; + } + + vector<int64_t> experimentIds = + processWatchdogRollbackOccurred(rollbackType, packageName); + vector<uint8_t> experimentIdProto; + writeExperimentIdsToProto(experimentIds, &experimentIdProto); + +#ifdef NEW_ENCODING_SCHEME + event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STORAGE); +#else + event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STRING); +#endif +} + +vector<int64_t> StatsLogProcessor::processWatchdogRollbackOccurred(const int32_t rollbackTypeIn, + const string& packageNameIn) { + // If the package name is empty, we can't attribute it to any train, so + // return early. + if (packageNameIn.empty()) { + return vector<int64_t>(); + } + bool readTrainInfoSuccess = false; + InstallTrainInfo trainInfoOnDisk; + readTrainInfoSuccess = StorageManager::readTrainInfo(packageNameIn, trainInfoOnDisk); + + if (!readTrainInfoSuccess) { + return vector<int64_t>(); + } + + if (trainInfoOnDisk.experimentIds.empty()) { + return vector<int64_t>(); + } + switch (rollbackTypeIn) { + case android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE: + trainInfoOnDisk.experimentIds.push_back(trainInfoOnDisk.experimentIds[0] + 4); + StorageManager::writeTrainInfo(trainInfoOnDisk); + break; + case android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS: + trainInfoOnDisk.experimentIds.push_back(trainInfoOnDisk.experimentIds[0] + 5); + StorageManager::writeTrainInfo(trainInfoOnDisk); + break; + } + + return trainInfoOnDisk.experimentIds; +} + void StatsLogProcessor::resetConfigs() { std::lock_guard<std::mutex> lock(mMetricsMutex); resetConfigsLocked(getElapsedRealtimeNs()); @@ -207,6 +399,18 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event) { void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { std::lock_guard<std::mutex> lock(mMetricsMutex); + // Hard-coded logic to update train info on disk and fill in any information + // this log event may be missing. + if (event->GetTagId() == android::util::BINARY_PUSH_STATE_CHANGED) { + onBinaryPushStateChangedEventLocked(event); + } + + // Hard-coded logic to update experiment ids on disk for certain rollback + // types and fill the rollback atom with experiment ids + if (event->GetTagId() == android::util::WATCHDOG_ROLLBACK_OCCURRED) { + onWatchdogRollbackOccurredLocked(event); + } + #ifdef VERY_VERBOSE_PRINTING if (mPrintAllLogs) { ALOGI("%s", event->ToString().c_str()); diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index c569bc1e33f7..42e56760fb89 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -18,6 +18,7 @@ #include <gtest/gtest_prod.h> #include "config/ConfigListener.h" +#include "logd/LogEvent.h" #include "metrics/MetricsManager.h" #include "packages/UidMap.h" #include "external/StatsPullerManager.h" @@ -196,6 +197,22 @@ private: // Handler over the isolated uid change event. void onIsolatedUidChangedEventLocked(const LogEvent& event); + // Handler over the binary push state changed event. + void onBinaryPushStateChangedEventLocked(LogEvent* event); + + // Handler over the watchdog rollback occurred event. + void onWatchdogRollbackOccurredLocked(LogEvent* event); + + // Updates train info on disk based on binary push state changed info and + // write disk info into parameters. + void getAndUpdateTrainInfoOnDisk(bool is_rollback, InstallTrainInfo* trainInfoIn); + + // Gets experiment ids on disk for associated train and updates them + // depending on rollback type. Then writes them back to disk and returns + // them. + std::vector<int64_t> processWatchdogRollbackOccurred(const int32_t rollbackTypeIn, + const string& packageName); + // Reset all configs. void resetConfigsLocked(const int64_t timestampNs); // Reset the specified configs. diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index c1a8d69191d2..168833fc8c8b 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -27,13 +27,10 @@ #include "subscriber/SubscriberReporter.h" #include <android-base/file.h> -#include <android-base/stringprintf.h> #include <android-base/strings.h> #include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> #include <binder/PermissionController.h> #include <cutils/multiuser.h> -#include <dirent.h> #include <frameworks/base/cmds/statsd/src/statsd_config.pb.h> #include <frameworks/base/cmds/statsd/src/uid_data.pb.h> #include <private/android_filesystem_config.h> @@ -42,17 +39,13 @@ #include <stdlib.h> #include <sys/system_properties.h> #include <unistd.h> -#include <utils/Looper.h> #include <utils/String16.h> -#include <chrono> using namespace android; using android::base::StringPrintf; using android::util::FIELD_COUNT_REPEATED; -using android::util::FIELD_TYPE_INT64; using android::util::FIELD_TYPE_MESSAGE; -using android::util::ProtoReader; namespace android { namespace os { @@ -77,6 +70,12 @@ static binder::Status exception(uint32_t code, const std::string& msg) { return binder::Status::fromExceptionCode(code, String8(msg.c_str())); } +static bool checkPermission(const char* permission) { + pid_t pid = IPCThreadState::self()->getCallingPid(); + uid_t uid = IPCThreadState::self()->getCallingUid(); + return checkPermissionForIds(permission, pid, uid); +} + binder::Status checkUid(uid_t expectedUid) { uid_t uid = IPCThreadState::self()->getCallingUid(); if (uid == expectedUid || uid == AID_ROOT) { @@ -97,11 +96,11 @@ binder::Status checkDumpAndUsageStats(const String16& packageName) { } // Caller must be granted these permissions - if (!checkCallingPermission(String16(kPermissionDump))) { + if (!checkPermission(kPermissionDump)) { return exception(binder::Status::EX_SECURITY, StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, kPermissionDump)); } - if (!checkCallingPermission(String16(kPermissionUsage))) { + if (!checkPermission(kPermissionUsage)) { return exception(binder::Status::EX_SECURITY, StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, kPermissionUsage)); } @@ -285,7 +284,7 @@ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* rep * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>. */ status_t StatsService::dump(int fd, const Vector<String16>& args) { - if (!checkCallingPermission(String16(kPermissionDump))) { + if (!checkPermission(kPermissionDump)) { return PERMISSION_DENIED; } int lastArg = args.size() - 1; @@ -858,18 +857,8 @@ status_t StatsService::cmd_log_binary_push(int out, const Vector<String8>& args) dprintf(out, "Incorrect number of argument supplied\n"); return UNKNOWN_ERROR; } - android::String16 trainName = android::String16(args[1].c_str()); + string trainName = string(args[1].c_str()); int64_t trainVersion = strtoll(args[2].c_str(), nullptr, 10); - int options = 0; - if (args[3] == "1") { - options = options | IStatsd::FLAG_REQUIRE_STAGING; - } - if (args[4] == "1") { - options = options | IStatsd::FLAG_ROLLBACK_ENABLED; - } - if (args[5] == "1") { - options = options | IStatsd::FLAG_REQUIRE_LOW_LATENCY_MONITOR; - } int32_t state = atoi(args[6].c_str()); vector<int64_t> experimentIds; if (argCount == 8) { @@ -880,7 +869,10 @@ status_t StatsService::cmd_log_binary_push(int out, const Vector<String8>& args) } } dprintf(out, "Logging BinaryPushStateChanged\n"); - sendBinaryPushStateChangedAtom(trainName, trainVersion, options, state, experimentIds); + vector<uint8_t> experimentIdBytes; + writeExperimentIdsToProto(experimentIds, &experimentIdBytes); + LogEvent event(trainName, trainVersion, args[3], args[4], args[5], state, experimentIdBytes, 0); + mProcessor->OnLogEvent(&event); return NO_ERROR; } @@ -914,7 +906,7 @@ status_t StatsService::cmd_clear_puller_cache(int out) { IPCThreadState* ipc = IPCThreadState::self(); VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); - if (checkCallingPermission(String16(kPermissionDump))) { + if (checkPermission(kPermissionDump)) { int cleared = mPullerManager->ForceClearPullerCache(); dprintf(out, "Puller removed %d cached data!\n", cleared); return NO_ERROR; @@ -927,7 +919,7 @@ status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) { IPCThreadState* ipc = IPCThreadState::self(); VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); - if (checkCallingPermission(String16(kPermissionDump))) { + if (checkPermission(kPermissionDump)) { bool enabled = true; if (args.size() >= 2) { enabled = atoi(args[1].c_str()) != 0; @@ -1301,275 +1293,25 @@ Status StatsService::unregisterNativePullAtomCallback(int32_t atomTag) { return Status::ok(); } -Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& trainNameIn, - const int64_t trainVersionCodeIn, - const int options, - const int32_t state, - const std::vector<int64_t>& experimentIdsIn) { - // Note: We skip the usage stats op check here since we do not have a package name. - // This is ok since we are overloading the usage_stats permission. - // This method only sends data, it does not receive it. - pid_t pid = IPCThreadState::self()->getCallingPid(); - uid_t uid = IPCThreadState::self()->getCallingUid(); - // Root, system, and shell always have access - if (uid != AID_ROOT && uid != AID_SYSTEM && uid != AID_SHELL) { - // Caller must be granted these permissions - if (!checkCallingPermission(String16(kPermissionDump))) { - return exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, - kPermissionDump)); - } - if (!checkCallingPermission(String16(kPermissionUsage))) { - return exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, - kPermissionUsage)); - } - } - - bool readTrainInfoSuccess = false; - InstallTrainInfo trainInfoOnDisk; - readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfoOnDisk); - - bool resetExperimentIds = false; - int64_t trainVersionCode = trainVersionCodeIn; - std::string trainNameUtf8 = std::string(String8(trainNameIn).string()); - if (readTrainInfoSuccess) { - // Keep the old train version if we received an empty version. - if (trainVersionCodeIn == -1) { - trainVersionCode = trainInfoOnDisk.trainVersionCode; - } else if (trainVersionCodeIn != trainInfoOnDisk.trainVersionCode) { - // Reset experiment ids if we receive a new non-empty train version. - resetExperimentIds = true; - } - - // Keep the old train name if we received an empty train name. - if (trainNameUtf8.size() == 0) { - trainNameUtf8 = trainInfoOnDisk.trainName; - } else if (trainNameUtf8 != trainInfoOnDisk.trainName) { - // Reset experiment ids if we received a new valid train name. - resetExperimentIds = true; - } - - // Reset if we received a different experiment id. - if (!experimentIdsIn.empty() && - (trainInfoOnDisk.experimentIds.empty() || - experimentIdsIn[0] != trainInfoOnDisk.experimentIds[0])) { - resetExperimentIds = true; - } - } - - // Find the right experiment IDs - std::vector<int64_t> experimentIds; - if (resetExperimentIds || !readTrainInfoSuccess) { - experimentIds = experimentIdsIn; - } else { - experimentIds = trainInfoOnDisk.experimentIds; - } - - if (!experimentIds.empty()) { - int64_t firstId = experimentIds[0]; - switch (state) { - case android::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALL_SUCCESS: - experimentIds.push_back(firstId + 1); - break; - case android::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_INITIATED: - experimentIds.push_back(firstId + 2); - break; - case android::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_SUCCESS: - experimentIds.push_back(firstId + 3); - break; - } - } - - // Flatten the experiment IDs to proto - vector<uint8_t> experimentIdsProtoBuffer; - writeExperimentIdsToProto(experimentIds, &experimentIdsProtoBuffer); - StorageManager::writeTrainInfo(trainVersionCode, trainNameUtf8, state, experimentIds); - - userid_t userId = multiuser_get_user_id(uid); - bool requiresStaging = options & IStatsd::FLAG_REQUIRE_STAGING; - bool rollbackEnabled = options & IStatsd::FLAG_ROLLBACK_ENABLED; - bool requiresLowLatencyMonitor = options & IStatsd::FLAG_REQUIRE_LOW_LATENCY_MONITOR; - LogEvent event(trainNameUtf8, trainVersionCode, requiresStaging, rollbackEnabled, - requiresLowLatencyMonitor, state, experimentIdsProtoBuffer, userId); - mProcessor->OnLogEvent(&event); - return Status::ok(); -} - -Status StatsService::sendWatchdogRollbackOccurredAtom(const int32_t rollbackTypeIn, - const android::String16& packageNameIn, - const int64_t packageVersionCodeIn, - const int32_t rollbackReasonIn, - const android::String16& - failingPackageNameIn) { - // Note: We skip the usage stats op check here since we do not have a package name. - // This is ok since we are overloading the usage_stats permission. - // This method only sends data, it does not receive it. - pid_t pid = IPCThreadState::self()->getCallingPid(); - uid_t uid = IPCThreadState::self()->getCallingUid(); - // Root, system, and shell always have access - if (uid != AID_ROOT && uid != AID_SYSTEM && uid != AID_SHELL) { - // Caller must be granted these permissions - if (!checkCallingPermission(String16(kPermissionDump))) { - return exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, - kPermissionDump)); - } - if (!checkCallingPermission(String16(kPermissionUsage))) { - return exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, - kPermissionUsage)); - } - } - - android::util::stats_write(android::util::WATCHDOG_ROLLBACK_OCCURRED, - rollbackTypeIn, String8(packageNameIn).string(), packageVersionCodeIn, - rollbackReasonIn, String8(failingPackageNameIn).string()); - - // Fast return to save disk read. - if (rollbackTypeIn != android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS - && rollbackTypeIn != - android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE) { - return Status::ok(); - } - - bool readTrainInfoSuccess = false; - InstallTrainInfo trainInfoOnDisk; - readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfoOnDisk); - - if (!readTrainInfoSuccess) { - return Status::ok(); - } - std::vector<int64_t> experimentIds = trainInfoOnDisk.experimentIds; - if (experimentIds.empty()) { - return Status::ok(); - } - switch (rollbackTypeIn) { - case android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE: - experimentIds.push_back(experimentIds[0] + 4); - break; - case android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS: - experimentIds.push_back(experimentIds[0] + 5); - break; - } - StorageManager::writeTrainInfo(trainInfoOnDisk.trainVersionCode, trainInfoOnDisk.trainName, - trainInfoOnDisk.status, experimentIds); - return Status::ok(); -} - - Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) { ENFORCE_UID(AID_SYSTEM); // TODO: add verifier permission + experimentIdsOut->clear(); // Read the latest train info - InstallTrainInfo trainInfo; - if (!StorageManager::readTrainInfo(trainInfo)) { + vector<InstallTrainInfo> trainInfoList = StorageManager::readAllTrainInfo(); + if (trainInfoList.empty()) { // No train info means no experiment IDs, return an empty list - experimentIdsOut->clear(); return Status::ok(); } // Copy the experiment IDs to the out vector - experimentIdsOut->assign(trainInfo.experimentIds.begin(), trainInfo.experimentIds.end()); - return Status::ok(); -} - -hardware::Return<void> StatsService::reportSpeakerImpedance( - const SpeakerImpedance& speakerImpedance) { - android::util::stats_write(android::util::SPEAKER_IMPEDANCE_REPORTED, - speakerImpedance.speakerLocation, speakerImpedance.milliOhms); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportHardwareFailed(const HardwareFailed& hardwareFailed) { - android::util::stats_write(android::util::HARDWARE_FAILED, int32_t(hardwareFailed.hardwareType), - hardwareFailed.hardwareLocation, int32_t(hardwareFailed.errorCode)); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportPhysicalDropDetected( - const PhysicalDropDetected& physicalDropDetected) { - android::util::stats_write(android::util::PHYSICAL_DROP_DETECTED, - int32_t(physicalDropDetected.confidencePctg), physicalDropDetected.accelPeak, - physicalDropDetected.freefallDuration); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportChargeCycles(const ChargeCycles& chargeCycles) { - std::vector<int32_t> buckets = chargeCycles.cycleBucket; - int initialSize = buckets.size(); - for (int i = 0; i < 10 - initialSize; i++) { - buckets.push_back(-1); // Push -1 for buckets that do not exist. + for (InstallTrainInfo& trainInfo : trainInfoList) { + experimentIdsOut->insert(experimentIdsOut->end(), + trainInfo.experimentIds.begin(), + trainInfo.experimentIds.end()); } - android::util::stats_write(android::util::CHARGE_CYCLES_REPORTED, buckets[0], buckets[1], - buckets[2], buckets[3], buckets[4], buckets[5], buckets[6], buckets[7], buckets[8], - buckets[9]); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportBatteryHealthSnapshot( - const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) { - android::util::stats_write(android::util::BATTERY_HEALTH_SNAPSHOT, - int32_t(batteryHealthSnapshotArgs.type), batteryHealthSnapshotArgs.temperatureDeciC, - batteryHealthSnapshotArgs.voltageMicroV, batteryHealthSnapshotArgs.currentMicroA, - batteryHealthSnapshotArgs.openCircuitVoltageMicroV, - batteryHealthSnapshotArgs.resistanceMicroOhm, batteryHealthSnapshotArgs.levelPercent); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportSlowIo(const SlowIo& slowIo) { - android::util::stats_write(android::util::SLOW_IO, int32_t(slowIo.operation), slowIo.count); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportBatteryCausedShutdown( - const BatteryCausedShutdown& batteryCausedShutdown) { - android::util::stats_write(android::util::BATTERY_CAUSED_SHUTDOWN, - batteryCausedShutdown.voltageMicroV); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportUsbPortOverheatEvent( - const UsbPortOverheatEvent& usbPortOverheatEvent) { - android::util::stats_write(android::util::USB_PORT_OVERHEAT_EVENT_REPORTED, - usbPortOverheatEvent.plugTemperatureDeciC, usbPortOverheatEvent.maxTemperatureDeciC, - usbPortOverheatEvent.timeToOverheat, usbPortOverheatEvent.timeToHysteresis, - usbPortOverheatEvent.timeToInactive); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportSpeechDspStat( - const SpeechDspStat& speechDspStat) { - android::util::stats_write(android::util::SPEECH_DSP_STAT_REPORTED, - speechDspStat.totalUptimeMillis, speechDspStat.totalDowntimeMillis, - speechDspStat.totalCrashCount, speechDspStat.totalRecoverCount); - - return hardware::Void(); -} - -hardware::Return<void> StatsService::reportVendorAtom(const VendorAtom& vendorAtom) { - std::string reverseDomainName = (std::string) vendorAtom.reverseDomainName; - if (vendorAtom.atomId < 100000 || vendorAtom.atomId >= 200000) { - ALOGE("Atom ID %ld is not a valid vendor atom ID", (long) vendorAtom.atomId); - return hardware::Void(); - } - if (reverseDomainName.length() > 50) { - ALOGE("Vendor atom reverse domain name %s is too long.", reverseDomainName.c_str()); - return hardware::Void(); - } - LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), vendorAtom); - mProcessor->OnLogEvent(&event); - - return hardware::Void(); + return Status::ok(); } void StatsService::binderDied(const wp <IBinder>& who) { diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index f2079d9f278f..0527d435fdf4 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -27,8 +27,6 @@ #include "shell/ShellSubscriber.h" #include "statscompanion_util.h" -#include <android/frameworks/stats/1.0/IStats.h> -#include <android/frameworks/stats/1.0/types.h> #include <android/os/BnStatsd.h> #include <android/os/IPendingIntentRef.h> #include <android/os/IStatsCompanionService.h> @@ -37,13 +35,10 @@ #include <binder/ParcelFileDescriptor.h> #include <utils/Looper.h> -#include <deque> #include <mutex> using namespace android; -using namespace android::base; using namespace android::binder; -using namespace android::frameworks::stats::V1_0; using namespace android::os; using namespace std; @@ -51,10 +46,7 @@ namespace android { namespace os { namespace statsd { -using android::hardware::Return; - class StatsService : public BnStatsd, - public IStats, public IBinder::DeathRecipient { public: StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue); @@ -195,85 +187,10 @@ public: virtual Status unregisterNativePullAtomCallback(int32_t atomTag) override; /** - * Binder call to log BinaryPushStateChanged atom. - */ - virtual Status sendBinaryPushStateChangedAtom( - const android::String16& trainNameIn, - const int64_t trainVersionCodeIn, - const int options, - const int32_t state, - const std::vector<int64_t>& experimentIdsIn) override; - - /** - * Binder call to log WatchdogRollbackOccurred atom. - */ - virtual Status sendWatchdogRollbackOccurredAtom( - const int32_t rollbackTypeIn, - const android::String16& packageNameIn, - const int64_t packageVersionCodeIn, - const int32_t rollbackReasonIn, - const android::String16& failingPackageNameIn) override; - - /** * Binder call to get registered experiment IDs. */ virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut); - /** - * Binder call to get SpeakerImpedance atom. - */ - virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override; - - /** - * Binder call to get HardwareFailed atom. - */ - virtual Return<void> reportHardwareFailed(const HardwareFailed& hardwareFailed) override; - - /** - * Binder call to get PhysicalDropDetected atom. - */ - virtual Return<void> reportPhysicalDropDetected( - const PhysicalDropDetected& physicalDropDetected) override; - - /** - * Binder call to get ChargeCyclesReported atom. - */ - virtual Return<void> reportChargeCycles(const ChargeCycles& chargeCycles) override; - - /** - * Binder call to get BatteryHealthSnapshot atom. - */ - virtual Return<void> reportBatteryHealthSnapshot( - const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) override; - - /** - * Binder call to get SlowIo atom. - */ - virtual Return<void> reportSlowIo(const SlowIo& slowIo) override; - - /** - * Binder call to get BatteryCausedShutdown atom. - */ - virtual Return<void> reportBatteryCausedShutdown( - const BatteryCausedShutdown& batteryCausedShutdown) override; - - /** - * Binder call to get UsbPortOverheatEvent atom. - */ - virtual Return<void> reportUsbPortOverheatEvent( - const UsbPortOverheatEvent& usbPortOverheatEvent) override; - - /** - * Binder call to get Speech DSP state atom. - */ - virtual Return<void> reportSpeechDspStat( - const SpeechDspStat& speechDspStat) override; - - /** - * Binder call to get vendor atom. - */ - virtual Return<void> reportVendorAtom(const VendorAtom& vendorAtom) override; - /** IBinder::DeathRecipient */ virtual void binderDied(const wp<IBinder>& who) override; diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h index bca858e67f13..219695ef5e43 100644 --- a/cmds/statsd/src/anomaly/AlarmMonitor.h +++ b/cmds/statsd/src/anomaly/AlarmMonitor.h @@ -21,8 +21,6 @@ #include <android/os/IStatsCompanionService.h> #include <utils/RefBase.h> -#include <queue> -#include <set> #include <unordered_set> #include <vector> diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h index e9414735b82b..794ee988ef55 100644 --- a/cmds/statsd/src/anomaly/AnomalyTracker.h +++ b/cmds/statsd/src/anomaly/AnomalyTracker.h @@ -16,8 +16,6 @@ #pragma once -#include <memory> // unique_ptr - #include <stdlib.h> #include <gtest/gtest_prod.h> diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp index 4c30c4cb223c..5a4a41d01de6 100644 --- a/cmds/statsd/src/anomaly/subscriber_util.cpp +++ b/cmds/statsd/src/anomaly/subscriber_util.cpp @@ -17,10 +17,6 @@ #define DEBUG false // STOPSHIP if true #include "Log.h" -#include <android/os/IIncidentManager.h> -#include <android/os/IncidentReportArgs.h> -#include <binder/IServiceManager.h> - #include "external/Perfetto.h" #include "subscriber/IncidentdReporter.h" #include "subscriber/SubscriberReporter.h" diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto index 946c55087005..9c875ba7502d 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -24,46 +24,75 @@ option java_outer_classname = "AtomFieldOptions"; import "google/protobuf/descriptor.proto"; enum StateField { - // Default value for fields that are not primary or exclusive state. + // Default value for fields that are not a primary or exclusive state field. STATE_FIELD_UNSET = 0; // Fields that represent the key that the state belongs to. - PRIMARY = 1; + // Used on simple proto fields. Do not use on attribution chains. + PRIMARY_FIELD = 1; // The field that represents the state. It's an exclusive state. - EXCLUSIVE = 2; - + EXCLUSIVE_STATE = 2; + // Used on an attribution chain field to indicate that the first uid is the + // primary field. PRIMARY_FIELD_FIRST_UID = 3; } -// Used to annotate an atom that reprsents a state change. A state change atom must have exactly ONE -// exclusive state field, and any number of primary key fields. -// For example, -// message UidProcessStateChanged { -// optional int32 uid = 1 [(state_field_option).option = PRIMARY]; -// optional android.app.ProcessStateEnum state = 2 [(state_field_option).option = EXCLUSIVE]; +// Used to annotate an atom that represents a state change. A state change atom must have exactly +// ONE exclusive state field, and any number of primary key fields. For example, message +// UidProcessStateChanged { +// optional int32 uid = 1 [(state_field_option).option = PRIMARY_FIELD]; +// optional android.app.ProcessStateEnum state = 2 [(state_field_option).option = +// EXCLUSIVE_STATE]; // } -// Each of this UidProcessStateChanged atom represents a state change for a specific uid. +// Each UidProcessStateChanged atom event represents a state change for a specific uid. // A new state automatically overrides the previous state. // -// If the atom has 2 or more primary fields, it means the combination of the primary fields are -// the primary key. +// If the atom has 2 or more primary fields, it means the combination of the +// primary fields are the primary key. // For example: // message ThreadStateChanged { -// optional int32 pid = 1 [(state_field_option).option = PRIMARY]; -// optional int32 tid = 2 [(state_field_option).option = PRIMARY]; -// optional int32 state = 3 [(state_field_option).option = EXCLUSIVE]; +// optional int32 pid = 1 [(state_field_option).option = PRIMARY_FIELD]; +// optional int32 tid = 2 [(state_field_option).option = PRIMARY_FIELD]; +// optional int32 state = 3 [(state_field_option).option = EXCLUSIVE_STATE]; // } // // Sometimes, there is no primary key field, when the state is GLOBAL. // For example, -// // message ScreenStateChanged { -// optional android.view.DisplayStateEnum state = 1 [(state_field_option).option = EXCLUSIVE]; +// optional android.view.DisplayStateEnum state = 1 [(state_field_option).option = +// EXCLUSIVE_STATE]; // } // -// Only fields of primary types can be annotated. AttributionNode cannot be primary keys (and they -// usually are not). +// For state atoms with attribution chain, sometimes the primary key is the first uid in the chain. +// For example: +// message AudioStateChanged { +// repeated AttributionNode attribution_node = 1 +// [(stateFieldOption).option = PRIMARY_KEY_FIRST_UID]; +// +// enum State { +// OFF = 0; +// ON = 1; +// // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes). +// RESET = 2; +// } +// optional State state = 2 [(stateFieldOption).option = EXCLUSIVE_STATE]; +// } message StateAtomFieldOption { optional StateField option = 1 [default = STATE_FIELD_UNSET]; + + // Note: We cannot annotate directly on the enums because many enums are imported from other + // proto files in the platform. proto-lite cc library does not support annotations unfortunately + + // Knowing the default state value allows state trackers to remove entries that become the + // default state. If there is no default value specified, the default value is unknown, and all + // states will be tracked in memory. + optional int32 default_state_value = 2; + + // A reset state signals all states go to default value. For example, BLE reset means all active + // BLE scans are to be turned off. + optional int32 reset_state_value = 3; + + // If the state change needs to count nesting. + optional bool nested = 4 [default = true]; } // Used to generate StatsLog.write APIs. diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 0906b359e9b9..89b1798587f0 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -127,7 +127,7 @@ message Atom { WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"]; AnomalyDetected anomaly_detected = 46; AppBreadcrumbReported app_breadcrumb_reported = - 47 [(allow_from_any_uid) = true, (module) = "framework"]; + 47 [(allow_from_any_uid) = true, (module) = "statsd"]; AppStartOccurred app_start_occurred = 48 [(module) = "framework"]; AppStartCanceled app_start_canceled = 49 [(module) = "framework"]; AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"]; @@ -188,7 +188,7 @@ message Atom { ServiceStateChanged service_state_changed = 99 [(module) = "framework"]; ServiceLaunchReported service_launch_reported = 100 [(module) = "framework"]; FlagFlipUpdateOccurred flag_flip_update_occurred = 101 [(module) = "framework"]; - BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "framework"]; + BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "statsd"]; DevicePolicyEvent device_policy_event = 103 [(module) = "framework"]; DocsUIFileOperationCanceledReported docs_ui_file_op_canceled = 104 [(module) = "docsui"]; DocsUIFileOperationCopyMoveModeReported docs_ui_file_op_copy_move_mode_reported = @@ -202,7 +202,8 @@ message Atom { DocsUIStartupMsReported docs_ui_startup_ms = 111 [(module) = "docsui"]; DocsUIUserActionReported docs_ui_user_action_reported = 112 [(module) = "docsui"]; WifiEnabledStateChanged wifi_enabled_state_changed = 113 [(module) = "framework"]; - WifiRunningStateChanged wifi_running_state_changed = 114 [(module) = "framework"]; + WifiRunningStateChanged wifi_running_state_changed = 114 + [(module) = "framework", deprecated = true]; AppCompacted app_compacted = 115 [(module) = "framework"]; NetworkDnsEventReported network_dns_event_reported = 116 [(module) = "resolv"]; DocsUIPickerLaunchedFromReported docs_ui_picker_launched_from_reported = @@ -226,14 +227,14 @@ message Atom { GnssNfwNotificationReported gnss_nfw_notification_reported = 131 [(module) = "framework"]; GnssConfigurationReported gnss_configuration_reported = 132 [(module) = "framework"]; UsbPortOverheatEvent usb_port_overheat_event_reported = 133; - NfcErrorOccurred nfc_error_occurred = 134; - NfcStateChanged nfc_state_changed = 135; - NfcBeamOccurred nfc_beam_occurred = 136; - NfcCardemulationOccurred nfc_cardemulation_occurred = 137; - NfcTagOccurred nfc_tag_occurred = 138; - NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139; - SeStateChanged se_state_changed = 140; - SeOmapiReported se_omapi_reported = 141; + NfcErrorOccurred nfc_error_occurred = 134 [(module) = "nfc"]; + NfcStateChanged nfc_state_changed = 135 [(module) = "nfc"]; + NfcBeamOccurred nfc_beam_occurred = 136 [(module) = "nfc"]; + NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"]; + NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"]; + NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"]; + SeStateChanged se_state_changed = 140 [(module) = "secure_element"]; + SeOmapiReported se_omapi_reported = 141 [(module) = "secure_element"]; BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported = 142 [(module) = "framework"]; AttentionManagerServiceResultReported attention_manager_service_result_reported = @@ -378,15 +379,20 @@ message Atom { BootTimeEventUtcTime boot_time_event_utc_time_reported = 241; BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"]; UserspaceRebootReported userspace_reboot_reported = 243; - NotificationReported notification_reported = 244; + NotificationReported notification_reported = 244 [(module) = "framework"]; NotificationPanelReported notification_panel_reported = 245; NotificationChannelModified notification_panel_modified = 246; - IntegrityCheckResultReported integrity_check_result_reported = 247; - IntegrityRulesPushed integrity_rules_pushed = 248; + IntegrityCheckResultReported integrity_check_result_reported = 247 [(module) = "framework"]; + IntegrityRulesPushed integrity_rules_pushed = 248 [(module) = "framework"]; CellBroadcastMessageReported cb_message_reported = 249 [(module) = "cellbroadcast"]; CellBroadcastMessageError cb_message_error = 250 [(module) = "cellbroadcast"]; + WifiHealthStatReported wifi_health_stat_reported = 251 [(module) = "wifi"]; + WifiFailureStatReported wifi_failure_stat_reported = 252 [(module) = "wifi"]; + WifiConnectionResultReported wifi_connection_result_reported = 253 [(module) = "wifi"]; + AppFreezeChanged app_freeze_changed = 254 [(module) = "framework"]; + SdkExtensionStatus sdk_extension_status = 354; } // Pulled events will start at field 10000. @@ -411,8 +417,8 @@ message Atom { CpuActiveTime cpu_active_time = 10016 [(module) = "framework"]; CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework"]; DiskSpace disk_space = 10018 [deprecated=true]; - RemainingBatteryCapacity remaining_battery_capacity = 10019; - FullBatteryCapacity full_battery_capacity = 10020; + RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"]; + FullBatteryCapacity full_battery_capacity = 10020 [(module) = "framework"]; Temperature temperature = 10021 [(module) = "framework"]; BinderCalls binder_calls = 10022 [(module) = "framework"]; BinderCallsExceptions binder_calls_exceptions = 10023 [(module) = "framework"]; @@ -422,7 +428,7 @@ message Atom { AppSize app_size = 10027 [(module) = "framework"]; CategorySize category_size = 10028 [(module) = "framework"]; ProcStats proc_stats = 10029 [(module) = "framework"]; - BatteryVoltage battery_voltage = 10030; + BatteryVoltage battery_voltage = 10030 [(module) = "framework"]; NumFingerprintsEnrolled num_fingerprints_enrolled = 10031 [(module) = "framework"]; DiskIo disk_io = 10032 [(module) = "framework"]; PowerProfile power_profile = 10033 [(module) = "framework"]; @@ -436,9 +442,9 @@ message Atom { DeviceCalculatedPowerBlameOther device_calculated_power_blame_other = 10041 [(module) = "framework"]; ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042 [(module) = "framework"]; - BatteryLevel battery_level = 10043; + BatteryLevel battery_level = 10043 [(module) = "framework"]; BuildInformation build_information = 10044 [(module) = "framework"]; - BatteryCycleCount battery_cycle_count = 10045; + BatteryCycleCount battery_cycle_count = 10045 [(module) = "framework"]; DebugElapsedClock debug_elapsed_clock = 10046 [(module) = "framework"]; DebugFailingElapsedClock debug_failing_elapsed_clock = 10047 [(module) = "framework"]; NumFacesEnrolled num_faces_enrolled = 10048 [(module) = "framework"]; @@ -463,7 +469,7 @@ message Atom { DangerousPermissionStateSampled dangerous_permission_state_sampled = 10067 [(module) = "framework"]; GraphicsStats graphics_stats = 10068; - RuntimeAppOpsAccess runtime_app_ops_access = 10069; + RuntimeAppOpAccess runtime_app_op_access = 10069 [(module) = "framework"]; IonHeapSize ion_heap_size = 10070 [(module) = "framework"]; } @@ -560,7 +566,8 @@ message ThermalThrottlingStateChanged { */ message ScreenStateChanged { // New screen state, from frameworks/base/core/proto/android/view/enums.proto. - optional android.view.DisplayStateEnum state = 1 [(state_field_option).option = EXCLUSIVE]; + optional android.view.DisplayStateEnum state = 1 + [(state_field_option).option = EXCLUSIVE_STATE, (state_field_option).nested = false]; } /** @@ -571,10 +578,11 @@ message ScreenStateChanged { * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java */ message UidProcessStateChanged { - optional int32 uid = 1 [(state_field_option).option = PRIMARY, (is_uid) = true]; + optional int32 uid = 1 [(state_field_option).option = PRIMARY_FIELD, (is_uid) = true]; // The state, from frameworks/base/core/proto/android/app/enums.proto. - optional android.app.ProcessStateEnum state = 2 [(state_field_option).option = EXCLUSIVE]; + optional android.app.ProcessStateEnum state = 2 + [(state_field_option).option = EXCLUSIVE_STATE, (state_field_option).nested = false]; } /** @@ -606,7 +614,7 @@ message ActivityManagerSleepStateChanged { ASLEEP = 1; AWAKE = 2; } - optional State state = 1 [(state_field_option).option = EXCLUSIVE]; + optional State state = 1 [(state_field_option).option = EXCLUSIVE_STATE]; } /** @@ -625,7 +633,7 @@ message MemoryFactorStateChanged { CRITICAL = 4; // critical memory. } - optional State factor = 1 [(state_field_option).option = EXCLUSIVE]; + optional State factor = 1 [(state_field_option).option = EXCLUSIVE_STATE]; } /** @@ -658,6 +666,81 @@ message CachedKillReported { } /** + * Logs the change in wifi health. + * + * Logged from: + * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiDataStall.java + */ +message WifiHealthStatReported { + // duration this stat is obtained over in milliseconds + optional int32 duration_millis = 1; + // whether wifi is classified as sufficient for the user's data traffic, determined + // by whether the calculated throughput exceeds the average demand within |duration_millis| + optional bool is_sufficient = 2; + // whether the calculated throughput is exceeds the minimum required for typical usage + optional bool is_throughput_good = 3; + // whether cellular data is available + optional bool is_cell_data_available = 4; + // the WLAN channel the connected network is on (ie. 2412) + optional int32 frequency = 5; +} + +/** + * Logged when wifi detects a significant change in connection failure rate. + * + * Logged from: frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiHealthMonitor.java + * + */ +message WifiFailureStatReported { + enum AbnormalityType { + UNKNOWN = 0; + SIGNIFICANT_INCREASE = 1; + SIGNIFICANT_DECREASE = 2; + SIMPLY_HIGH = 3; + } + enum FailureType { + FAILURE_UNKNOWN = 0; + FAILURE_CONNECTION = 1; + FAILURE_ASSOCIATION_REJECTION = 2; + FAILURE_ASSOCIATION_TIMEOUT = 3; + FAILURE_AUTHENTICATION = 4; + FAILURE_NON_LOCAL_DISCONNECTION = 5; + FAILURE_SHORT_CONNECTION_DUE_TO_NON_LOCAL_DISCONNECTION = 6; + } + // Reason for uploading this stat + optional AbnormalityType abnormality_type = 1; + // The particular type of failure + optional FailureType failure_type = 2; + // How many times we have encountered this combination of AbnormalityType and FailureType + optional int32 failure_count = 3; +} + +/** + * Logs whether a wifi connection is successful and reasons for failure if it isn't. + * + * Logged from: + * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java + */ +message WifiConnectionResultReported { + enum FailureCode { + FAILURE_UNKNOWN = 0; + FAILURE_ASSOCIATION_TIMEOUT = 1; + FAILURE_ASSOCIATION_REJECTION = 2; + FAILURE_AUTHENTICATION_GENERAL = 3; + FAILURE_AUTHENTICATION_EAP = 4; + FAILURE_DHCP = 5; + FAILURE_NETWORK_DISCONNECTION = 6; + FAILURE_ROAM_TIMEOUT = 7; + } + // true represents a successful connection + optional bool connection_result = 1; + // reason for the connection failure + optional FailureCode failure_code = 2; + // scan rssi before the connection attempt + optional int32 rssi = 3; +} + +/** * Logs when memory stats of a process is reported. * * Logged from: @@ -712,7 +795,8 @@ message ProcessLifeCycleStateChanged { * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java */ message BleScanStateChanged { - repeated AttributionNode attribution_node = 1; + repeated AttributionNode attribution_node = 1 + [(state_field_option).option = PRIMARY_FIELD_FIRST_UID]; enum State { OFF = 0; @@ -720,14 +804,19 @@ message BleScanStateChanged { // RESET indicates all ble stopped. Used when it (re)starts (e.g. after it crashes). RESET = 2; } - optional State state = 2; + optional State state = 2 [ + (state_field_option).option = EXCLUSIVE_STATE, + (state_field_option).default_state_value = 0 /* State.OFF */, + (state_field_option).reset_state_value = 2 /* State.RESET */, + (state_field_option).nested = true + ]; // Does the scan have a filter. - optional bool is_filtered = 3; + optional bool is_filtered = 3 [(state_field_option).option = PRIMARY_FIELD]; // Whether the scan is a CALLBACK_TYPE_FIRST_MATCH scan. Called 'background' scan internally. - optional bool is_first_match = 4; + optional bool is_first_match = 4 [(state_field_option).option = PRIMARY_FIELD]; // Whether the scan set to piggy-back off the results of other scans (SCAN_MODE_OPPORTUNISTIC). - optional bool is_opportunistic = 5; + optional bool is_opportunistic = 5 [(state_field_option).option = PRIMARY_FIELD]; } /** @@ -951,11 +1040,11 @@ message WakelockStateChanged { // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock. // From frameworks/base/core/proto/android/os/enums.proto. - optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).option = PRIMARY]; + optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).option = PRIMARY_FIELD]; ; // The wakelock tag (Called tag in the Java API, sometimes name elsewhere). - optional string tag = 3 [(state_field_option).option = PRIMARY]; + optional string tag = 3 [(state_field_option).option = PRIMARY_FIELD]; enum State { RELEASE = 0; @@ -963,7 +1052,11 @@ message WakelockStateChanged { CHANGE_RELEASE = 2; CHANGE_ACQUIRE = 3; } - optional State state = 4 [(state_field_option).option = EXCLUSIVE]; + optional State state = 4 [ + (state_field_option).option = EXCLUSIVE_STATE, + (state_field_option).default_state_value = 0, + (state_field_option).nested = true + ]; } /** @@ -1168,6 +1261,8 @@ message WifiEnabledStateChanged { } /** + * This atom is deprecated starting in R. + * * Logs when an app causes Wifi to run. In this context, 'to run' means to use Wifi Client Mode. * TODO: Include support for Hotspot, perhaps by using an extra field to denote 'mode'. * Note that Wifi Scanning is monitored separately in WifiScanStateChanged. @@ -1780,6 +1875,8 @@ message WatchdogRollbackOccurred { // Set by RollbackPackageHealthObserver to be the package that is failing when a rollback // is initiated. Empty if the package is unknown. optional string failing_package_name = 5; + + optional TrainExperimentIds experiment_ids = 6 [(log_mode) = MODE_BYTES]; } /** @@ -3147,9 +3244,9 @@ message PictureInPictureStateChanged { * services/core/java/com/android/server/wm/Session.java */ message OverlayStateChanged { - optional int32 uid = 1 [(state_field_option).option = PRIMARY, (is_uid) = true]; + optional int32 uid = 1 [(state_field_option).option = PRIMARY_FIELD, (is_uid) = true]; - optional string package_name = 2 [(state_field_option).option = PRIMARY]; + optional string package_name = 2 [(state_field_option).option = PRIMARY_FIELD]; optional bool using_alert_window = 3; @@ -3157,7 +3254,11 @@ message OverlayStateChanged { ENTERED = 1; EXITED = 2; } - optional State state = 4 [(state_field_option).option = EXCLUSIVE]; + optional State state = 4 [ + (state_field_option).option = EXCLUSIVE_STATE, + (state_field_option).nested = false, + (state_field_option).default_state_value = 2 + ]; } /* @@ -3323,7 +3424,7 @@ message LmkKillOccurred { */ message AppDied { // timestamp(elapsedRealtime) of record creation - optional uint64 timestamp_millis = 1 [(state_field_option).option = EXCLUSIVE]; + optional uint64 timestamp_millis = 1 [(state_field_option).option = EXCLUSIVE_STATE]; } /** @@ -3612,6 +3713,7 @@ message FlagFlipUpdateOccurred { /** * Potential experiment ids that goes with a train install. + * Should be kept in sync with experiment_ids.proto. */ message TrainExperimentIds { repeated int64 experiment_id = 1; @@ -3671,6 +3773,8 @@ message BinaryPushStateChanged { // user id optional int32 user_id = 8; optional int32 reason = 9; + // Whether or not this is a rollback event + optional bool is_rollback = 10; } /* Test atom, is not logged anywhere */ @@ -3843,7 +3947,7 @@ message PrivacyIndicatorsInteracted { DIALOG_LINE_ITEM = 5; } - optional Type type = 1 [(state_field_option).option = EXCLUSIVE]; + optional Type type = 1 [(state_field_option).option = EXCLUSIVE_STATE]; // Used if the type is LINE_ITEM optional string package_name = 2; @@ -4153,6 +4257,9 @@ message BootTimeEventDuration { // Time since last factory reset. // Logged from bootstat. FACTORY_RESET_TIME_SINCE_RESET = 18; + // Init's total time spent for completing the 1st stage. + // Logged from bootstat. + ANDROID_INIT_STAGE_1 = 19; } // Type of the event. @@ -4180,19 +4287,19 @@ message BootTimeEventElapsedTime { // BOOT_COMPLETE for device with no encryption. BOOT_COMPLETE_NO_ENCRYPTION = 4; // Adjusted BOOT_COMPLETE for encrypted device extracting decryption time. - BOOT_COMPLETE_POST_DESCRYPT = 5; + BOOT_COMPLETE_POST_DECRYPT = 5; // BOOT_COMPLETE after factory reset. FACTORY_RESET_BOOT_COMPLETE = 6; // BOOT_COMPLETE_NO_ENCRYPTION after factory reset. FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION = 7; - // BOOT_COMPLETE_POST_DESCRYPT after factory reset. - FACTORY_RESET_BOOT_COMPLETE_POST_DESCRYPT = 8; + // BOOT_COMPLETE_POST_DECRYPT after factory reset. + FACTORY_RESET_BOOT_COMPLETE_POST_DECRYPT = 8; // BOOT_COMPLETE after OTA. OTA_BOOT_COMPLETE = 9; // BOOT_COMPLETE_NO_ENCRYPTION after OTA. OTA_BOOT_COMPLETE_NO_ENCRYPTION = 10; - // BOOT_COMPLETE_POST_DESCRYPT after OTA. - OTA_BOOT_COMPLETE_POST_DESCRYPT = 11; + // BOOT_COMPLETE_POST_DECRYPT after OTA. + OTA_BOOT_COMPLETE_POST_DECRYPT = 11; // Time when the system starts sending LOCKED_BOOT_COMPLETED broadcast. // Logged from f/b/services/.../UserController.java FRAMEWORK_LOCKED_BOOT_COMPLETED = 12; @@ -6385,6 +6492,8 @@ message PermissionGrantRequestResultReported { USER_DENIED_WITH_PREJUDICE_IN_SETTINGS = 14; // permission was automatically revoked after one-time permission expired AUTO_ONE_TIME_PERMISSION_REVOKED = 15; + // permission was automatically revoked for unused app + AUTO_UNUSED_APP_PERMISSION_REVOKED = 16; } // The result of the permission grant optional Result result = 6; @@ -7410,6 +7519,9 @@ message GrantPermissionsActivityButtonActions { // Button clicked by user - same as bit flags in buttons_presented with only single bit set optional int32 button_clicked = 5; + + // id which identifies single session of user interacting with permission controller + optional int64 session_id = 6; } /** @@ -7462,6 +7574,28 @@ message AppPermissionFragmentActionReported { // The result of the permission grant optional bool permission_granted = 6; + + // State of Permission Flags after grant as per android.content.pm.PermissionFlags + optional int32 permission_flags = 7; + + enum Button { + UNDEFINED = 0; + // Allow button + ALLOW = 1; + // Deny button + DENY = 2; + // Ask every time button + ASK_EVERY_TIME = 3; + // Allow all the time button + ALLOW_ALWAYS = 4; + // Allow only while using the app button + ALLOW_FOREGROUND = 5; + // Same is Deny button but shown in while in use dialog + DENY_FOREGROUND = 6; + } + + // Button pressed in the dialog + optional Button button_pressed = 8; } /** @@ -8054,15 +8188,15 @@ message GraphicsStats { /** * Message related to dangerous (runtime) app ops access */ -message RuntimeAppOpsAccess { +message RuntimeAppOpAccess { // Uid of the package accessing app op optional int32 uid = 1 [(is_uid) = true]; // Name of the package accessing app op optional string package_name = 2; - // operation id; maps to the OP_* constants in AppOpsManager.java - optional int32 op_id = 3; + // operation string id per OPSTR_ constants in AppOpsManager.java + optional string op = 3; // feature id; provided by developer when accessing related API, limited at 50 chars by API. // Features must be provided through manifest using <feature> tag available in R and above. @@ -8212,3 +8346,52 @@ message CellBroadcastMessageError { // Exception message (or log message) associated with the error (max 1000 chars) optional string exception_message = 2; } + +/** + * Logs when the SDK Extensions test app has polled the current version. + * This is atom ID 354. + * + * Logged from: + * vendor/google_testing/integration/packages/apps/SdkExtensionsTestApp/ + */ +message SdkExtensionStatus { + enum ApiCallStatus { + CALL_NOT_ATTEMPTED = 0; + CALL_SUCCESSFUL = 1; + CALL_FAILED = 2; + } + + optional ApiCallStatus result = 1; + + // The R extension version, i.e. android.os.ext.SdkExtension.getExtensionVersion(R). + optional int32 r_extension_version = 2; + + // A number identifying which particular symbol's call failed, if any. 0 means no missing symbol. + // "Failed" here can mean a symbol that wasn't meant to be visible was, or the other way around. + optional int32 failed_call_symbol = 3; +} + +/** + * Logs when an app is frozen or unfrozen. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/am/CachedAppOptimizer.java + */ +message AppFreezeChanged { + // The type of event. + enum Action { + UNKNOWN = 0; + FREEZE_APP = 1; + UNFREEZE_APP = 2; + } + optional Action action = 1; + + // Pid of the process being frozen. + optional int32 pid = 2; + + // Name of the process being frozen. + optional string process_name = 3; + + // Time since last unfrozen. + optional int64 time_unfrozen_millis = 4; +} diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp index 69aae3d1e31c..2d7f912dac84 100644 --- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp +++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp @@ -18,15 +18,10 @@ #include "Log.h" #include "CombinationConditionTracker.h" -#include <log/logprint.h> - namespace android { namespace os { namespace statsd { -using std::map; -using std::string; -using std::unique_ptr; using std::unordered_map; using std::vector; diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h index e94ea6586f05..26de88860ab4 100644 --- a/cmds/statsd/src/condition/ConditionTracker.h +++ b/cmds/statsd/src/condition/ConditionTracker.h @@ -21,10 +21,8 @@ #include "matchers/LogMatchingTracker.h" #include "matchers/matcher_util.h" -#include <log/logprint.h> #include <utils/RefBase.h> -#include <unordered_set> #include <unordered_map> namespace android { diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp index 4f44a69ba980..c542032b48ea 100644 --- a/cmds/statsd/src/condition/ConditionWizard.cpp +++ b/cmds/statsd/src/condition/ConditionWizard.cpp @@ -14,14 +14,11 @@ * limitations under the License. */ #include "ConditionWizard.h" -#include <unordered_set> namespace android { namespace os { namespace statsd { -using std::map; -using std::string; using std::vector; ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters, diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp index 0c92149f4c96..61760f3e29b2 100644 --- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp +++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp @@ -24,11 +24,7 @@ namespace android { namespace os { namespace statsd { -using std::map; -using std::string; -using std::unique_ptr; using std::unordered_map; -using std::vector; SimpleConditionTracker::SimpleConditionTracker( const ConfigKey& key, const int64_t& id, const int index, diff --git a/cmds/statsd/src/condition/StateConditionTracker.cpp b/cmds/statsd/src/condition/StateConditionTracker.cpp index 7f3eeddba831..d19a1761ac00 100644 --- a/cmds/statsd/src/condition/StateConditionTracker.cpp +++ b/cmds/statsd/src/condition/StateConditionTracker.cpp @@ -23,8 +23,6 @@ namespace android { namespace os { namespace statsd { -using std::string; -using std::unordered_set; using std::vector; StateConditionTracker::StateConditionTracker(const ConfigKey& key, const int64_t& id, const int index, diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp index 35e03e45c785..60b8c53e91e1 100644 --- a/cmds/statsd/src/condition/condition_util.cpp +++ b/cmds/statsd/src/condition/condition_util.cpp @@ -18,11 +18,6 @@ #include "condition_util.h" -#include <log/event_tag_map.h> -#include <log/log_event_list.h> -#include <log/logprint.h> -#include <utils/Errors.h> -#include <unordered_map> #include "../matchers/matcher_util.h" #include "ConditionTracker.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" @@ -32,9 +27,6 @@ namespace android { namespace os { namespace statsd { -using std::set; -using std::string; -using std::unordered_map; using std::vector; diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h index 54e77701b7dc..dcd5e52feefd 100644 --- a/cmds/statsd/src/config/ConfigListener.h +++ b/cmds/statsd/src/config/ConfigListener.h @@ -19,14 +19,12 @@ #include "config/ConfigKey.h" #include <utils/RefBase.h> -#include <string> namespace android { namespace os { namespace statsd { using android::RefBase; -using std::string; /** * Callback for different subsystems inside statsd to implement to find out diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp index 972adf7d4d05..986955bc5f39 100644 --- a/cmds/statsd/src/config/ConfigManager.cpp +++ b/cmds/statsd/src/config/ConfigManager.cpp @@ -25,8 +25,6 @@ #include "stats_util.h" #include "stats_log_util.h" -#include <android-base/file.h> -#include <dirent.h> #include <stdio.h> #include <vector> #include "android-base/stringprintf.h" @@ -35,9 +33,7 @@ namespace android { namespace os { namespace statsd { -using std::map; using std::pair; -using std::set; using std::string; using std::vector; diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h index 88e864a2520b..2095173e8959 100644 --- a/cmds/statsd/src/config/ConfigManager.h +++ b/cmds/statsd/src/config/ConfigManager.h @@ -20,9 +20,7 @@ #include "config/ConfigListener.h" #include <android/os/IPendingIntentRef.h> -#include <map> #include <mutex> -#include <set> #include <string> #include <stdio.h> diff --git a/cmds/statsd/src/external/PowerStatsPuller.h b/cmds/statsd/src/experiment_ids.proto index 6f15bd68fa94..c2036314cf58 100644 --- a/cmds/statsd/src/external/PowerStatsPuller.h +++ b/cmds/statsd/src/experiment_ids.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,25 +14,16 @@ * limitations under the License. */ -#pragma once +syntax = "proto2"; -#include "StatsPuller.h" +package android.os.statsd; -namespace android { -namespace os { -namespace statsd { +option java_package = "com.android.internal.os"; +option java_outer_classname = "ExperimentIdsProto"; -/** - * Reads hal for power.stats - */ -class PowerStatsPuller : public StatsPuller { -public: - PowerStatsPuller(); - -private: - bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; -}; - -} // namespace statsd -} // namespace os -} // namespace android +// StatsLogProcessor uses the proto to parse experiment ids from +// BinaryPushStateChanged atoms. This needs to be in sync with +// TrainExperimentIds in atoms.proto. +message ExperimentIds { + repeated int64 experiment_id = 1; +} diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp deleted file mode 100644 index 3229ba82fe3c..000000000000 --- a/cmds/statsd/src/external/GpuStatsPuller.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "GpuStatsPuller.h" - -#include <binder/IServiceManager.h> -#include <graphicsenv/GpuStatsInfo.h> -#include <graphicsenv/IGpuService.h> - -#include "logd/LogEvent.h" - -#include "stats_log_util.h" -#include "statslog.h" - -namespace android { -namespace os { -namespace statsd { - -using android::util::ProtoReader; - -GpuStatsPuller::GpuStatsPuller(const int tagId) : StatsPuller(tagId) { -} - -static sp<IGpuService> getGpuService() { - const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu")); - if (!binder) { - ALOGE("Failed to get gpu service"); - return nullptr; - } - - return interface_cast<IGpuService>(binder); -} - -static bool pullGpuStatsGlobalInfo(const sp<IGpuService>& gpuService, - std::vector<std::shared_ptr<LogEvent>>* data) { - std::vector<GpuStatsGlobalInfo> stats; - status_t status = gpuService->getGpuStatsGlobalInfo(&stats); - if (status != OK) { - return false; - } - - data->clear(); - data->reserve(stats.size()); - for (const auto& info : stats) { - std::shared_ptr<LogEvent> event = make_shared<LogEvent>( - android::util::GPU_STATS_GLOBAL_INFO, getWallClockNs(), getElapsedRealtimeNs()); - if (!event->write(info.driverPackageName)) return false; - if (!event->write(info.driverVersionName)) return false; - if (!event->write((int64_t)info.driverVersionCode)) return false; - if (!event->write(info.driverBuildTime)) return false; - if (!event->write((int64_t)info.glLoadingCount)) return false; - if (!event->write((int64_t)info.glLoadingFailureCount)) return false; - if (!event->write((int64_t)info.vkLoadingCount)) return false; - if (!event->write((int64_t)info.vkLoadingFailureCount)) return false; - if (!event->write(info.vulkanVersion)) return false; - if (!event->write(info.cpuVulkanVersion)) return false; - if (!event->write(info.glesVersion)) return false; - if (!event->write((int64_t)info.angleLoadingCount)) return false; - if (!event->write((int64_t)info.angleLoadingFailureCount)) return false; - event->init(); - data->emplace_back(event); - } - - return true; -} - -static bool pullGpuStatsAppInfo(const sp<IGpuService>& gpuService, - std::vector<std::shared_ptr<LogEvent>>* data) { - std::vector<GpuStatsAppInfo> stats; - status_t status = gpuService->getGpuStatsAppInfo(&stats); - if (status != OK) { - return false; - } - - data->clear(); - data->reserve(stats.size()); - for (const auto& info : stats) { - std::shared_ptr<LogEvent> event = make_shared<LogEvent>( - android::util::GPU_STATS_APP_INFO, getWallClockNs(), getElapsedRealtimeNs()); - if (!event->write(info.appPackageName)) return false; - if (!event->write((int64_t)info.driverVersionCode)) return false; - if (!event->writeBytes(int64VectorToProtoByteString(info.glDriverLoadingTime))) { - return false; - } - if (!event->writeBytes(int64VectorToProtoByteString(info.vkDriverLoadingTime))) { - return false; - } - if (!event->writeBytes(int64VectorToProtoByteString(info.angleDriverLoadingTime))) { - return false; - } - if (!event->write(info.cpuVulkanInUse)) return false; - if (!event->write(info.falsePrerotation)) return false; - if (!event->write(info.gles1InUse)) return false; - event->init(); - data->emplace_back(event); - } - - return true; -} - -bool GpuStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) { - const sp<IGpuService> gpuService = getGpuService(); - if (!gpuService) { - return false; - } - - switch (mTagId) { - case android::util::GPU_STATS_GLOBAL_INFO: - return pullGpuStatsGlobalInfo(gpuService, data); - case android::util::GPU_STATS_APP_INFO: - return pullGpuStatsAppInfo(gpuService, data); - default: - break; - } - - return false; -} - -static std::string protoOutputStreamToByteString(ProtoOutputStream& proto) { - if (!proto.size()) return ""; - - std::string byteString; - sp<ProtoReader> reader = proto.data(); - while (reader->readBuffer() != nullptr) { - const size_t toRead = reader->currentToRead(); - byteString.append((char*)reader->readBuffer(), toRead); - reader->move(toRead); - } - - if (byteString.size() != proto.size()) return ""; - - return byteString; -} - -std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) { - if (value.empty()) return ""; - - ProtoOutputStream proto; - for (const auto& ele : value) { - proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED | - 1 /* field id */, - (long long)ele); - } - - return protoOutputStreamToByteString(proto); -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/GpuStatsPuller.h b/cmds/statsd/src/external/GpuStatsPuller.h deleted file mode 100644 index 2da199c51e0f..000000000000 --- a/cmds/statsd/src/external/GpuStatsPuller.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "StatsPuller.h" - -namespace android { -namespace os { -namespace statsd { - -/** - * Pull GpuStats from GpuService. - */ -class GpuStatsPuller : public StatsPuller { -public: - explicit GpuStatsPuller(const int tagId); - bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) override; -}; - -// convert a int64_t vector into a byte string for proto message like: -// message RepeatedInt64Wrapper { -// repeated int64 value = 1; -// } -std::string int64VectorToProtoByteString(const std::vector<int64_t>& value); - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/Perfetto.cpp b/cmds/statsd/src/external/Perfetto.cpp index 0c4c3301e61e..85b660efc956 100644 --- a/cmds/statsd/src/external/Perfetto.cpp +++ b/cmds/statsd/src/external/Perfetto.cpp @@ -21,12 +21,8 @@ #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert #include <android-base/unique_fd.h> -#include <errno.h> -#include <fcntl.h> #include <inttypes.h> -#include <sys/types.h> #include <sys/wait.h> -#include <unistd.h> #include <string> diff --git a/cmds/statsd/src/external/PowerStatsPuller.cpp b/cmds/statsd/src/external/PowerStatsPuller.cpp deleted file mode 100644 index dc69b78f0329..000000000000 --- a/cmds/statsd/src/external/PowerStatsPuller.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define DEBUG false // STOPSHIP if true -#include "Log.h" - -#include <android/hardware/power/stats/1.0/IPowerStats.h> - -#include <vector> - -#include "PowerStatsPuller.h" -#include "statslog.h" -#include "stats_log_util.h" - -using android::hardware::hidl_vec; -using android::hardware::power::stats::V1_0::IPowerStats; -using android::hardware::power::stats::V1_0::EnergyData; -using android::hardware::power::stats::V1_0::RailInfo; -using android::hardware::power::stats::V1_0::Status; -using android::hardware::Return; -using android::hardware::Void; - -using std::make_shared; -using std::shared_ptr; - -namespace android { -namespace os { -namespace statsd { - -static sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHal = nullptr; -static std::mutex gPowerStatsHalMutex; -static bool gPowerStatsExist = true; // Initialized to ensure making a first attempt. -static std::vector<RailInfo> gRailInfo; - -struct PowerStatsPullerDeathRecipient : virtual public hardware::hidl_death_recipient { - virtual void serviceDied(uint64_t cookie, - const wp<android::hidl::base::V1_0::IBase>& who) override { - // The HAL just died. Reset all handles to HAL services. - std::lock_guard<std::mutex> lock(gPowerStatsHalMutex); - gPowerStatsHal = nullptr; - } -}; - -static sp<PowerStatsPullerDeathRecipient> gDeathRecipient = new PowerStatsPullerDeathRecipient(); - -static bool getPowerStatsHalLocked() { - if (gPowerStatsHal == nullptr && gPowerStatsExist) { - gPowerStatsHal = android::hardware::power::stats::V1_0::IPowerStats::getService(); - if (gPowerStatsHal == nullptr) { - ALOGW("Couldn't load power.stats HAL service"); - gPowerStatsExist = false; - } else { - // Link death recipient to power.stats service handle - hardware::Return<bool> linked = gPowerStatsHal->linkToDeath(gDeathRecipient, 0); - if (!linked.isOk()) { - ALOGE("Transaction error in linking to power.stats HAL death: %s", - linked.description().c_str()); - gPowerStatsHal = nullptr; - return false; - } else if (!linked) { - ALOGW("Unable to link to power.stats HAL death notifications"); - // We should still continue even though linking failed - } - } - } - return gPowerStatsHal != nullptr; -} - -PowerStatsPuller::PowerStatsPuller() : StatsPuller(android::util::ON_DEVICE_POWER_MEASUREMENT) { -} - -bool PowerStatsPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { - std::lock_guard<std::mutex> lock(gPowerStatsHalMutex); - - if (!getPowerStatsHalLocked()) { - return false; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - - data->clear(); - - // Pull getRailInfo if necessary - if (gRailInfo.empty()) { - bool resultSuccess = true; - Return<void> ret = gPowerStatsHal->getRailInfo( - [&resultSuccess](const hidl_vec<RailInfo> &list, Status status) { - resultSuccess = (status == Status::SUCCESS || status == Status::NOT_SUPPORTED); - if (status != Status::SUCCESS) return; - - gRailInfo.reserve(list.size()); - for (size_t i = 0; i < list.size(); ++i) { - gRailInfo.push_back(list[i]); - } - }); - if (!resultSuccess || !ret.isOk()) { - ALOGE("power.stats getRailInfo() failed. Description: %s", ret.description().c_str()); - gPowerStatsHal = nullptr; - return false; - } - // If SUCCESS but empty, or if NOT_SUPPORTED, then never try again. - if (gRailInfo.empty()) { - ALOGE("power.stats has no rail information"); - gPowerStatsExist = false; // No rail info, so never try again. - gPowerStatsHal = nullptr; - return false; - } - } - - // Pull getEnergyData and write the data out - const hidl_vec<uint32_t> desiredRailIndices; // Empty vector indicates we want all. - bool resultSuccess = true; - Return<void> ret = gPowerStatsHal->getEnergyData(desiredRailIndices, - [&data, wallClockTimestampNs, elapsedTimestampNs, &resultSuccess] - (hidl_vec<EnergyData> energyDataList, Status status) { - resultSuccess = (status == Status::SUCCESS); - if (!resultSuccess) return; - - for (size_t i = 0; i < energyDataList.size(); i++) { - const EnergyData& energyData = energyDataList[i]; - - if (energyData.index >= gRailInfo.size()) { - ALOGE("power.stats getEnergyData() returned an invalid rail index %u.", - energyData.index); - resultSuccess = false; - return; - } - const RailInfo& rail = gRailInfo[energyData.index]; - - auto ptr = make_shared<LogEvent>(android::util::ON_DEVICE_POWER_MEASUREMENT, - wallClockTimestampNs, elapsedTimestampNs); - ptr->write(rail.subsysName); - ptr->write(rail.railName); - ptr->write(energyData.timestamp); - ptr->write(energyData.energy); - ptr->init(); - data->push_back(ptr); - - VLOG("power.stat: %s.%s: %llu, %llu", - rail.subsysName.c_str(), - rail.railName.c_str(), - (unsigned long long)energyData.timestamp, - (unsigned long long)energyData.energy); - } - }); - if (!resultSuccess || !ret.isOk()) { - ALOGE("power.stats getEnergyData() failed. Description: %s", ret.description().c_str()); - gPowerStatsHal = nullptr; - return false; - } - return true; -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/PullDataReceiver.h b/cmds/statsd/src/external/PullDataReceiver.h index d2193f41b80a..dd5c0cfa04c1 100644 --- a/cmds/statsd/src/external/PullDataReceiver.h +++ b/cmds/statsd/src/external/PullDataReceiver.h @@ -15,8 +15,6 @@ */ #pragma once -#include <utils/String16.h> -#include <unordered_map> #include <utils/RefBase.h> #include "StatsPuller.h" #include "logd/LogEvent.h" diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp deleted file mode 100644 index 75b63f4b5f9e..000000000000 --- a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define DEBUG false // STOPSHIP if true -#include "Log.h" - -#include <android/hardware/health/2.0/IHealth.h> -#include <healthhalutils/HealthHalUtils.h> -#include "external/ResourceHealthManagerPuller.h" -#include "external/StatsPuller.h" - -#include "ResourceHealthManagerPuller.h" -#include "logd/LogEvent.h" -#include "stats_log_util.h" -#include "statslog.h" - -using android::hardware::hidl_vec; -using android::hardware::Return; -using android::hardware::Void; -using android::hardware::health::V2_0::get_health_service; -using android::hardware::health::V2_0::HealthInfo; -using android::hardware::health::V2_0::IHealth; -using android::hardware::health::V2_0::Result; - -using std::make_shared; -using std::shared_ptr; - -namespace android { -namespace os { -namespace statsd { - -sp<android::hardware::health::V2_0::IHealth> gHealthHal = nullptr; - -bool getHealthHal() { - if (gHealthHal == nullptr) { - gHealthHal = get_health_service(); - } - return gHealthHal != nullptr; -} - -ResourceHealthManagerPuller::ResourceHealthManagerPuller(int tagId) : StatsPuller(tagId) { -} - -// TODO(b/110565992): add other health atoms (eg. Temperature). -bool ResourceHealthManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { - if (!getHealthHal()) { - ALOGE("Health Hal not loaded"); - return false; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - - data->clear(); - bool result_success = true; - - // Get the data from the Health HAL (hardware/interfaces/health/1.0/types.hal). - Return<void> ret = gHealthHal->getHealthInfo([&](Result r, HealthInfo v) { - if (r != Result::SUCCESS) { - result_success = false; - return; - } - if (mTagId == android::util::REMAINING_BATTERY_CAPACITY) { - auto ptr = make_shared<LogEvent>(android::util::REMAINING_BATTERY_CAPACITY, - wallClockTimestampNs, elapsedTimestampNs); - ptr->write(v.legacy.batteryChargeCounter); - ptr->init(); - data->push_back(ptr); - } else if (mTagId == android::util::FULL_BATTERY_CAPACITY) { - auto ptr = make_shared<LogEvent>(android::util::FULL_BATTERY_CAPACITY, - wallClockTimestampNs, elapsedTimestampNs); - ptr->write(v.legacy.batteryFullCharge); - ptr->init(); - data->push_back(ptr); - } else if (mTagId == android::util::BATTERY_VOLTAGE) { - auto ptr = make_shared<LogEvent>(android::util::BATTERY_VOLTAGE, wallClockTimestampNs, - elapsedTimestampNs); - ptr->write(v.legacy.batteryVoltage); - ptr->init(); - data->push_back(ptr); - } else if (mTagId == android::util::BATTERY_LEVEL) { - auto ptr = make_shared<LogEvent>(android::util::BATTERY_LEVEL, wallClockTimestampNs, - elapsedTimestampNs); - ptr->write(v.legacy.batteryLevel); - ptr->init(); - data->push_back(ptr); - } else if (mTagId == android::util::BATTERY_CYCLE_COUNT) { - auto ptr = make_shared<LogEvent>(android::util::BATTERY_CYCLE_COUNT, - wallClockTimestampNs, elapsedTimestampNs); - ptr->write(v.legacy.batteryCycleCount); - ptr->init(); - data->push_back(ptr); - } else { - ALOGE("Unsupported tag in ResourceHealthManagerPuller: %d", mTagId); - } - }); - if (!result_success || !ret.isOk()) { - ALOGE("getHealthHal() failed: health HAL service not available. Description: %s", - ret.description().c_str()); - if (!ret.isOk() && ret.isDeadObject()) { - gHealthHal = nullptr; - } - return false; - } - return true; -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.h b/cmds/statsd/src/external/ResourceHealthManagerPuller.h deleted file mode 100644 index f650fccc447e..000000000000 --- a/cmds/statsd/src/external/ResourceHealthManagerPuller.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <utils/String16.h> -#include "StatsPuller.h" - -namespace android { -namespace os { -namespace statsd { - -/** - * Reads Ihealth.hal - */ -class ResourceHealthManagerPuller : public StatsPuller { -public: - explicit ResourceHealthManagerPuller(int tagId); - -private: - bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; -}; - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp index 6257771b5b0d..1a11f0e37311 100644 --- a/cmds/statsd/src/external/StatsCallbackPuller.cpp +++ b/cmds/statsd/src/external/StatsCallbackPuller.cpp @@ -68,7 +68,7 @@ bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { for (const StatsEventParcel& parcel: output) { shared_ptr<LogEvent> event = make_shared<LogEvent>( const_cast<uint8_t*>(parcel.buffer.data()), parcel.buffer.size(), - /*uid=*/-1, /*useNewSchema=*/true); + /*uid=*/-1, /*pid=*/-1, /*useNewSchema=*/true); sharedData->push_back(event); } *pullSuccess = success; diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h index ac88524a72ee..fe6af19e3901 100644 --- a/cmds/statsd/src/external/StatsCallbackPuller.h +++ b/cmds/statsd/src/external/StatsCallbackPuller.h @@ -17,7 +17,6 @@ #pragma once #include <android/os/IPullAtomCallback.h> -#include <utils/String16.h> #include "StatsPuller.h" diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 85d1e38d6052..3ceff7529440 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -32,20 +32,12 @@ #include "../logd/LogEvent.h" #include "../stats_log_util.h" #include "../statscompanion_util.h" -#include "GpuStatsPuller.h" -#include "PowerStatsPuller.h" -#include "ResourceHealthManagerPuller.h" #include "StatsCallbackPuller.h" -#include "SubsystemSleepStatePuller.h" #include "TrainInfoPuller.h" #include "statslog.h" -using std::make_shared; -using std::map; using std::shared_ptr; -using std::string; using std::vector; -using std::list; namespace android { namespace os { @@ -56,43 +48,8 @@ const int64_t NO_ALARM_UPDATE = INT64_MAX; StatsPullerManager::StatsPullerManager() : kAllPullAtomInfo({ - // subsystem_sleep_state - {{.atomTag = android::util::SUBSYSTEM_SLEEP_STATE}, new SubsystemSleepStatePuller()}, - - // on_device_power_measurement - {{.atomTag = android::util::ON_DEVICE_POWER_MEASUREMENT}, new PowerStatsPuller()}, - - // remaining_battery_capacity - {{.atomTag = android::util::REMAINING_BATTERY_CAPACITY}, - new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}, - - // full_battery_capacity - {{.atomTag = android::util::FULL_BATTERY_CAPACITY}, - new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}, - - // battery_voltage - {{.atomTag = android::util::BATTERY_VOLTAGE}, - new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)}, - - // battery_level - {{.atomTag = android::util::BATTERY_LEVEL}, - new ResourceHealthManagerPuller(android::util::BATTERY_LEVEL)}, - - // battery_cycle_count - {{.atomTag = android::util::BATTERY_CYCLE_COUNT}, - new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}, - // TrainInfo. {{.atomTag = android::util::TRAIN_INFO}, new TrainInfoPuller()}, - - // GpuStatsGlobalInfo - {{.atomTag = android::util::GPU_STATS_GLOBAL_INFO}, - new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)}, - - // GpuStatsAppInfo - {{.atomTag = android::util::GPU_STATS_APP_INFO}, - new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}, - }), mNextPullTimeNs(NO_ALARM_UPDATE) { } @@ -113,7 +70,7 @@ bool StatsPullerManager::PullLocked(int tagId, vector<shared_ptr<LogEvent>>* dat } return ret; } else { - VLOG("Unknown tagId %d", tagId); + ALOGW("StatsPullerManager: Unknown tagId %d", tagId); return false; // Return early since we don't know what to pull. } } diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h index f5d6057c2aec..aef16dcf2147 100644 --- a/cmds/statsd/src/external/StatsPullerManager.h +++ b/cmds/statsd/src/external/StatsPullerManager.h @@ -23,8 +23,6 @@ #include <utils/threads.h> #include <list> -#include <string> -#include <unordered_map> #include <vector> #include "PullDataReceiver.h" diff --git a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp b/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp deleted file mode 100644 index f6a4aeaa3f9e..000000000000 --- a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define DEBUG false // STOPSHIP if true -#include "Log.h" - -#include <android/hardware/power/1.0/IPower.h> -#include <android/hardware/power/1.1/IPower.h> -#include <android/hardware/power/stats/1.0/IPowerStats.h> - -#include <fcntl.h> -#include <hardware/power.h> -#include <hardware_legacy/power.h> -#include <inttypes.h> -#include <semaphore.h> -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include "external/SubsystemSleepStatePuller.h" -#include "external/StatsPuller.h" - -#include "SubsystemSleepStatePuller.h" -#include "logd/LogEvent.h" -#include "statslog.h" -#include "stats_log_util.h" - -using android::hardware::hidl_vec; -using android::hardware::power::V1_0::IPower; -using android::hardware::power::V1_0::PowerStatePlatformSleepState; -using android::hardware::power::V1_0::PowerStateVoter; -using android::hardware::power::V1_1::PowerStateSubsystem; -using android::hardware::power::V1_1::PowerStateSubsystemSleepState; -using android::hardware::power::stats::V1_0::PowerEntityInfo; -using android::hardware::power::stats::V1_0::PowerEntityStateResidencyResult; -using android::hardware::power::stats::V1_0::PowerEntityStateSpace; - -using android::hardware::Return; -using android::hardware::Void; - -using std::make_shared; -using std::shared_ptr; - -namespace android { -namespace os { -namespace statsd { - -static std::function<bool(vector<shared_ptr<LogEvent>>* data)> gPuller = {}; - -static sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr; -static sp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr; -static sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHalV1_0 = nullptr; - -static std::unordered_map<uint32_t, std::string> gEntityNames = {}; -static std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> gStateNames = {}; - -static std::mutex gPowerHalMutex; - -// The caller must be holding gPowerHalMutex. -static void deinitPowerStatsLocked() { - gPowerHalV1_0 = nullptr; - gPowerHalV1_1 = nullptr; - gPowerStatsHalV1_0 = nullptr; -} - -struct SubsystemSleepStatePullerDeathRecipient : virtual public hardware::hidl_death_recipient { - virtual void serviceDied(uint64_t cookie, - const wp<android::hidl::base::V1_0::IBase>& who) override { - - // The HAL just died. Reset all handles to HAL services. - std::lock_guard<std::mutex> lock(gPowerHalMutex); - deinitPowerStatsLocked(); - } -}; - -static sp<SubsystemSleepStatePullerDeathRecipient> gDeathRecipient = - new SubsystemSleepStatePullerDeathRecipient(); - -SubsystemSleepStatePuller::SubsystemSleepStatePuller() : - StatsPuller(android::util::SUBSYSTEM_SLEEP_STATE) { -} - -// The caller must be holding gPowerHalMutex. -static bool checkResultLocked(const Return<void> &ret, const char* function) { - if (!ret.isOk()) { - ALOGE("%s failed: requested HAL service not available. Description: %s", - function, ret.description().c_str()); - if (ret.isDeadObject()) { - deinitPowerStatsLocked(); - } - return false; - } - return true; -} - -// The caller must be holding gPowerHalMutex. -// gPowerStatsHalV1_0 must not be null -static bool initializePowerStats() { - using android::hardware::power::stats::V1_0::Status; - - // Clear out previous content if we are re-initializing - gEntityNames.clear(); - gStateNames.clear(); - - Return<void> ret; - ret = gPowerStatsHalV1_0->getPowerEntityInfo([](auto infos, auto status) { - if (status != Status::SUCCESS) { - ALOGE("Error getting power entity info"); - return; - } - - // construct lookup table of powerEntityId to power entity name - for (auto info : infos) { - gEntityNames.emplace(info.powerEntityId, info.powerEntityName); - } - }); - if (!checkResultLocked(ret, __func__)) { - return false; - } - - ret = gPowerStatsHalV1_0->getPowerEntityStateInfo({}, [](auto stateSpaces, auto status) { - if (status != Status::SUCCESS) { - ALOGE("Error getting state info"); - return; - } - - // construct lookup table of powerEntityId, powerEntityStateId to power entity state name - for (auto stateSpace : stateSpaces) { - std::unordered_map<uint32_t, std::string> stateNames = {}; - for (auto state : stateSpace.states) { - stateNames.emplace(state.powerEntityStateId, - state.powerEntityStateName); - } - gStateNames.emplace(stateSpace.powerEntityId, stateNames); - } - }); - if (!checkResultLocked(ret, __func__)) { - return false; - } - - return (!gEntityNames.empty()) && (!gStateNames.empty()); -} - -// The caller must be holding gPowerHalMutex. -static bool getPowerStatsHalLocked() { - if(gPowerStatsHalV1_0 == nullptr) { - gPowerStatsHalV1_0 = android::hardware::power::stats::V1_0::IPowerStats::getService(); - if (gPowerStatsHalV1_0 == nullptr) { - ALOGE("Unable to get power.stats HAL service."); - return false; - } - - // Link death recipient to power.stats service handle - hardware::Return<bool> linked = gPowerStatsHalV1_0->linkToDeath(gDeathRecipient, 0); - if (!linked.isOk()) { - ALOGE("Transaction error in linking to power.stats HAL death: %s", - linked.description().c_str()); - deinitPowerStatsLocked(); - return false; - } else if (!linked) { - ALOGW("Unable to link to power.stats HAL death notifications"); - // We should still continue even though linking failed - } - return initializePowerStats(); - } - return true; -} - -// The caller must be holding gPowerHalMutex. -static bool getIPowerStatsDataLocked(vector<shared_ptr<LogEvent>>* data) { - using android::hardware::power::stats::V1_0::Status; - - if(!getPowerStatsHalLocked()) { - return false; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - - // Get power entity state residency data - bool success = false; - Return<void> ret = gPowerStatsHalV1_0->getPowerEntityStateResidencyData({}, - [&data, &success, wallClockTimestampNs, elapsedTimestampNs] - (auto results, auto status) { - if (status == Status::NOT_SUPPORTED) { - ALOGW("getPowerEntityStateResidencyData is not supported"); - success = false; - return; - } - - for(auto result : results) { - for(auto stateResidency : result.stateResidencyData) { - auto statePtr = make_shared<LogEvent>( - android::util::SUBSYSTEM_SLEEP_STATE, - wallClockTimestampNs, elapsedTimestampNs); - statePtr->write(gEntityNames.at(result.powerEntityId)); - statePtr->write(gStateNames.at(result.powerEntityId) - .at(stateResidency.powerEntityStateId)); - statePtr->write(stateResidency.totalStateEntryCount); - statePtr->write(stateResidency.totalTimeInStateMs); - statePtr->init(); - data->emplace_back(statePtr); - } - } - success = true; - }); - // Intentionally not returning early here. - // bool success determines if this succeeded or not. - checkResultLocked(ret, __func__); - - return success; -} - -// The caller must be holding gPowerHalMutex. -static bool getPowerHalLocked() { - if(gPowerHalV1_0 == nullptr) { - gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService(); - if(gPowerHalV1_0 == nullptr) { - ALOGE("Unable to get power HAL service."); - return false; - } - gPowerHalV1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0); - - // Link death recipient to power service handle - hardware::Return<bool> linked = gPowerHalV1_0->linkToDeath(gDeathRecipient, 0); - if (!linked.isOk()) { - ALOGE("Transaction error in linking to power HAL death: %s", - linked.description().c_str()); - gPowerHalV1_0 = nullptr; - return false; - } else if (!linked) { - ALOGW("Unable to link to power. death notifications"); - // We should still continue even though linking failed - } - } - return true; -} - -// The caller must be holding gPowerHalMutex. -static bool getIPowerDataLocked(vector<shared_ptr<LogEvent>>* data) { - using android::hardware::power::V1_0::Status; - - if(!getPowerHalLocked()) { - return false; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - Return<void> ret; - ret = gPowerHalV1_0->getPlatformLowPowerStats( - [&data, wallClockTimestampNs, elapsedTimestampNs] - (hidl_vec<PowerStatePlatformSleepState> states, Status status) { - if (status != Status::SUCCESS) return; - - for (size_t i = 0; i < states.size(); i++) { - const PowerStatePlatformSleepState& state = states[i]; - - auto statePtr = make_shared<LogEvent>( - android::util::SUBSYSTEM_SLEEP_STATE, - wallClockTimestampNs, elapsedTimestampNs); - statePtr->write(state.name); - statePtr->write(""); - statePtr->write(state.totalTransitions); - statePtr->write(state.residencyInMsecSinceBoot); - statePtr->init(); - data->push_back(statePtr); - VLOG("powerstate: %s, %lld, %lld, %d", state.name.c_str(), - (long long)state.residencyInMsecSinceBoot, - (long long)state.totalTransitions, - state.supportedOnlyInSuspend ? 1 : 0); - for (const auto& voter : state.voters) { - auto voterPtr = make_shared<LogEvent>( - android::util::SUBSYSTEM_SLEEP_STATE, - wallClockTimestampNs, elapsedTimestampNs); - voterPtr->write(state.name); - voterPtr->write(voter.name); - voterPtr->write(voter.totalNumberOfTimesVotedSinceBoot); - voterPtr->write(voter.totalTimeInMsecVotedForSinceBoot); - voterPtr->init(); - data->push_back(voterPtr); - VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(), - voter.name.c_str(), - (long long)voter.totalTimeInMsecVotedForSinceBoot, - (long long)voter.totalNumberOfTimesVotedSinceBoot); - } - } - }); - if (!checkResultLocked(ret, __func__)) { - return false; - } - - // Trying to cast to IPower 1.1, this will succeed only for devices supporting 1.1 - sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 = - android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0); - if (gPowerHal_1_1 != nullptr) { - ret = gPowerHal_1_1->getSubsystemLowPowerStats( - [&data, wallClockTimestampNs, elapsedTimestampNs] - (hidl_vec<PowerStateSubsystem> subsystems, Status status) { - if (status != Status::SUCCESS) return; - - if (subsystems.size() > 0) { - for (size_t i = 0; i < subsystems.size(); i++) { - const PowerStateSubsystem& subsystem = subsystems[i]; - for (size_t j = 0; j < subsystem.states.size(); j++) { - const PowerStateSubsystemSleepState& state = - subsystem.states[j]; - auto subsystemStatePtr = make_shared<LogEvent>( - android::util::SUBSYSTEM_SLEEP_STATE, - wallClockTimestampNs, elapsedTimestampNs); - subsystemStatePtr->write(subsystem.name); - subsystemStatePtr->write(state.name); - subsystemStatePtr->write(state.totalTransitions); - subsystemStatePtr->write(state.residencyInMsecSinceBoot); - subsystemStatePtr->init(); - data->push_back(subsystemStatePtr); - VLOG("subsystemstate: %s, %s, %lld, %lld, %lld", - subsystem.name.c_str(), state.name.c_str(), - (long long)state.residencyInMsecSinceBoot, - (long long)state.totalTransitions, - (long long)state.lastEntryTimestampMs); - } - } - } - }); - } - return true; -} - -// The caller must be holding gPowerHalMutex. -std::function<bool(vector<shared_ptr<LogEvent>>* data)> getPullerLocked() { - std::function<bool(vector<shared_ptr<LogEvent>>* data)> ret = {}; - - // First see if power.stats HAL is available. Fall back to power HAL if - // power.stats HAL is unavailable. - if(android::hardware::power::stats::V1_0::IPowerStats::getService() != nullptr) { - ALOGI("Using power.stats HAL"); - ret = getIPowerStatsDataLocked; - } else if(android::hardware::power::V1_0::IPower::getService() != nullptr) { - ALOGI("Using power HAL"); - ret = getIPowerDataLocked; - } - - return ret; -} - -bool SubsystemSleepStatePuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { - std::lock_guard<std::mutex> lock(gPowerHalMutex); - - if(!gPuller) { - gPuller = getPullerLocked(); - } - - if(gPuller) { - return gPuller(data); - } - - ALOGE("Unable to load Power Hal or power.stats HAL"); - return false; -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/SubsystemSleepStatePuller.h b/cmds/statsd/src/external/SubsystemSleepStatePuller.h deleted file mode 100644 index 87f5f02614a9..000000000000 --- a/cmds/statsd/src/external/SubsystemSleepStatePuller.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <utils/String16.h> -#include "StatsPuller.h" - -namespace android { -namespace os { -namespace statsd { - -/** - * Reads hal for sleep states - */ -class SubsystemSleepStatePuller : public StatsPuller { -public: - SubsystemSleepStatePuller(); - -private: - bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; -}; - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/TrainInfoPuller.cpp b/cmds/statsd/src/external/TrainInfoPuller.cpp index 9d0924297912..a7d8d4ebebae 100644 --- a/cmds/statsd/src/external/TrainInfoPuller.cpp +++ b/cmds/statsd/src/external/TrainInfoPuller.cpp @@ -37,14 +37,16 @@ TrainInfoPuller::TrainInfoPuller() : } bool TrainInfoPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { - InstallTrainInfo trainInfo; - bool ret = StorageManager::readTrainInfo(trainInfo); - if (!ret) { - ALOGW("Failed to read train info."); - return false; + vector<InstallTrainInfo> trainInfoList = + StorageManager::readAllTrainInfo(); + if (trainInfoList.empty()) { + ALOGW("Train info was empty."); + return true; + } + for (InstallTrainInfo& trainInfo : trainInfoList) { + auto event = make_shared<LogEvent>(getWallClockNs(), getElapsedRealtimeNs(), trainInfo); + data->push_back(event); } - auto event = make_shared<LogEvent>(getWallClockNs(), getElapsedRealtimeNs(), trainInfo); - data->push_back(event); return true; } diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index a836bd14c012..3054b6d2204b 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -36,7 +36,6 @@ using android::util::FIELD_TYPE_MESSAGE; using android::util::FIELD_TYPE_STRING; using android::util::ProtoOutputStream; using std::lock_guard; -using std::map; using std::shared_ptr; using std::string; using std::vector; diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 3827b9e21b70..103eb0c78bd5 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -35,13 +35,42 @@ using android::util::ProtoOutputStream; using std::string; using std::vector; +// stats_event.h socket types. Keep in sync. +/* ERRORS */ +#define ERROR_NO_TIMESTAMP 0x1 +#define ERROR_NO_ATOM_ID 0x2 +#define ERROR_OVERFLOW 0x4 +#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8 +#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10 +#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20 +#define ERROR_INVALID_ANNOTATION_ID 0x40 +#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80 +#define ERROR_TOO_MANY_ANNOTATIONS 0x100 +#define ERROR_TOO_MANY_FIELDS 0x200 +#define ERROR_INVALID_VALUE_TYPE 0x400 +#define ERROR_STRING_NOT_NULL_TERMINATED 0x800 + +/* TYPE IDS */ +#define INT32_TYPE 0x00 +#define INT64_TYPE 0x01 +#define STRING_TYPE 0x02 +#define LIST_TYPE 0x03 +#define FLOAT_TYPE 0x04 +#define BOOL_TYPE 0x05 +#define BYTE_ARRAY_TYPE 0x06 +#define OBJECT_TYPE 0x07 +#define KEY_VALUE_PAIRS_TYPE 0x08 +#define ATTRIBUTION_CHAIN_TYPE 0x09 +#define ERROR_TYPE 0x0F + // Msg is expected to begin at the start of the serialized atom -- it should not // include the android_log_header_t or the StatsEventTag. -LogEvent::LogEvent(uint8_t* msg, uint32_t len, uint32_t uid) +LogEvent::LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid) : mBuf(msg), mRemainingLen(len), mLogdTimestampNs(time(nullptr)), - mLogUid(uid) + mLogUid(uid), + mLogPid(pid) { #ifdef NEW_ENCODING_SCHEME initNew(); @@ -52,8 +81,13 @@ LogEvent::LogEvent(uint8_t* msg, uint32_t len, uint32_t uid) #endif } -LogEvent::LogEvent(uint8_t* msg, uint32_t len, uint32_t uid, bool useNewSchema) - : mBuf(msg), mRemainingLen(len), mLogdTimestampNs(time(nullptr)), mLogUid(uid) { +LogEvent::LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid, bool useNewSchema) + : mBuf(msg), + mRemainingLen(len), + mLogdTimestampNs(time(nullptr)), + mLogUid(uid), + mLogPid(pid) +{ if (useNewSchema) { initNew(); } else { @@ -66,6 +100,7 @@ LogEvent::LogEvent(uint8_t* msg, uint32_t len, uint32_t uid, bool useNewSchema) LogEvent::LogEvent(const LogEvent& event) { mTagId = event.mTagId; mLogUid = event.mLogUid; + mLogPid = event.mLogPid; mElapsedTimestampNs = event.mElapsedTimestampNs; mLogdTimestampNs = event.mLogdTimestampNs; mValues = event.mValues; @@ -146,6 +181,7 @@ LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requi mElapsedTimestampNs = getElapsedRealtimeNs(); mTagId = android::util::BINARY_PUSH_STATE_CHANGED; mLogUid = android::IPCThreadState::self()->getCallingUid(); + mLogPid = android::IPCThreadState::self()->getCallingPid(); mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName))); mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode))); @@ -159,37 +195,6 @@ LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requi } LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, - const VendorAtom& vendorAtom) { - mLogdTimestampNs = wallClockTimestampNs; - mElapsedTimestampNs = elapsedTimestampNs; - mTagId = vendorAtom.atomId; - mLogUid = AID_STATSD; - - mValues.push_back( - FieldValue(Field(mTagId, getSimpleField(1)), Value(vendorAtom.reverseDomainName))); - for (int i = 0; i < (int)vendorAtom.values.size(); i++) { - switch (vendorAtom.values[i].getDiscriminator()) { - case VendorAtom::Value::hidl_discriminator::intValue: - mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)), - Value(vendorAtom.values[i].intValue()))); - break; - case VendorAtom::Value::hidl_discriminator::longValue: - mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)), - Value(vendorAtom.values[i].longValue()))); - break; - case VendorAtom::Value::hidl_discriminator::floatValue: - mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)), - Value(vendorAtom.values[i].floatValue()))); - break; - case VendorAtom::Value::hidl_discriminator::stringValue: - mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 2)), - Value(vendorAtom.values[i].stringValue()))); - break; - } - } -} - -LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, const InstallTrainInfo& trainInfo) { mLogdTimestampNs = wallClockTimestampNs; mElapsedTimestampNs = elapsedTimestampNs; @@ -801,6 +806,26 @@ float LogEvent::GetFloat(size_t key, status_t* err) const { return 0.0; } +std::vector<uint8_t> LogEvent::GetStorage(size_t key, status_t* err) const { + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == STORAGE) { + return value.mValue.storage_value; + } else { + *err = BAD_TYPE; + return vector<uint8_t>(); + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return vector<uint8_t>(); +} + string LogEvent::ToString() const { string result; result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs, diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 463a1b68f885..a67bef451be7 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -18,19 +18,14 @@ #include "FieldValue.h" -#include <android/frameworks/stats/1.0/types.h> #include <android/util/ProtoOutputStream.h> -#include <log/log_read.h> #include <private/android_logger.h> #include <stats_event_list.h> #include <stats_event.h> -#include <utils/Errors.h> #include <string> #include <vector> -using namespace android::frameworks::stats::V1_0; - namespace android { namespace os { namespace statsd { @@ -61,6 +56,9 @@ struct InstallTrainInfo { std::string trainName; int32_t status; std::vector<int64_t> experimentIds; + bool requiresStaging; + bool rollbackEnabled; + bool requiresLowLatencyMonitor; }; /** @@ -71,12 +69,12 @@ public: /** * Read a LogEvent from the socket */ - explicit LogEvent(uint8_t* msg, uint32_t len, uint32_t uid); + explicit LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid); /** * Temp constructor to use for pulled atoms until we flip the socket schema. */ - explicit LogEvent(uint8_t* msg, uint32_t len, uint32_t uid, bool useNewSchema); + explicit LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid, bool useNewSchema); /** * Constructs a LogEvent with synthetic data for testing. Must call init() before reading. @@ -105,9 +103,6 @@ public: const std::vector<uint8_t>& experimentIds, int32_t userId); explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, - const VendorAtom& vendorAtom); - - explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, const InstallTrainInfo& installTrainInfo); ~LogEvent(); @@ -123,9 +118,17 @@ public: */ inline int GetTagId() const { return mTagId; } - inline uint32_t GetUid() const { - return mLogUid; - } + /** + * Get the uid of the logging client. + * Returns -1 if the uid is unknown/has not been set. + */ + inline int32_t GetUid() const { return mLogUid; } + + /** + * Get the pid of the logging client. + * Returns -1 if the pid is unknown/has not been set. + */ + inline int32_t GetPid() const { return mLogPid; } /** * Get the nth value, starting at 1. @@ -138,6 +141,7 @@ public: const char* GetString(size_t key, status_t* err) const; bool GetBool(size_t key, status_t* err) const; float GetFloat(size_t key, status_t* err) const; + std::vector<uint8_t> GetStorage(size_t key, status_t* err) const; /** * Write test data to the LogEvent. This can only be used when the LogEvent is constructed @@ -208,6 +212,22 @@ public: return LogEvent(*this); } + template <class T> + status_t updateValue(size_t key, T& value, Type type) { + int field = getSimpleField(key); + for (auto& fieldValue : mValues) { + if (fieldValue.mField.getField() == field) { + if (fieldValue.mValue.getType() == type) { + fieldValue.mValue = Value(value); + return OK; + } else { + return BAD_TYPE; + } + } + } + return BAD_INDEX; + } + private: /** * Only use this if copy is absolutely needed. @@ -305,9 +325,14 @@ private: // The elapsed timestamp set by statsd log writer. int64_t mElapsedTimestampNs; + // The atom tag of the event. int mTagId; - uint32_t mLogUid; + // The uid of the logging client (defaults to -1). + int32_t mLogUid = -1; + + // The pid of the logging client (defaults to -1). + int32_t mLogPid = -1; }; void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut); diff --git a/cmds/statsd/src/logd/LogEventQueue.h b/cmds/statsd/src/logd/LogEventQueue.h index b4fd63f119e6..9dda3d24c571 100644 --- a/cmds/statsd/src/logd/LogEventQueue.h +++ b/cmds/statsd/src/logd/LogEventQueue.h @@ -19,10 +19,8 @@ #include "LogEvent.h" #include <condition_variable> -#include <memory> #include <mutex> #include <queue> -#include <thread> namespace android { namespace os { diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp index 7d446a9a1ed6..140ef4e9cea9 100644 --- a/cmds/statsd/src/main.cpp +++ b/cmds/statsd/src/main.cpp @@ -20,16 +20,10 @@ #include "StatsService.h" #include "socket/StatsSocketListener.h" -#include <binder/IInterface.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> -#include <binder/Status.h> -#include <hidl/HidlTransportSupport.h> #include <utils/Looper.h> -#include <utils/StrongPointer.h> - -#include <memory> #include <stdio.h> #include <sys/stat.h> @@ -80,8 +74,6 @@ int main(int /*argc*/, char** /*argv*/) { ps->giveThreadPoolName(); IPCThreadState::self()->disableBackgroundScheduling(true); - ::android::hardware::configureRpcThreadpool(4 /*threads*/, false /*willJoin*/); - std::shared_ptr<LogEventQueue> eventQueue = std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/); @@ -94,12 +86,6 @@ int main(int /*argc*/, char** /*argv*/) { return -1; } - auto ret = gStatsService->registerAsService(); - if (ret != ::android::OK) { - ALOGE("Failed to add service as HIDL service"); - return 1; // or handle error - } - registerSigHandler(); gStatsService->sayHiToStatsCompanion(); diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp index 15c067ee936d..b94a9572113e 100644 --- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp +++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp @@ -24,8 +24,6 @@ namespace os { namespace statsd { using std::set; -using std::string; -using std::unique_ptr; using std::unordered_map; using std::vector; diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h index 2a3f08da7b96..55bc46059fc1 100644 --- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h +++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h @@ -16,9 +16,6 @@ #ifndef COMBINATION_LOG_MATCHING_TRACKER_H #define COMBINATION_LOG_MATCHING_TRACKER_H -#include <log/log_read.h> -#include <log/logprint.h> -#include <set> #include <unordered_map> #include <vector> #include "LogMatchingTracker.h" diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.cpp b/cmds/statsd/src/matchers/EventMatcherWizard.cpp index 8418e9833509..025c9a87b16b 100644 --- a/cmds/statsd/src/matchers/EventMatcherWizard.cpp +++ b/cmds/statsd/src/matchers/EventMatcherWizard.cpp @@ -14,14 +14,11 @@ * limitations under the License. */ #include "EventMatcherWizard.h" -#include <unordered_set> namespace android { namespace os { namespace statsd { -using std::map; -using std::string; using std::vector; MatchingState EventMatcherWizard::matchLogEvent(const LogEvent& event, int matcher_index) { diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp index 31b3db524e80..082daf5a1916 100644 --- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp +++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp @@ -23,8 +23,6 @@ namespace android { namespace os { namespace statsd { -using std::string; -using std::unique_ptr; using std::unordered_map; using std::vector; diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h index 28b339caa466..a0f6a888bd44 100644 --- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h +++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h @@ -17,9 +17,6 @@ #ifndef SIMPLE_LOG_MATCHING_TRACKER_H #define SIMPLE_LOG_MATCHING_TRACKER_H -#include <log/log_read.h> -#include <log/logprint.h> -#include <set> #include <unordered_map> #include <vector> #include "LogMatchingTracker.h" diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp index 476fae37899d..1f8bbd7f528c 100644 --- a/cmds/statsd/src/matchers/matcher_util.cpp +++ b/cmds/statsd/src/matchers/matcher_util.cpp @@ -23,7 +23,6 @@ using std::set; using std::string; -using std::unordered_map; using std::vector; namespace android { diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h index 15b4a9799a93..1ab3e87b5fed 100644 --- a/cmds/statsd/src/matchers/matcher_util.h +++ b/cmds/statsd/src/matchers/matcher_util.h @@ -18,11 +18,6 @@ #include "logd/LogEvent.h" -#include <log/log_read.h> -#include <log/logprint.h> -#include <set> -#include <string> -#include <unordered_map> #include <vector> #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "packages/UidMap.h" diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index 4ab6fd48f1db..5c606bc98235 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -21,8 +21,6 @@ #include "GaugeMetricProducer.h" #include "../stats_log_util.h" -#include <cutils/log.h> - using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_FLOAT; @@ -549,14 +547,11 @@ void GaugeMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) { void GaugeMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs, const int64_t& nextBucketStartTimeNs) { int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs(); + int64_t bucketEndTime = eventTimeNs < fullBucketEndTimeNs ? eventTimeNs : fullBucketEndTimeNs; GaugeBucket info; info.mBucketStartNs = mCurrentBucketStartTimeNs; - if (eventTimeNs < fullBucketEndTimeNs) { - info.mBucketEndNs = eventTimeNs; - } else { - info.mBucketEndNs = fullBucketEndTimeNs; - } + info.mBucketEndNs = bucketEndTime; // Add bucket to mPastBuckets if bucket is large enough. // Otherwise, drop the bucket data and add bucket metadata to mSkippedBuckets. @@ -571,7 +566,7 @@ void GaugeMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs, } } else { mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs; - mCurrentSkippedBucket.bucketEndTimeNs = eventTimeNs; + mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime; if (!maxDropEventsReached()) { mCurrentSkippedBucket.dropEvents.emplace_back( buildDropEvent(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL)); diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp index 5c29cb3c27fe..be754e29b5bd 100644 --- a/cmds/statsd/src/metrics/MetricProducer.cpp +++ b/cmds/statsd/src/metrics/MetricProducer.cpp @@ -33,7 +33,6 @@ namespace android { namespace os { namespace statsd { -using std::map; // for ActiveMetric const int FIELD_ID_ACTIVE_METRIC_ID = 1; diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 99f0c64bd47c..d721514ed1f0 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -18,7 +18,6 @@ #define METRIC_PRODUCER_H #include <frameworks/base/cmds/statsd/src/active_config_list.pb.h> -#include <log/logprint.h> #include <utils/RefBase.h> #include <unordered_map> diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 088f607ecfce..536700f3bfe7 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -18,9 +18,7 @@ #include "MetricsManager.h" -#include <log/logprint.h> #include <private/android_filesystem_config.h> -#include <utils/SystemClock.h> #include "CountMetricProducer.h" #include "atoms_info.h" @@ -42,10 +40,8 @@ using android::util::FIELD_TYPE_MESSAGE; using android::util::FIELD_TYPE_STRING; using android::util::ProtoOutputStream; -using std::make_unique; using std::set; using std::string; -using std::unordered_map; using std::vector; namespace android { diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index d2db6e9c9ead..dc9b41303894 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -21,7 +21,6 @@ #include "../guardrail/StatsdStats.h" #include "../stats_log_util.h" -#include <cutils/log.h> #include <limits.h> #include <stdlib.h> @@ -33,12 +32,8 @@ using android::util::FIELD_TYPE_INT64; using android::util::FIELD_TYPE_MESSAGE; using android::util::FIELD_TYPE_STRING; using android::util::ProtoOutputStream; -using std::list; -using std::make_pair; -using std::make_shared; using std::map; using std::shared_ptr; -using std::unique_ptr; using std::unordered_map; namespace android { @@ -384,9 +379,6 @@ void ValueMetricProducer::invalidateCurrentBucketWithoutResetBase(const int64_t if (!mCurrentBucketIsInvalid) { // Only report to StatsdStats once per invalid bucket. StatsdStats::getInstance().noteInvalidatedBucket(mMetricId); - - mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs; - mCurrentSkippedBucket.bucketEndTimeNs = getCurrentBucketEndTimeNs(); } if (!maxDropEventsReached()) { @@ -960,12 +952,6 @@ void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs, int64_t conditionTrueDuration = mConditionTimer.newBucketStart(bucketEndTime); bool isBucketLargeEnough = bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs; if (!isBucketLargeEnough) { - // If the bucket is valid, this is the only drop reason and we need to - // set the skipped bucket start and end times. - if (!mCurrentBucketIsInvalid) { - mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs; - mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime; - } if (!maxDropEventsReached()) { mCurrentSkippedBucket.dropEvents.emplace_back( buildDropEvent(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL)); @@ -983,6 +969,8 @@ void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs, } } } else { + mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs; + mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime; mSkippedBuckets.emplace_back(mCurrentSkippedBucket); } diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index 19fb6942928f..50317b341843 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -17,8 +17,6 @@ #pragma once #include <gtest/gtest_prod.h> -#include <utils/threads.h> -#include <list> #include "anomaly/AnomalyTracker.h" #include "condition/ConditionTimer.h" #include "condition/ConditionTracker.h" diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h index c3aad668aa78..f44e3275b83d 100644 --- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h +++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h @@ -19,7 +19,6 @@ #include "DurationTracker.h" -#include <set> namespace android { namespace os { namespace statsd { diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 17f62b056426..40a313a14eab 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -40,7 +40,6 @@ #include "stats_util.h" using std::set; -using std::string; using std::unordered_map; using std::vector; diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h index 95b2ab81fa53..5ebb232694a4 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.h +++ b/cmds/statsd/src/metrics/metrics_manager_util.h @@ -16,7 +16,6 @@ #pragma once -#include <memory> #include <set> #include <unordered_map> #include <vector> diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h index fcdbe69dbbd1..6c50a8c41770 100644 --- a/cmds/statsd/src/packages/PackageInfoListener.h +++ b/cmds/statsd/src/packages/PackageInfoListener.h @@ -17,7 +17,6 @@ #ifndef STATSD_PACKAGE_INFO_LISTENER_H #define STATSD_PACKAGE_INFO_LISTENER_H -#include <utils/RefBase.h> #include <string> namespace android { diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp index 7e63bbff2d0a..ab0e86e24b02 100644 --- a/cmds/statsd/src/packages/UidMap.cpp +++ b/cmds/statsd/src/packages/UidMap.cpp @@ -21,10 +21,6 @@ #include "guardrail/StatsdStats.h" #include "packages/UidMap.h" -#include <android/os/IStatsCompanionService.h> -#include <binder/IServiceManager.h> -#include <utils/Errors.h> - #include <inttypes.h> using namespace android; diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h index 2d3f6ee9c2e8..bfac6e3431b0 100644 --- a/cmds/statsd/src/packages/UidMap.h +++ b/cmds/statsd/src/packages/UidMap.h @@ -21,10 +21,8 @@ #include "packages/PackageInfoListener.h" #include "stats_util.h" -#include <binder/IResultReceiver.h> #include <binder/IShellCallback.h> #include <gtest/gtest_prod.h> -#include <log/logprint.h> #include <stdio.h> #include <utils/RefBase.h> #include <list> diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp index f7e32d4aed26..d6a04336bc46 100644 --- a/cmds/statsd/src/shell/ShellSubscriber.cpp +++ b/cmds/statsd/src/shell/ShellSubscriber.cpp @@ -18,7 +18,6 @@ #include "ShellSubscriber.h" -#include <android-base/file.h> #include "matchers/matcher_util.h" #include "stats_log_util.h" diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h index 8e54a8b00091..86d85901083a 100644 --- a/cmds/statsd/src/shell/ShellSubscriber.h +++ b/cmds/statsd/src/shell/ShellSubscriber.h @@ -22,7 +22,6 @@ #include <binder/IResultReceiver.h> #include <condition_variable> #include <mutex> -#include <string> #include <thread> #include "external/StatsPullerManager.h" #include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h" diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp index 4308a1107039..8f0f480cb862 100755 --- a/cmds/statsd/src/socket/StatsSocketListener.cpp +++ b/cmds/statsd/src/socket/StatsSocketListener.cpp @@ -27,9 +27,6 @@ #include <unistd.h> #include <cutils/sockets.h> -#include <private/android_filesystem_config.h> -#include <private/android_logger.h> -#include <unordered_map> #include "StatsSocketListener.h" #include "guardrail/StatsdStats.h" @@ -126,9 +123,10 @@ bool StatsSocketListener::onDataAvailable(SocketClient* cli) { uint8_t* msg = ptr + sizeof(uint32_t); uint32_t len = n - sizeof(uint32_t); uint32_t uid = cred->uid; + uint32_t pid = cred->pid; int64_t oldestTimestamp; - if (!mQueue->push(std::make_unique<LogEvent>(msg, len, uid), &oldestTimestamp)) { + if (!mQueue->push(std::make_unique<LogEvent>(msg, len, uid, pid), &oldestTimestamp)) { StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp); } diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h index 8bc24612be90..8b3a4218238c 100644 --- a/cmds/statsd/src/state/StateManager.h +++ b/cmds/statsd/src/state/StateManager.h @@ -15,7 +15,6 @@ */ #pragma once -#include <gtest/gtest_prod.h> #include <inttypes.h> #include <utils/RefBase.h> diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp index 3ad21e0c96ae..ab861275073c 100644 --- a/cmds/statsd/src/state/StateTracker.cpp +++ b/cmds/statsd/src/state/StateTracker.cpp @@ -26,7 +26,9 @@ namespace os { namespace statsd { StateTracker::StateTracker(const int32_t atomId, const util::StateAtomFieldOptions& stateAtomInfo) - : mAtomId(atomId), mStateField(getSimpleMatcher(atomId, stateAtomInfo.exclusiveField)) { + : mAtomId(atomId), + mStateField(getSimpleMatcher(atomId, stateAtomInfo.exclusiveField)), + mNested(stateAtomInfo.nested) { // create matcher for each primary field for (const auto& primaryField : stateAtomInfo.primaryFields) { if (primaryField == util::FIRST_UID_IN_CHAIN) { @@ -38,7 +40,13 @@ StateTracker::StateTracker(const int32_t atomId, const util::StateAtomFieldOptio } } - // TODO(tsaichristine): b/142108433 set default state, reset state, and nesting + if (stateAtomInfo.defaultState != util::UNSET_VALUE) { + mDefaultState = stateAtomInfo.defaultState; + } + + if (stateAtomInfo.resetState != util::UNSET_VALUE) { + mResetState = stateAtomInfo.resetState; + } } void StateTracker::onLogEvent(const LogEvent& event) { @@ -60,7 +68,6 @@ void StateTracker::onLogEvent(const LogEvent& event) { // Parse event for state value. FieldValue stateValue; - int32_t state; if (!filterValues(mStateField, event.getValues(), &stateValue) || stateValue.mValue.getType() != INT) { ALOGE("StateTracker error extracting state from log event. Type: %d", @@ -68,11 +75,12 @@ void StateTracker::onLogEvent(const LogEvent& event) { handlePartialReset(eventTimeNs, primaryKey); return; } - state = stateValue.mValue.int_value; + int32_t state = stateValue.mValue.int_value; if (state == mResetState) { VLOG("StateTracker Reset state: %s", stateValue.mValue.toString().c_str()); handleReset(eventTimeNs); + return; } // Track and update state. @@ -113,15 +121,17 @@ bool StateTracker::getStateValue(const HashableDimensionKey& queryKey, FieldValu return true; } } else if (queryKey.getValues().size() > mPrimaryFields.size()) { - ALOGE("StateTracker query key size > primary key size is illegal"); + ALOGE("StateTracker query key size %zu > primary key size %zu is illegal", + queryKey.getValues().size(), mPrimaryFields.size()); } else { - ALOGE("StateTracker query key size < primary key size is not supported"); + ALOGE("StateTracker query key size %zu < primary key size %zu is not supported", + queryKey.getValues().size(), mPrimaryFields.size()); } - // Set the state value to unknown if: + // Set the state value to default state if: // - query key size is incorrect // - query key is not found in state map - output->mValue = StateTracker::kStateUnknown; + output->mValue = mDefaultState; return false; } @@ -164,18 +174,52 @@ void StateTracker::updateState(const HashableDimensionKey& primaryKey, const int *oldState = mDefaultState; } - // update state map - if (eventState == mDefaultState) { - // remove (key, state) pair if state returns to default state - VLOG("\t StateTracker changed to default state") - mStateMap.erase(primaryKey); - } else { - mStateMap[primaryKey].state = eventState; - mStateMap[primaryKey].count = 1; + // Update state map for non-nested counting case. + // Every state event triggers a state overwrite. + if (!mNested) { + if (eventState == mDefaultState) { + // remove (key, state) pair if state returns to default state + VLOG("\t StateTracker changed to default state") + mStateMap.erase(primaryKey); + } else { + mStateMap[primaryKey].state = eventState; + mStateMap[primaryKey].count = 1; + } + *newState = eventState; + return; } - *newState = eventState; - // TODO(tsaichristine): support atoms with nested counting + // Update state map for nested counting case. + // + // Nested counting is only allowed for binary state events such as ON/OFF or + // ACQUIRE/RELEASE. For example, WakelockStateChanged might have the state + // events: ON, ON, OFF. The state will still be ON until we see the same + // number of OFF events as ON events. + // + // In atoms.proto, a state atom with nested counting enabled + // must only have 2 states and one of the states must be the default state. + it = mStateMap.find(primaryKey); + if (it != mStateMap.end()) { + *newState = it->second.state; + if (eventState == it->second.state) { + it->second.count++; + } else if (eventState == mDefaultState) { + if ((--it->second.count) == 0) { + mStateMap.erase(primaryKey); + *newState = mDefaultState; + } + } else { + ALOGE("StateTracker Nest counting state has a third state instead of the binary state " + "limit."); + return; + } + } else { + if (eventState != mDefaultState) { + mStateMap[primaryKey].state = eventState; + mStateMap[primaryKey].count = 1; + } + *newState = eventState; + } } } // namespace statsd diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h index 70f16274c7f6..aeca2a53bfdc 100644 --- a/cmds/statsd/src/state/StateTracker.h +++ b/cmds/statsd/src/state/StateTracker.h @@ -74,6 +74,8 @@ private: int32_t mResetState = kStateUnknown; + const bool mNested; + // Maps primary key to state value info std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap; diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index 76c193679eef..73f640e130a8 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -17,14 +17,12 @@ #include "hash.h" #include "stats_log_util.h" -#include <logd/LogEvent.h> #include <private/android_filesystem_config.h> -#include <utils/Log.h> #include <set> -#include <stack> -#include <utils/Log.h> #include <utils/SystemClock.h> +#include "statscompanion_util.h" + using android::util::AtomsInfo; using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; @@ -588,6 +586,21 @@ int64_t MillisToNano(const int64_t millis) { return millis * 1000000; } +bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid) { + sp<IStatsCompanionService> scs = getStatsCompanionService(); + if (scs == nullptr) { + return false; + } + + bool success; + binder::Status status = scs->checkPermission(String16(permission), pid, uid, &success); + if (!status.isOk()) { + return false; + } + + return success; +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h index 5fdf6e260247..aec09561b7c6 100644 --- a/cmds/statsd/src/stats_log_util.h +++ b/cmds/statsd/src/stats_log_util.h @@ -95,6 +95,9 @@ bool parseProtoOutputStream(util::ProtoOutputStream& protoOutput, T* message) { // Returns the truncated timestamp to the nearest 5 minutes if needed. int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs); +// Checks permission for given pid and uid. +bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid); + inline bool isVendorPulledAtom(int atomId) { return atomId >= StatsdStats::kVendorPulledAtomStartTag && atomId < StatsdStats::kMaxAtomTag; } diff --git a/cmds/statsd/src/statscompanion_util.h b/cmds/statsd/src/statscompanion_util.h index ff702f23f6d1..dc4f28361214 100644 --- a/cmds/statsd/src/statscompanion_util.h +++ b/cmds/statsd/src/statscompanion_util.h @@ -18,12 +18,6 @@ #include "StatsLogProcessor.h" -using namespace android; -using namespace android::base; -using namespace android::binder; -using namespace android::os; -using namespace std; - namespace android { namespace os { namespace statsd { diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp index 9b48a02c7f78..1bac19ed2c5d 100644 --- a/cmds/statsd/src/storage/StorageManager.cpp +++ b/cmds/statsd/src/storage/StorageManager.cpp @@ -23,10 +23,8 @@ #include "stats_log_util.h" #include <android-base/file.h> -#include <dirent.h> #include <private/android_filesystem_config.h> #include <fstream> -#include <iostream> namespace android { namespace os { @@ -46,7 +44,7 @@ using std::map; #define TRAIN_INFO_PATH "/data/misc/train-info/train-info.bin" // Magic word at the start of the train info file, change this if changing the file format -const uint32_t TRAIN_INFO_FILE_MAGIC = 0xff7447ff; +const uint32_t TRAIN_INFO_FILE_MAGIC = 0xfb7447bf; // for ConfigMetricsReportList const int FIELD_ID_REPORTS = 2; @@ -77,6 +75,29 @@ string StorageManager::getDataHistoryFileName(long wallClockSec, int uid, int64_ (long long)id); } +static const char* findTrainInfoFileNameLocked(const string& trainName) { + unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir); + if (dir == NULL) { + VLOG("Path %s does not exist", TRAIN_INFO_DIR); + return nullptr; + } + dirent* de; + while ((de = readdir(dir.get()))) { + char* fileName = de->d_name; + if (fileName[0] == '.') continue; + + size_t fileNameLength = strlen(fileName); + if (fileNameLength >= trainName.length()) { + if (0 == strncmp(fileName + fileNameLength - trainName.length(), trainName.c_str(), + trainName.length())) { + return fileName; + } + } + } + + return nullptr; +} + // Returns array of int64_t which contains timestamp in seconds, uid, // configID and whether the file is a local history file. static void parseFileName(char* name, FileName* output) { @@ -125,20 +146,25 @@ void StorageManager::writeFile(const char* file, const void* buffer, int numByte close(fd); } -bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& trainName, - int32_t status, const std::vector<int64_t>& experimentIds) { +bool StorageManager::writeTrainInfo(const InstallTrainInfo& trainInfo) { std::lock_guard<std::mutex> lock(sTrainInfoMutex); - deleteAllFiles(TRAIN_INFO_DIR); + if (trainInfo.trainName.empty()) { + return false; + } + deleteSuffixedFiles(TRAIN_INFO_DIR, trainInfo.trainName.c_str()); - int fd = open(TRAIN_INFO_PATH, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); + std::string fileName = + StringPrintf("%s/%ld_%s", TRAIN_INFO_DIR, (long) getWallClockSec(), + trainInfo.trainName.c_str()); + + int fd = open(fileName.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); if (fd == -1) { - VLOG("Attempt to access %s but failed", TRAIN_INFO_PATH); + VLOG("Attempt to access %s but failed", fileName.c_str()); return false; } size_t result; - // Write the magic word result = write(fd, &TRAIN_INFO_FILE_MAGIC, sizeof(TRAIN_INFO_FILE_MAGIC)); if (result != sizeof(TRAIN_INFO_FILE_MAGIC)) { @@ -148,8 +174,8 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& } // Write the train version - const size_t trainVersionCodeByteCount = sizeof(trainVersionCode); - result = write(fd, &trainVersionCode, trainVersionCodeByteCount); + const size_t trainVersionCodeByteCount = sizeof(trainInfo.trainVersionCode); + result = write(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount); if (result != trainVersionCodeByteCount) { VLOG("Failed to wrtie train version code"); close(fd); @@ -157,7 +183,7 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& } // Write # of bytes in trainName to file - const size_t trainNameSize = trainName.size(); + const size_t trainNameSize = trainInfo.trainName.size(); const size_t trainNameSizeByteCount = sizeof(trainNameSize); result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount); if (result != trainNameSizeByteCount) { @@ -167,7 +193,7 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& } // Write trainName to file - result = write(fd, trainName.c_str(), trainNameSize); + result = write(fd, trainInfo.trainName.c_str(), trainNameSize); if (result != trainNameSize) { VLOG("Failed to write train name"); close(fd); @@ -175,8 +201,8 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& } // Write status to file - const size_t statusByteCount = sizeof(status); - result = write(fd, (uint8_t*)&status, statusByteCount); + const size_t statusByteCount = sizeof(trainInfo.status); + result = write(fd, (uint8_t*)&trainInfo.status, statusByteCount); if (result != statusByteCount) { VLOG("Failed to write status"); close(fd); @@ -184,7 +210,7 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& } // Write experiment id count to file. - const size_t experimentIdsCount = experimentIds.size(); + const size_t experimentIdsCount = trainInfo.experimentIds.size(); const size_t experimentIdsCountByteCount = sizeof(experimentIdsCount); result = write(fd, (uint8_t*) &experimentIdsCount, experimentIdsCountByteCount); if (result != experimentIdsCountByteCount) { @@ -195,7 +221,7 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& // Write experimentIds to file for (size_t i = 0; i < experimentIdsCount; i++) { - const int64_t experimentId = experimentIds[i]; + const int64_t experimentId = trainInfo.experimentIds[i]; const size_t experimentIdByteCount = sizeof(experimentId); result = write(fd, &experimentId, experimentIdByteCount); if (result == experimentIdByteCount) { @@ -207,23 +233,47 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& } } - result = fchown(fd, AID_STATSD, AID_STATSD); - if (result) { - VLOG("Failed to chown train info file to statsd"); - close(fd); - return false; + // Write bools to file + const size_t boolByteCount = sizeof(trainInfo.requiresStaging); + result = write(fd, (uint8_t*)&trainInfo.requiresStaging, boolByteCount); + if (result != boolByteCount) { + VLOG("Failed to write requires staging"); + close(fd); + return false; + } + + result = write(fd, (uint8_t*)&trainInfo.rollbackEnabled, boolByteCount); + if (result != boolByteCount) { + VLOG("Failed to write rollback enabled"); + close(fd); + return false; + } + + result = write(fd, (uint8_t*)&trainInfo.requiresLowLatencyMonitor, boolByteCount); + if (result != boolByteCount) { + VLOG("Failed to write requires log latency monitor"); + close(fd); + return false; } close(fd); return true; } -bool StorageManager::readTrainInfo(InstallTrainInfo& trainInfo) { +bool StorageManager::readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo) { std::lock_guard<std::mutex> lock(sTrainInfoMutex); + return readTrainInfoLocked(trainName, trainInfo); +} - int fd = open(TRAIN_INFO_PATH, O_RDONLY | O_CLOEXEC); +bool StorageManager::readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo) { + trimToFit(TRAIN_INFO_DIR, /*parseTimestampOnly=*/ true); + const char* fileName = findTrainInfoFileNameLocked(trainName); + if (fileName == nullptr) { + return false; + } + int fd = open(StringPrintf("%s/%s", TRAIN_INFO_DIR, fileName).c_str(), O_RDONLY | O_CLOEXEC); if (fd == -1) { - VLOG("Failed to open train-info.bin"); + VLOG("Failed to open %s", fileName); return false; } @@ -299,6 +349,29 @@ bool StorageManager::readTrainInfo(InstallTrainInfo& trainInfo) { trainInfo.experimentIds.push_back(experimentId); } + // Read bools + const size_t boolByteCount = sizeof(trainInfo.requiresStaging); + result = read(fd, &trainInfo.requiresStaging, boolByteCount); + if (result != boolByteCount) { + VLOG("Failed to read requires requires staging from train info file"); + close(fd); + return false; + } + + result = read(fd, &trainInfo.rollbackEnabled, boolByteCount); + if (result != boolByteCount) { + VLOG("Failed to read requires rollback enabled from train info file"); + close(fd); + return false; + } + + result = read(fd, &trainInfo.requiresLowLatencyMonitor, boolByteCount); + if (result != boolByteCount) { + VLOG("Failed to read requires requires low latency monitor from train info file"); + close(fd); + return false; + } + // Expect to be at EOF. char c; result = read(fd, &c, 1); @@ -313,6 +386,32 @@ bool StorageManager::readTrainInfo(InstallTrainInfo& trainInfo) { return true; } +vector<InstallTrainInfo> StorageManager::readAllTrainInfo() { + std::lock_guard<std::mutex> lock(sTrainInfoMutex); + vector<InstallTrainInfo> trainInfoList; + unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir); + if (dir == NULL) { + VLOG("Directory does not exist: %s", TRAIN_INFO_DIR); + return trainInfoList; + } + + dirent* de; + while ((de = readdir(dir.get()))) { + char* name = de->d_name; + if (name[0] == '.') { + continue; + } + + InstallTrainInfo trainInfo; + bool readSuccess = StorageManager::readTrainInfoLocked(name, trainInfo); + if (!readSuccess) { + continue; + } + trainInfoList.push_back(trainInfo); + } + return trainInfoList; +} + void StorageManager::deleteFile(const char* file) { if (remove(file) != 0) { VLOG("Attempt to delete %s but is not found", file); @@ -576,7 +675,7 @@ void StorageManager::sortFiles(vector<FileInfo>* fileNames) { }); } -void StorageManager::trimToFit(const char* path) { +void StorageManager::trimToFit(const char* path, bool parseTimestampOnly) { unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir); if (dir == NULL) { VLOG("Path %s does not exist", path); @@ -591,7 +690,12 @@ void StorageManager::trimToFit(const char* path) { if (name[0] == '.') continue; FileName output; - parseFileName(name, &output); + if (parseTimestampOnly) { + output.mTimestampSec = StrToInt64(strtok(name, "_")); + output.mIsHistory = false; + } else { + parseFileName(name, &output); + } if (output.mTimestampSec == -1) continue; string file_name = output.getFullFileName(path); diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h index 69b41c2cb974..d59046dfbb99 100644 --- a/cmds/statsd/src/storage/StorageManager.h +++ b/cmds/statsd/src/storage/StorageManager.h @@ -52,13 +52,22 @@ public: /** * Writes train info. */ - static bool writeTrainInfo(int64_t trainVersionCode, const std::string& trainName, - int32_t status, const std::vector<int64_t>& experimentIds); + static bool writeTrainInfo(const InstallTrainInfo& trainInfo); /** * Reads train info. */ - static bool readTrainInfo(InstallTrainInfo& trainInfo); + static bool readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo); + + /** + * Reads train info assuming lock is obtained. + */ + static bool readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo); + + /** + * Reads all train info and returns a vector of train info. + */ + static vector<InstallTrainInfo> readAllTrainInfo(); /** * Reads the file content to the buffer. @@ -124,7 +133,7 @@ public: * Trims files in the provided directory to limit the total size, number of * files, accumulation of outdated files. */ - static void trimToFit(const char* dir); + static void trimToFit(const char* dir, bool parseTimestampOnly = false); /** * Returns true if there already exists identical configuration on device. diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp index f1320c2f746d..30c90b1e1f71 100644 --- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp +++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp @@ -21,11 +21,8 @@ #include "packages/UidMap.h" #include "stats_log_util.h" -#include <android/os/IIncidentManager.h> -#include <android/os/IncidentReportArgs.h> #include <android/util/ProtoOutputStream.h> -#include <binder/IBinder.h> -#include <binder/IServiceManager.h> +#include <incident/incident_report.h> #include <vector> @@ -133,7 +130,7 @@ bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int return false; } - IncidentReportArgs incidentReport; + android::os::IncidentReportRequest incidentReport; vector<uint8_t> protoData; getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey, @@ -147,30 +144,21 @@ bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int uint8_t dest; switch (config.dest()) { case IncidentdDetails_Destination_AUTOMATIC: - dest = android::os::PRIVACY_POLICY_AUTOMATIC; + dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC; break; case IncidentdDetails_Destination_EXPLICIT: - dest = android::os::PRIVACY_POLICY_EXPLICIT; + dest = INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT; break; default: - dest = android::os::PRIVACY_POLICY_AUTOMATIC; + dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC; } incidentReport.setPrivacyPolicy(dest); - incidentReport.setReceiverPkg(config.receiver_pkg()); + incidentReport.setReceiverPackage(config.receiver_pkg()); - incidentReport.setReceiverCls(config.receiver_cls()); + incidentReport.setReceiverClass(config.receiver_cls()); - sp<IIncidentManager> service = interface_cast<IIncidentManager>( - defaultServiceManager()->getService(android::String16("incident"))); - if (service == nullptr) { - ALOGW("Failed to fetch incident service."); - return false; - } - VLOG("Calling incidentd %p", service.get()); - binder::Status s = service->reportIncident(incidentReport); - VLOG("Report incident status: %s", s.toString8().string()); - return s.isOk(); + return incidentReport.takeReport() == NO_ERROR; } } // namespace statsd diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp index a37cad14fcbc..8fd6b46d0716 100644 --- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp +++ b/cmds/statsd/src/subscriber/SubscriberReporter.cpp @@ -20,7 +20,6 @@ #include "SubscriberReporter.h" using std::lock_guard; -using std::unordered_map; namespace android { namespace os { @@ -122,7 +121,7 @@ void SubscriberReporter::sendBroadcastLocked(const sp<IPendingIntentRef>& pir, subscription.id(), subscription.rule_id(), cookies, - getStatsDimensionsValue(dimKey.getDimensionKeyInWhat())); + dimKey.getDimensionKeyInWhat().toStatsDimensionsValueParcel()); } sp<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey, @@ -139,61 +138,6 @@ sp<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey return pirMapIt->second; } -void getStatsDimensionsValueHelper(const vector<FieldValue>& dims, size_t* index, int depth, - int prefix, vector<StatsDimensionsValue>* output) { - size_t count = dims.size(); - while (*index < count) { - const auto& dim = dims[*index]; - const int valueDepth = dim.mField.getDepth(); - const int valuePrefix = dim.mField.getPrefix(depth); - if (valueDepth > 2) { - ALOGE("Depth > 2 not supported"); - return; - } - if (depth == valueDepth && valuePrefix == prefix) { - switch (dim.mValue.getType()) { - case INT: - output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), - dim.mValue.int_value)); - break; - case LONG: - output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), - dim.mValue.long_value)); - break; - case FLOAT: - output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), - dim.mValue.float_value)); - break; - case STRING: - output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), - String16(dim.mValue.str_value.c_str()))); - break; - default: - break; - } - (*index)++; - } else if (valueDepth > depth && valuePrefix == prefix) { - vector<StatsDimensionsValue> childOutput; - getStatsDimensionsValueHelper(dims, index, depth + 1, dim.mField.getPrefix(depth + 1), - &childOutput); - output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), childOutput)); - } else { - return; - } - } -} - -StatsDimensionsValue SubscriberReporter::getStatsDimensionsValue(const HashableDimensionKey& dim) { - if (dim.getValues().size() == 0) { - return StatsDimensionsValue(); - } - - vector<StatsDimensionsValue> fields; - size_t index = 0; - getStatsDimensionsValueHelper(dim.getValues(), &index, 0, 0, &fields); - return StatsDimensionsValue(dim.getValues()[0].mField.getTag(), fields); -} - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h index 087a1b84b91f..42599f508313 100644 --- a/cmds/statsd/src/subscriber/SubscriberReporter.h +++ b/cmds/statsd/src/subscriber/SubscriberReporter.h @@ -22,7 +22,6 @@ #include "config/ConfigKey.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // subscription -#include "android/os/StatsDimensionsValue.h" #include "HashableDimensionKey.h" #include <mutex> @@ -70,8 +69,6 @@ public: sp<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId); - static StatsDimensionsValue getStatsDimensionsValue(const HashableDimensionKey& dim); - private: SubscriberReporter() {}; diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp index f4a59ed14d10..9e69d977f351 100644 --- a/cmds/statsd/tests/FieldValue_test.cpp +++ b/cmds/statsd/tests/FieldValue_test.cpp @@ -290,33 +290,34 @@ TEST(AtomMatcherTest, TestWriteDimensionPath) { } } -TEST(AtomMatcherTest, TestSubscriberDimensionWrite) { - HashableDimensionKey dim; - - int pos1[] = {1, 1, 1}; - int pos2[] = {1, 1, 2}; - int pos3[] = {1, 1, 3}; - int pos4[] = {2, 0, 0}; - - Field field1(10, pos1, 2); - Field field2(10, pos2, 2); - Field field3(10, pos3, 2); - Field field4(10, pos4, 0); - - Value value1((int32_t)10025); - Value value2("tag"); - Value value3((int32_t)987654); - Value value4((int32_t)99999); - - dim.addValue(FieldValue(field1, value1)); - dim.addValue(FieldValue(field2, value2)); - dim.addValue(FieldValue(field3, value3)); - dim.addValue(FieldValue(field4, value4)); - - SubscriberReporter::getStatsDimensionsValue(dim); - // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't - // have any read api. -} +//TODO(b/149050405) Update this test for StatsDimensionValueParcel +//TEST(AtomMatcherTest, TestSubscriberDimensionWrite) { +// HashableDimensionKey dim; +// +// int pos1[] = {1, 1, 1}; +// int pos2[] = {1, 1, 2}; +// int pos3[] = {1, 1, 3}; +// int pos4[] = {2, 0, 0}; +// +// Field field1(10, pos1, 2); +// Field field2(10, pos2, 2); +// Field field3(10, pos3, 2); +// Field field4(10, pos4, 0); +// +// Value value1((int32_t)10025); +// Value value2("tag"); +// Value value3((int32_t)987654); +// Value value4((int32_t)99999); +// +// dim.addValue(FieldValue(field1, value1)); +// dim.addValue(FieldValue(field2, value2)); +// dim.addValue(FieldValue(field3, value3)); +// dim.addValue(FieldValue(field4, value4)); +// +// SubscriberReporter::getStatsDimensionsValue(dim); +// // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't +// // have any read api. +//} TEST(AtomMatcherTest, TestWriteDimensionToProto) { HashableDimensionKey dim; diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index 1cf9fb681d61..f624e12c9623 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -46,20 +46,22 @@ Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vec } TEST(LogEventTest, TestPrimitiveParsing) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); - stats_event_write_int32(event, 10); - stats_event_write_int64(event, 0x123456789); - stats_event_write_float(event, 2.0); - stats_event_write_bool(event, true); - stats_event_build(event); + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + AStatsEvent_writeInt32(event, 10); + AStatsEvent_writeInt64(event, 0x123456789); + AStatsEvent_writeFloat(event, 2.0); + AStatsEvent_writeBool(event, true); + AStatsEvent_build(event); size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); + uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000); + LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); EXPECT_TRUE(logEvent.isValid()); EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(4, values.size()); @@ -88,24 +90,26 @@ TEST(LogEventTest, TestPrimitiveParsing) { EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type EXPECT_EQ(1, boolItem.mValue.int_value); - stats_event_release(event); + AStatsEvent_release(event); } TEST(LogEventTest, TestStringAndByteArrayParsing) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); string str = "test"; - stats_event_write_string8(event, str.c_str()); - stats_event_write_byte_array(event, (uint8_t*)str.c_str(), str.length()); - stats_event_build(event); + AStatsEvent_writeString(event, str.c_str()); + AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length()); + AStatsEvent_build(event); size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); + uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000); + LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); EXPECT_TRUE(logEvent.isValid()); EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(2, values.size()); @@ -123,22 +127,24 @@ TEST(LogEventTest, TestStringAndByteArrayParsing) { vector<uint8_t> expectedValue = {'t', 'e', 's', 't'}; EXPECT_EQ(expectedValue, storageItem.mValue.storage_value); - stats_event_release(event); + AStatsEvent_release(event); } TEST(LogEventTest, TestEmptyString) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); string empty = ""; - stats_event_write_string8(event, empty.c_str()); - stats_event_build(event); + AStatsEvent_writeString(event, empty.c_str()); + AStatsEvent_build(event); size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); + uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000); + LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); EXPECT_TRUE(logEvent.isValid()); EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(1, values.size()); @@ -149,22 +155,24 @@ TEST(LogEventTest, TestEmptyString) { EXPECT_EQ(Type::STRING, item.mValue.getType()); EXPECT_EQ(empty, item.mValue.str_value); - stats_event_release(event); + AStatsEvent_release(event); } TEST(LogEventTest, TestByteArrayWithNullCharacter) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); uint8_t message[] = {'\t', 'e', '\0', 's', 't'}; - stats_event_write_byte_array(event, message, 5); - stats_event_build(event); + AStatsEvent_writeByteArray(event, message, 5); + AStatsEvent_build(event); size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); + uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000); + LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); EXPECT_TRUE(logEvent.isValid()); EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(1, values.size()); @@ -176,77 +184,12 @@ TEST(LogEventTest, TestByteArrayWithNullCharacter) { vector<uint8_t> expectedValue(message, message + 5); EXPECT_EQ(expectedValue, item.mValue.storage_value); - stats_event_release(event); -} - -TEST(LogEventTest, TestKeyValuePairs) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); - - struct key_value_pair pairs[4]; - pairs[0] = {.key = 0, .valueType = INT32_TYPE, .int32Value = 1}; - pairs[1] = {.key = 1, .valueType = INT64_TYPE, .int64Value = 0x123456789}; - pairs[2] = {.key = 2, .valueType = FLOAT_TYPE, .floatValue = 2.0}; - string str = "test"; - pairs[3] = {.key = 3, .valueType = STRING_TYPE, .stringValue = str.c_str()}; - - stats_event_write_key_value_pairs(event, pairs, 4); - stats_event_build(event); - - size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); - - LogEvent logEvent(buf, size, /*uid=*/ 1000); - EXPECT_TRUE(logEvent.isValid()); - EXPECT_EQ(100, logEvent.GetTagId()); - - const vector<FieldValue>& values = logEvent.getValues(); - EXPECT_EQ(8, values.size()); // 2 FieldValues per key-value pair - - // Check the keys first - for (int i = 0; i < values.size() / 2; i++) { - const FieldValue& item = values[2 * i]; - int32_t depth1Pos = i + 1; - bool depth1Last = i == (values.size() / 2 - 1); - Field expectedField = getField(100, {1, depth1Pos, 1}, 2, {true, depth1Last, false}); - - EXPECT_EQ(expectedField, item.mField); - EXPECT_EQ(Type::INT, item.mValue.getType()); - EXPECT_EQ(i, item.mValue.int_value); - } - - // Check the values now - // Note: pos[2] = index of type in KeyValuePair in atoms.proto - const FieldValue& int32Item = values[1]; - Field expectedField = getField(100, {1, 1, 2}, 2, {true, false, true}); - EXPECT_EQ(expectedField, int32Item.mField); - EXPECT_EQ(Type::INT, int32Item.mValue.getType()); - EXPECT_EQ(1, int32Item.mValue.int_value); - - const FieldValue& int64Item = values[3]; - expectedField = getField(100, {1, 2, 3}, 2, {true, false, true}); - EXPECT_EQ(expectedField, int64Item.mField); - EXPECT_EQ(Type::LONG, int64Item.mValue.getType()); - EXPECT_EQ(0x123456789, int64Item.mValue.long_value); - - const FieldValue& floatItem = values[5]; - expectedField = getField(100, {1, 3, 5}, 2, {true, false, true}); - EXPECT_EQ(expectedField, floatItem.mField); - EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType()); - EXPECT_EQ(2.0, floatItem.mValue.float_value); - - const FieldValue& stringItem = values[7]; - expectedField = getField(100, {1, 4, 4}, 2, {true, true, true}); - EXPECT_EQ(expectedField, stringItem.mField); - EXPECT_EQ(Type::STRING, stringItem.mValue.getType()); - EXPECT_EQ(str, stringItem.mValue.str_value); - - stats_event_release(event); + AStatsEvent_release(event); } TEST(LogEventTest, TestAttributionChain) { - struct stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, 100); + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); string tag1 = "tag1"; string tag2 = "tag2"; @@ -254,15 +197,17 @@ TEST(LogEventTest, TestAttributionChain) { uint32_t uids[] = {1001, 1002}; const char* tags[] = {tag1.c_str(), tag2.c_str()}; - stats_event_write_attribution_chain(event, uids, tags, 2); - stats_event_build(event); + AStatsEvent_writeAttributionChain(event, uids, tags, 2); + AStatsEvent_build(event); size_t size; - uint8_t* buf = stats_event_get_buffer(event, &size); + uint8_t* buf = AStatsEvent_getBuffer(event, &size); - LogEvent logEvent(buf, size, /*uid=*/ 1000); + LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001); EXPECT_TRUE(logEvent.isValid()); EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(4, values.size()); // 2 per attribution node @@ -293,7 +238,7 @@ TEST(LogEventTest, TestAttributionChain) { EXPECT_EQ(Type::STRING, tag2Item.mValue.getType()); EXPECT_EQ(tag2, tag2Item.mValue.str_value); - stats_event_release(event); + AStatsEvent_release(event); } #else // NEW_ENCODING_SCHEME diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp index c7ba9be3ca5a..5e60abaf7792 100644 --- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp +++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp @@ -14,12 +14,12 @@ #include <gtest/gtest.h> +#include <vector> + #include "src/StatsLogProcessor.h" #include "src/stats_log_util.h" #include "tests/statsd_test_util.h" -#include <vector> - namespace android { namespace os { namespace statsd { @@ -29,12 +29,13 @@ namespace statsd { namespace { const int64_t metricId = 123456; +const int32_t ATOM_TAG = android::util::SUBSYSTEM_SLEEP_STATE; StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type, bool useCondition = true) { StatsdConfig config; config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE); + auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG); *config.add_atom_matcher() = atomMatcher; *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); @@ -51,7 +52,7 @@ StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type, gaugeMetric->set_sampling_type(sampling_type); gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true); *gaugeMetric->mutable_dimensions_in_what() = - CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */}); + CreateDimensions(ATOM_TAG, {1 /* subsystem name */}); gaugeMetric->set_bucket(FIVE_MINUTES); gaugeMetric->set_max_pull_delay_sec(INT_MAX); config.set_hash_strings_in_metric_report(false); @@ -69,8 +70,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), ATOM_TAG); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -144,7 +145,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { EXPECT_GT((int)gaugeMetrics.data_size(), 1); auto data = gaugeMetrics.data(0); - EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); + EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field()); EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); EXPECT_EQ(1 /* subsystem name field */, data.dimensions_in_what().value_tuple().dimensions_value(0).field()); @@ -214,8 +215,8 @@ TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) { TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), ATOM_TAG); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -267,7 +268,7 @@ TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) { EXPECT_GT((int)gaugeMetrics.data_size(), 1); auto data = gaugeMetrics.data(0); - EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); + EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field()); EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); EXPECT_EQ(1 /* subsystem name field */, data.dimensions_in_what().value_tuple().dimensions_value(0).field()); @@ -315,8 +316,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) { TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback, ATOM_TAG); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -371,7 +372,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) { EXPECT_GT((int)gaugeMetrics.data_size(), 1); auto data = gaugeMetrics.data(0); - EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); + EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field()); EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); EXPECT_EQ(1 /* subsystem name field */, data.dimensions_in_what().value_tuple().dimensions_value(0).field()); @@ -424,8 +425,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) { event_activation->set_ttl_seconds(ttlNs / 1000000000); ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), ATOM_TAG); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -493,7 +494,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) { EXPECT_GT((int)gaugeMetrics.data_size(), 0); auto data = gaugeMetrics.data(0); - EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); + EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field()); EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); EXPECT_EQ(1 /* subsystem name field */, data.dimensions_in_what().value_tuple().dimensions_value(0).field()); @@ -542,8 +543,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) { TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000; ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), ATOM_TAG); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -586,7 +587,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) { EXPECT_GT((int)gaugeMetrics.data_size(), 0); auto data = gaugeMetrics.data(0); - EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field()); + EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field()); EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size()); EXPECT_EQ(1 /* subsystem name field */, data.dimensions_in_what().value_tuple().dimensions_value(0).field()); diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp index 16b51d99535b..9d58867f09db 100644 --- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp @@ -12,22 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <android/os/BnPullAtomCallback.h> +#include <android/os/IPullAtomResultReceiver.h> +#include <binder/IPCThreadState.h> #include <gtest/gtest.h> -#include <binder/IPCThreadState.h> +#include <vector> + #include "src/StatsLogProcessor.h" #include "src/StatsService.h" #include "src/stats_log_util.h" #include "tests/statsd_test_util.h" -#include <vector> - namespace android { namespace os { namespace statsd { #ifdef __ANDROID__ - +namespace { const string kApp1 = "app1.sharing.1"; const int kConfigKey = 789130123; // Randomly chosen to avoid collisions with existing configs. const int kCallingUid = 0; // Randomly chosen @@ -109,6 +111,7 @@ StatsdConfig MakeGaugeMetricConfig(int64_t minTime) { gaugeMetric->set_min_bucket_size_nanos(minTime); return config; } +} // anonymous namespace TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) { StatsService service(nullptr, nullptr); @@ -202,6 +205,9 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) { TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { StatsService service(nullptr, nullptr); + service.mPullerManager->RegisterPullAtomCallback( + /*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {}, + new FakeSubsystemSleepCallback()); // Partial buckets don't occur when app is first installed. service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeValueMetricConfig(0)); @@ -220,6 +226,9 @@ TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { StatsService service(nullptr, nullptr); + service.mPullerManager->RegisterPullAtomCallback( + /*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {}, + new FakeSubsystemSleepCallback()); // Partial buckets don't occur when app is first installed. service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */)); diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp index e8d2ec514cad..a140af876474 100644 --- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp @@ -69,8 +69,9 @@ TEST(ValueMetricE2eTest, TestPulledEvents) { TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000; ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), + android::util::SUBSYSTEM_SLEEP_STATE); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -173,8 +174,9 @@ TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) { TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000; ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), + android::util::SUBSYSTEM_SLEEP_STATE); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); @@ -285,8 +287,9 @@ TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) { event_activation->set_ttl_seconds(ttlNs / 1000000000); ConfigKey cfgKey; - auto processor = CreateStatsLogProcessor( - baseTimeNs, configAddedTimeNs, config, cfgKey); + auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + new FakeSubsystemSleepCallback(), + android::util::SUBSYSTEM_SLEEP_STATE); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); processor->mPullerManager->ForceClearPullerCache(); diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp deleted file mode 100644 index ae92705aff4c..000000000000 --- a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#undef LOG_TAG -#define LOG_TAG "GpuStatsPuller_test" - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <graphicsenv/GpuStatsInfo.h> -#include <log/log.h> - -#include "src/external/GpuStatsPuller.h" -#include "statslog.h" - -#ifdef __ANDROID__ - -namespace android { -namespace os { -namespace statsd { - -// clang-format off -static const std::string DRIVER_PACKAGE_NAME = "TEST_DRIVER"; -static const std::string DRIVER_VERSION_NAME = "TEST_DRIVER_VERSION"; -static const std::string APP_PACKAGE_NAME = "TEST_APP"; -static const int64_t TIMESTAMP_WALLCLOCK = 111; -static const int64_t TIMESTAMP_ELAPSED = 222; -static const int64_t DRIVER_VERSION_CODE = 333; -static const int64_t DRIVER_BUILD_TIME = 444; -static const int64_t GL_LOADING_COUNT = 3; -static const int64_t GL_LOADING_FAILURE_COUNT = 1; -static const int64_t VK_LOADING_COUNT = 4; -static const int64_t VK_LOADING_FAILURE_COUNT = 0; -static const int64_t ANGLE_LOADING_COUNT = 2; -static const int64_t ANGLE_LOADING_FAILURE_COUNT = 1; -static const int64_t GL_DRIVER_LOADING_TIME_0 = 555; -static const int64_t GL_DRIVER_LOADING_TIME_1 = 666; -static const int64_t VK_DRIVER_LOADING_TIME_0 = 777; -static const int64_t VK_DRIVER_LOADING_TIME_1 = 888; -static const int64_t VK_DRIVER_LOADING_TIME_2 = 999; -static const int64_t ANGLE_DRIVER_LOADING_TIME_0 = 1010; -static const int64_t ANGLE_DRIVER_LOADING_TIME_1 = 1111; -static const int32_t VULKAN_VERSION = 1; -static const int32_t CPU_VULKAN_VERSION = 2; -static const int32_t GLES_VERSION = 3; -static const bool CPU_VULKAN_IN_USE = true; -static const bool FALSE_PREROTATION = true; -static const bool GLES_1_IN_USE = true; -static const size_t NUMBER_OF_VALUES_GLOBAL = 13; -static const size_t NUMBER_OF_VALUES_APP = 8; -// clang-format on - -class MockGpuStatsPuller : public GpuStatsPuller { -public: - MockGpuStatsPuller(const int tagId, vector<std::shared_ptr<LogEvent>>* data) - : GpuStatsPuller(tagId), mData(data){}; - -private: - bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override { - *data = *mData; - return true; - } - - vector<std::shared_ptr<LogEvent>>* mData; -}; - -class GpuStatsPuller_test : public ::testing::Test { -public: - GpuStatsPuller_test() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); - } - - ~GpuStatsPuller_test() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); - } -}; - -TEST_F(GpuStatsPuller_test, PullGpuStatsGlobalInfo) { - vector<std::shared_ptr<LogEvent>> inData, outData; - std::shared_ptr<LogEvent> event = make_shared<LogEvent>(android::util::GPU_STATS_GLOBAL_INFO, - TIMESTAMP_WALLCLOCK, TIMESTAMP_ELAPSED); - EXPECT_TRUE(event->write(DRIVER_PACKAGE_NAME)); - EXPECT_TRUE(event->write(DRIVER_VERSION_NAME)); - EXPECT_TRUE(event->write(DRIVER_VERSION_CODE)); - EXPECT_TRUE(event->write(DRIVER_BUILD_TIME)); - EXPECT_TRUE(event->write(GL_LOADING_COUNT)); - EXPECT_TRUE(event->write(GL_LOADING_FAILURE_COUNT)); - EXPECT_TRUE(event->write(VK_LOADING_COUNT)); - EXPECT_TRUE(event->write(VK_LOADING_FAILURE_COUNT)); - EXPECT_TRUE(event->write(VULKAN_VERSION)); - EXPECT_TRUE(event->write(CPU_VULKAN_VERSION)); - EXPECT_TRUE(event->write(GLES_VERSION)); - EXPECT_TRUE(event->write(ANGLE_LOADING_COUNT)); - EXPECT_TRUE(event->write(ANGLE_LOADING_FAILURE_COUNT)); - event->init(); - inData.emplace_back(event); - MockGpuStatsPuller mockPuller(android::util::GPU_STATS_GLOBAL_INFO, &inData); - mockPuller.ForceClearCache(); - mockPuller.Pull(&outData); - - ASSERT_EQ(1, outData.size()); - EXPECT_EQ(android::util::GPU_STATS_GLOBAL_INFO, outData[0]->GetTagId()); - ASSERT_EQ(NUMBER_OF_VALUES_GLOBAL, outData[0]->size()); - EXPECT_EQ(DRIVER_PACKAGE_NAME, outData[0]->getValues()[0].mValue.str_value); - EXPECT_EQ(DRIVER_VERSION_NAME, outData[0]->getValues()[1].mValue.str_value); - EXPECT_EQ(DRIVER_VERSION_CODE, outData[0]->getValues()[2].mValue.long_value); - EXPECT_EQ(DRIVER_BUILD_TIME, outData[0]->getValues()[3].mValue.long_value); - EXPECT_EQ(GL_LOADING_COUNT, outData[0]->getValues()[4].mValue.long_value); - EXPECT_EQ(GL_LOADING_FAILURE_COUNT, outData[0]->getValues()[5].mValue.long_value); - EXPECT_EQ(VK_LOADING_COUNT, outData[0]->getValues()[6].mValue.long_value); - EXPECT_EQ(VK_LOADING_FAILURE_COUNT, outData[0]->getValues()[7].mValue.long_value); - EXPECT_EQ(VULKAN_VERSION, outData[0]->getValues()[8].mValue.int_value); - EXPECT_EQ(CPU_VULKAN_VERSION, outData[0]->getValues()[9].mValue.int_value); - EXPECT_EQ(GLES_VERSION, outData[0]->getValues()[10].mValue.int_value); - EXPECT_EQ(ANGLE_LOADING_COUNT, outData[0]->getValues()[11].mValue.long_value); - EXPECT_EQ(ANGLE_LOADING_FAILURE_COUNT, outData[0]->getValues()[12].mValue.long_value); -} - -TEST_F(GpuStatsPuller_test, PullGpuStatsAppInfo) { - vector<std::shared_ptr<LogEvent>> inData, outData; - std::shared_ptr<LogEvent> event = make_shared<LogEvent>(android::util::GPU_STATS_APP_INFO, - TIMESTAMP_WALLCLOCK, TIMESTAMP_ELAPSED); - EXPECT_TRUE(event->write(APP_PACKAGE_NAME)); - EXPECT_TRUE(event->write(DRIVER_VERSION_CODE)); - std::vector<int64_t> glDriverLoadingTime; - glDriverLoadingTime.emplace_back(GL_DRIVER_LOADING_TIME_0); - glDriverLoadingTime.emplace_back(GL_DRIVER_LOADING_TIME_1); - std::vector<int64_t> vkDriverLoadingTime; - vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_0); - vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_1); - vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_2); - std::vector<int64_t> angleDriverLoadingTime; - angleDriverLoadingTime.emplace_back(ANGLE_DRIVER_LOADING_TIME_0); - angleDriverLoadingTime.emplace_back(ANGLE_DRIVER_LOADING_TIME_1); - EXPECT_TRUE(event->write(int64VectorToProtoByteString(glDriverLoadingTime))); - EXPECT_TRUE(event->write(int64VectorToProtoByteString(vkDriverLoadingTime))); - EXPECT_TRUE(event->write(int64VectorToProtoByteString(angleDriverLoadingTime))); - EXPECT_TRUE(event->write(CPU_VULKAN_IN_USE)); - EXPECT_TRUE(event->write(FALSE_PREROTATION)); - EXPECT_TRUE(event->write(GLES_1_IN_USE)); - event->init(); - inData.emplace_back(event); - MockGpuStatsPuller mockPuller(android::util::GPU_STATS_APP_INFO, &inData); - mockPuller.ForceClearCache(); - mockPuller.Pull(&outData); - - ASSERT_EQ(1, outData.size()); - EXPECT_EQ(android::util::GPU_STATS_APP_INFO, outData[0]->GetTagId()); - ASSERT_EQ(NUMBER_OF_VALUES_APP, outData[0]->size()); - EXPECT_EQ(APP_PACKAGE_NAME, outData[0]->getValues()[0].mValue.str_value); - EXPECT_EQ(DRIVER_VERSION_CODE, outData[0]->getValues()[1].mValue.long_value); - EXPECT_EQ(int64VectorToProtoByteString(glDriverLoadingTime), - outData[0]->getValues()[2].mValue.str_value); - EXPECT_EQ(int64VectorToProtoByteString(vkDriverLoadingTime), - outData[0]->getValues()[3].mValue.str_value); - EXPECT_EQ(int64VectorToProtoByteString(angleDriverLoadingTime), - outData[0]->getValues()[4].mValue.str_value); - EXPECT_EQ(CPU_VULKAN_IN_USE, outData[0]->getValues()[5].mValue.int_value); - EXPECT_EQ(FALSE_PREROTATION, outData[0]->getValues()[6].mValue.int_value); - EXPECT_EQ(GLES_1_IN_USE, outData[0]->getValues()[7].mValue.int_value); -} - -} // namespace statsd -} // namespace os -} // namespace android -#else -GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif diff --git a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp b/cmds/statsd/tests/external/IncidentReportArgs_test.cpp deleted file mode 100644 index 38bc19452afa..000000000000 --- a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2018 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <android/os/IncidentReportArgs.h> - -#include <gtest/gtest.h> - -namespace android { -namespace os { -namespace statsd { - -TEST(IncidentReportArgsTest, testSerialization) { - IncidentReportArgs args; - args.setAll(0); - args.addSection(1000); - args.addSection(1001); - - vector<uint8_t> header1; - header1.push_back(0x1); - header1.push_back(0x2); - vector<uint8_t> header2; - header1.push_back(0x22); - header1.push_back(0x33); - - args.addHeader(header1); - args.addHeader(header2); - - args.setPrivacyPolicy(1); - - args.setReceiverPkg("com.android.os"); - args.setReceiverCls("com.android.os.Receiver"); - - Parcel out; - status_t err = args.writeToParcel(&out); - EXPECT_EQ(NO_ERROR, err); - - out.setDataPosition(0); - - IncidentReportArgs args2; - err = args2.readFromParcel(&out); - EXPECT_EQ(NO_ERROR, err); - - EXPECT_EQ(0, args2.all()); - set<int> sections; - sections.insert(1000); - sections.insert(1001); - EXPECT_EQ(sections, args2.sections()); - EXPECT_EQ(1, args2.getPrivacyPolicy()); - - EXPECT_EQ(string("com.android.os"), args2.receiverPkg()); - EXPECT_EQ(string("com.android.os.Receiver"), args2.receiverCls()); - - vector<vector<uint8_t>> headers; - headers.push_back(header1); - headers.push_back(header2); - EXPECT_EQ(headers, args2.headers()); -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp index 2576cf5b1339..a011692ee625 100644 --- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp +++ b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp @@ -50,11 +50,11 @@ int64_t pullTimeoutNs; int64_t pullCoolDownNs; std::thread pullThread; -stats_event* createSimpleEvent(int64_t value) { - stats_event* event = stats_event_obtain(); - stats_event_set_atom_id(event, pullTagId); - stats_event_write_int64(event, value); - stats_event_build(event); +AStatsEvent* createSimpleEvent(int64_t value) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, pullTagId); + AStatsEvent_writeInt64(event, value); + AStatsEvent_build(event); return event; } @@ -62,16 +62,16 @@ void executePull(const sp<IPullAtomResultReceiver>& resultReceiver) { // Convert stats_events into StatsEventParcels. std::vector<android::util::StatsEventParcel> parcels; for (int i = 0; i < values.size(); i++) { - stats_event* event = createSimpleEvent(values[i]); + AStatsEvent* event = createSimpleEvent(values[i]); size_t size; - uint8_t* buffer = stats_event_get_buffer(event, &size); + uint8_t* buffer = AStatsEvent_getBuffer(event, &size); android::util::StatsEventParcel p; // vector.assign() creates a copy, but this is inevitable unless // stats_event.h/c uses a vector as opposed to a buffer. p.buffer.assign(buffer, buffer + size); parcels.push_back(std::move(p)); - stats_event_release(event); + AStatsEvent_release(event); } sleep_for(std::chrono::nanoseconds(pullDelayNs)); diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 92e8241d9ec2..f6245ac8ea9a 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -3333,7 +3333,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequeste EXPECT_EQ(NanoToMillis(bucketStartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); @@ -3393,7 +3393,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWron EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket3StartTimeNs), + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); @@ -3470,7 +3470,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWro EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket3StartTimeNs), + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); @@ -3519,7 +3519,8 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) // Check dump report. ProtoOutputStream output; std::set<string> strSet; - valueProducer->onDumpReport(bucketStartTimeNs + 100, true /* include recent buckets */, true, + int64_t dumpReportTimeNs = bucketStartTimeNs + 10000; + valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); StatsLogReport report = outputStreamToProto(&output); @@ -3529,13 +3530,13 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) EXPECT_EQ(NanoToMillis(bucketStartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); auto dropEvent = report.value_metrics().skipped(0).drop_event(0); EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason()); - EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 100), dropEvent.drop_time_millis()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); } /* @@ -3569,7 +3570,8 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) { // Check dump report. ProtoOutputStream output; std::set<string> strSet; - valueProducer->onDumpReport(bucketStartTimeNs + 100, true /* include recent buckets */, true, + int64_t dumpReportTimeNs = bucketStartTimeNs + 10000; + valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); StatsLogReport report = outputStreamToProto(&output); @@ -3579,13 +3581,13 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) { EXPECT_EQ(NanoToMillis(bucketStartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); auto dropEvent = report.value_metrics().skipped(0).drop_event(0); EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason()); - EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 100), dropEvent.drop_time_millis()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); } /* @@ -3691,8 +3693,9 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) { // Check dump report. ProtoOutputStream output; std::set<string> strSet; - valueProducer->onDumpReport(bucketStartTimeNs + 9000000, true /* include recent buckets */, - true, NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); + int64_t dumpReportTimeNs = bucketStartTimeNs + 9000000; + valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, + NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); StatsLogReport report = outputStreamToProto(&output); EXPECT_TRUE(report.has_value_metrics()); @@ -3701,13 +3704,13 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) { EXPECT_EQ(NanoToMillis(bucketStartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); auto dropEvent = report.value_metrics().skipped(0).drop_event(0); EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason()); - EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), dropEvent.drop_time_millis()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); } /* @@ -3739,7 +3742,8 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) { // Check dump report. ProtoOutputStream output; std::set<string> strSet; - valueProducer->onDumpReport(bucketStartTimeNs + 1000, true /* include recent buckets */, true, + int64_t dumpReportTimeNs = bucketStartTimeNs + 1000; + valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, FAST /* dumpLatency */, &strSet, &output); StatsLogReport report = outputStreamToProto(&output); @@ -3749,7 +3753,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) { EXPECT_EQ(NanoToMillis(bucketStartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(2, report.value_metrics().skipped(0).drop_event_size()); @@ -3759,7 +3763,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) { dropEvent = report.value_metrics().skipped(0).drop_event(1); EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason()); - EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 1000), dropEvent.drop_time_millis()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); } /* @@ -3826,6 +3830,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) { // Check dump report. ProtoOutputStream output; std::set<string> strSet; + int64_t dumpReportTimeNs = bucketStartTimeNs + 1000; // Because we already have 10 dump events in the current bucket, // this case should not be added to the list of dump events. valueProducer->onDumpReport(bucketStartTimeNs + 1000, true /* include recent buckets */, true, @@ -3838,7 +3843,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) { EXPECT_EQ(NanoToMillis(bucketStartTimeNs), report.value_metrics().skipped(0).start_bucket_elapsed_millis()); - EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), report.value_metrics().skipped(0).end_bucket_elapsed_millis()); EXPECT_EQ(10, report.value_metrics().skipped(0).drop_event_size()); diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp index 84aaa54bc5bf..b0acd5ad7452 100644 --- a/cmds/statsd/tests/state/StateTracker_test.cpp +++ b/cmds/statsd/tests/state/StateTracker_test.cpp @@ -127,6 +127,23 @@ std::shared_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::stri event->init(); return event; } + +std::shared_ptr<LogEvent> buildBleScanEvent(int uid, bool acquire, bool reset) { + std::vector<AttributionNodeInternal> chain; + chain.push_back(AttributionNodeInternal()); + AttributionNodeInternal& attr = chain.back(); + attr.set_uid(uid); + + std::shared_ptr<LogEvent> event = + std::make_shared<LogEvent>(android::util::BLE_SCAN_STATE_CHANGED, 1000); + event->write(chain); + event->write(reset ? 2 : acquire ? 1 : 0); // PARTIAL_WAKE_LOCK + event->write(0); // filtered + event->write(0); // first match + event->write(0); // opportunistic + event->init(); + return event; +} // END: build event functions. // START: get primary key functions @@ -277,6 +294,80 @@ TEST(StateTrackerTest, TestUnregisterListener) { } /** + * Test a binary state atom with nested counting. + * + * To go from an "ON" state to an "OFF" state with nested counting, we must see + * an equal number of "OFF" events as "ON" events. + * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state. + * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state. + */ +TEST(StateTrackerTest, TestStateChangeNested) { + sp<TestStateListener> listener = new TestStateListener(); + StateManager mgr; + mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener); + + std::shared_ptr<LogEvent> event1 = + buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/); + mgr.onLogEvent(*event1); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(1, listener->updates[0].mState); + listener->updates.clear(); + + std::shared_ptr<LogEvent> event2 = + buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/); + mgr.onLogEvent(*event2); + EXPECT_EQ(0, listener->updates.size()); + + std::shared_ptr<LogEvent> event3 = + buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/); + mgr.onLogEvent(*event3); + EXPECT_EQ(0, listener->updates.size()); + + std::shared_ptr<LogEvent> event4 = + buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/); + mgr.onLogEvent(*event4); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(0, listener->updates[0].mState); +} + +/** + * Test a state atom with a reset state. + * + * If the reset state value is seen, every state in the map is set to the default + * state and every listener is notified. + */ +TEST(StateTrackerTest, TestStateChangeReset) { + sp<TestStateListener> listener = new TestStateListener(); + StateManager mgr; + mgr.registerListener(android::util::BLE_SCAN_STATE_CHANGED, listener); + + std::shared_ptr<LogEvent> event1 = + buildBleScanEvent(1000 /* uid */, true /*acquire*/, false /*reset*/); + mgr.onLogEvent(*event1); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); + listener->updates.clear(); + + std::shared_ptr<LogEvent> event2 = + buildBleScanEvent(2000 /* uid */, true /*acquire*/, false /*reset*/); + mgr.onLogEvent(*event2); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); + listener->updates.clear(); + + std::shared_ptr<LogEvent> event3 = + buildBleScanEvent(2000 /* uid */, false /*acquire*/, true /*reset*/); + mgr.onLogEvent(*event3); + EXPECT_EQ(2, listener->updates.size()); + EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState); + EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState); +} + +/** * Test StateManager's onLogEvent and StateListener's onStateChanged correctly * updates listener for states without primary keys. */ @@ -334,7 +425,7 @@ TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) { // Log event. std::shared_ptr<LogEvent> event = - buildPartialWakelockEvent(1001 /* uid */, "tag1", false /* acquire */); + buildPartialWakelockEvent(1001 /* uid */, "tag1", true /* acquire */); mgr.onLogEvent(*event); EXPECT_EQ(1, mgr.getStateTrackersCount()); @@ -346,23 +437,25 @@ TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) { EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value); EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value); EXPECT_EQ("tag1", listener1->updates[0].mKey.getValues()[2].mValue.str_value); - EXPECT_EQ(WakelockStateChanged::RELEASE, listener1->updates[0].mState); + EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState); // Check StateTracker was updated by querying for state. HashableDimensionKey queryKey; getPartialWakelockKey(1001 /* uid */, "tag1", &queryKey); - EXPECT_EQ(WakelockStateChanged::RELEASE, + EXPECT_EQ(WakelockStateChanged::ACQUIRE, getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey)); // No state stored for this query key. HashableDimensionKey queryKey2; getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2); - EXPECT_EQ(-1, getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey2)); + EXPECT_EQ(WakelockStateChanged::RELEASE, + getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey2)); // Partial query fails. HashableDimensionKey queryKey3; getPartialWakelockKey(1001 /* uid */, &queryKey3); - EXPECT_EQ(-1, getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey3)); + EXPECT_EQ(WakelockStateChanged::RELEASE, + getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey3)); } /** diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index e0aecceac4e3..db09ee9311ba 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -580,9 +580,15 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( } sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, - const StatsdConfig& config, const ConfigKey& key) { + const StatsdConfig& config, const ConfigKey& key, + const sp<IPullAtomCallback>& puller, + const int32_t atomTag) { sp<UidMap> uidMap = new UidMap(); sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + if (puller != nullptr) { + pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {}, + puller); + } sp<AlarmMonitor> anomalyAlarmMonitor = new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){}, [](const sp<IStatsCompanionService>&){}); @@ -942,6 +948,34 @@ void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) { } } +binder::Status FakeSubsystemSleepCallback::onPullAtom( + int atomTag, const sp<IPullAtomResultReceiver>& resultReceiver) { + // Convert stats_events into StatsEventParcels. + std::vector<android::util::StatsEventParcel> parcels; + for (int i = 1; i < 3; i++) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, atomTag); + std::string subsystemName = "subsystem_name_"; + subsystemName = subsystemName + std::to_string(i); + AStatsEvent_writeString(event, subsystemName.c_str()); + AStatsEvent_writeString(event, "subsystem_subname foo"); + AStatsEvent_writeInt64(event, /*count= */ i); + AStatsEvent_writeInt64(event, /*time_millis= */ i * 100); + AStatsEvent_build(event); + size_t size; + uint8_t* buffer = AStatsEvent_getBuffer(event, &size); + + android::util::StatsEventParcel p; + // vector.assign() creates a copy, but this is inevitable unless + // stats_event.h/c uses a vector as opposed to a buffer. + p.buffer.assign(buffer, buffer + size); + parcels.push_back(std::move(p)); + AStatsEvent_write(event); + } + resultReceiver->pullFinished(atomTag, /*success=*/true, parcels); + return binder::Status::ok(); +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index 9bdfeebe561f..576a4916d60b 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -14,12 +14,16 @@ #pragma once +#include <android/os/BnPullAtomCallback.h> +#include <android/os/IPullAtomCallback.h> +#include <android/os/IPullAtomResultReceiver.h> #include <gtest/gtest.h> + #include "frameworks/base/cmds/statsd/src/stats_log.pb.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "src/StatsLogProcessor.h" -#include "src/logd/LogEvent.h" #include "src/hash.h" +#include "src/logd/LogEvent.h" #include "src/stats_log_util.h" #include "statslog.h" @@ -224,9 +228,10 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( AttributionNodeInternal CreateAttribution(const int& uid, const string& tag); // Create a statsd log event processor upon the start time in seconds, config and key. -sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, - const int64_t currentTimeNs, - const StatsdConfig& config, const ConfigKey& key); +sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, + const StatsdConfig& config, const ConfigKey& key, + const sp<IPullAtomCallback>& puller = nullptr, + const int32_t atomTag = 0 /*for puller only*/); // Util function to sort the log events by timestamp. void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events); @@ -278,6 +283,12 @@ bool backfillDimensionPath(const DimensionsValue& path, const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues, DimensionsValue* dimension); +class FakeSubsystemSleepCallback : public BnPullAtomCallback { +public: + binder::Status onPullAtom(int atomTag, + const sp<IPullAtomResultReceiver>& resultReceiver) override; +}; + template <typename T> void backfillDimensionPath(const DimensionsValue& whatPath, const DimensionsValue& conditionPath, diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp index b91e5a0ad3a1..27a86e4230d8 100644 --- a/cmds/statsd/tests/storage/StorageManager_test.cpp +++ b/cmds/statsd/tests/storage/StorageManager_test.cpp @@ -40,40 +40,12 @@ TEST(StorageManagerTest, TrainInfoReadWriteTest) { bool result; - result = StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.trainName, - trainInfo.status, trainInfo.experimentIds); + result = StorageManager::writeTrainInfo(trainInfo); EXPECT_TRUE(result); InstallTrainInfo trainInfoResult; - result = StorageManager::readTrainInfo(trainInfoResult); - EXPECT_TRUE(result); - - EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode); - EXPECT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size()); - EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName); - EXPECT_EQ(trainInfo.status, trainInfoResult.status); - EXPECT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size()); - EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds); -} - -TEST(StorageManagerTest, TrainInfoReadWriteEmptyTrainNameTest) { - InstallTrainInfo trainInfo; - trainInfo.trainVersionCode = 12345; - trainInfo.trainName = ""; - trainInfo.status = 1; - const char* expIds = "test_ids"; - trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds)); - - bool result; - - result = StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.trainName, - trainInfo.status, trainInfo.experimentIds); - - EXPECT_TRUE(result); - - InstallTrainInfo trainInfoResult; - result = StorageManager::readTrainInfo(trainInfoResult); + result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult); EXPECT_TRUE(result); EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode); @@ -94,13 +66,12 @@ TEST(StorageManagerTest, TrainInfoReadWriteTrainNameSizeOneTest) { bool result; - result = StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.trainName, - trainInfo.status, trainInfo.experimentIds); + result = StorageManager::writeTrainInfo(trainInfo); EXPECT_TRUE(result); InstallTrainInfo trainInfoResult; - result = StorageManager::readTrainInfo(trainInfoResult); + result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult); EXPECT_TRUE(result); EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode); |