From 8b8d526961a6cc5a6f2fa690acea7691437370f2 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Tue, 27 Oct 2020 22:51:26 +0800 Subject: profcollectd: Use device_config to control behaviours This allows server to push out experiment studies. Also applied clang-format. Test: build Test: adb shell device_config put profcollect_native_boot KEY VALUE Bug: 79161490 Change-Id: I0ad5c1d01d7b832885ce772f9bbc772c895ed03e --- profcollectd/libprofcollectd/Android.bp | 2 + profcollectd/libprofcollectd/config_utils.cpp | 49 +++++++++++++++++++++ profcollectd/libprofcollectd/config_utils.h | 38 ++++++++++++++++ profcollectd/libprofcollectd/interface.cpp | 2 +- profcollectd/libprofcollectd/scheduler.cpp | 63 +++++++++++---------------- 5 files changed, 116 insertions(+), 38 deletions(-) create mode 100644 profcollectd/libprofcollectd/config_utils.cpp create mode 100644 profcollectd/libprofcollectd/config_utils.h diff --git a/profcollectd/libprofcollectd/Android.bp b/profcollectd/libprofcollectd/Android.bp index fa02cf5f..92facb91 100644 --- a/profcollectd/libprofcollectd/Android.bp +++ b/profcollectd/libprofcollectd/Android.bp @@ -58,6 +58,7 @@ cc_library { "libsimpleperf_profcollect", "libutils", "libziparchive", + "server_configurable_flags", ], static_libs: [ @@ -67,6 +68,7 @@ cc_library { srcs: [ "binder_service.cpp", "compress.cpp", + "config_utils.cpp", "interface.cpp", "scheduler.cpp", "simpleperf_etm_provider.cpp", diff --git a/profcollectd/libprofcollectd/config_utils.cpp b/profcollectd/libprofcollectd/config_utils.cpp new file mode 100644 index 00000000..40a03427 --- /dev/null +++ b/profcollectd/libprofcollectd/config_utils.cpp @@ -0,0 +1,49 @@ +// +// 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. +// 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 "config_utils.h" + +#include +#include + +static const std::string PROFCOLLECT_CONFIG_NAMESPACE = "profcollect_native_boot"; + +namespace android { +namespace profcollectd { + +using ::android::base::GetProperty; +using ::server_configurable_flags::GetServerConfigurableFlag; + +std::string getBuildFingerprint() { + return GetProperty("ro.build.fingerprint", "unknown"); +} + +std::string getConfigFlag(const config_t& config) { + return GetServerConfigurableFlag(PROFCOLLECT_CONFIG_NAMESPACE, config.name, config.defaultValue); +} + +int getConfigFlagInt(const config_t& config) { + std::string value = getConfigFlag(config); + return std::stoi(value); +} + +float getConfigFlagFloat(const config_t& config) { + std::string value = getConfigFlag(config); + return std::stof(value); +} + +} // namespace profcollectd +} // namespace android diff --git a/profcollectd/libprofcollectd/config_utils.h b/profcollectd/libprofcollectd/config_utils.h new file mode 100644 index 00000000..8ad5d0d1 --- /dev/null +++ b/profcollectd/libprofcollectd/config_utils.h @@ -0,0 +1,38 @@ +// +// 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. +// 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 + +#include +#include + +namespace android { +namespace profcollectd { + +struct config_t { + const char* name; + const char* defaultValue; +}; + +std::string getBuildFingerprint(); +std::string getConfigFlag(const config_t& config); +int getConfigFlagInt(const config_t& config); +float getConfigFlagFloat(const config_t& config); + +} // namespace profcollectd +} // namespace android diff --git a/profcollectd/libprofcollectd/interface.cpp b/profcollectd/libprofcollectd/interface.cpp index fbc3e79c..71f71f3e 100644 --- a/profcollectd/libprofcollectd/interface.cpp +++ b/profcollectd/libprofcollectd/interface.cpp @@ -24,8 +24,8 @@ #include "binder_service.h" -using com::android::server::profcollect::IProfCollectd; using android::profcollectd::ProfcollectdBinder; +using com::android::server::profcollect::IProfCollectd; using namespace android; diff --git a/profcollectd/libprofcollectd/scheduler.cpp b/profcollectd/libprofcollectd/scheduler.cpp index cf707bcc..ce316eed 100644 --- a/profcollectd/libprofcollectd/scheduler.cpp +++ b/profcollectd/libprofcollectd/scheduler.cpp @@ -19,37 +19,32 @@ #include "scheduler.h" #include -#include #include #include -#include #include "compress.h" +#include "config_utils.h" #include "hwtrace_provider.h" #include "json/json.h" #include "json/writer.h" namespace fs = std::filesystem; +namespace android { +namespace profcollectd { + // Default option values. -using config_t = std::pair>; -static constexpr const config_t CONFIG_BUILD_FINGERPRINT = {"Fingerprint", "unknown"}; -static constexpr const config_t CONFIG_COLLECTION_INTERVAL_SEC = {"CollectionInterval", 600}; -static constexpr const config_t CONFIG_SAMPLING_PERIOD_MS = {"SamplingPeriod", 500}; -static constexpr const config_t CONFIG_BINARY_FILTER = {"BinaryFilter", ""}; +static constexpr config_t CONFIG_BUILD_FINGERPRINT = {"build_fingerprint", "unknown"}; +static constexpr config_t CONFIG_COLLECTION_INTERVAL_SEC = {"collection_interval", "600"}; +static constexpr config_t CONFIG_SAMPLING_PERIOD_SEC = {"sampling_period", "0.5"}; +static constexpr config_t CONFIG_BINARY_FILTER = {"binary_filter", ""}; static const fs::path OUT_ROOT_DIR("/data/misc/profcollectd"); static const fs::path TRACE_DIR(OUT_ROOT_DIR / "trace"); static const fs::path OUTPUT_DIR(OUT_ROOT_DIR / "output"); static const fs::path REPORT_FILE(OUT_ROOT_DIR / "report.zip"); -namespace android { -namespace profcollectd { - -using ::android::base::GetIntProperty; -using ::android::base::GetProperty; - // Hwtrace provider registry extern std::unique_ptr REGISTER_SIMPLEPERF_ETM_PROVIDER(); @@ -114,16 +109,12 @@ OptError ProfcollectdScheduler::ReadConfig() { const std::lock_guard lock(mu); - config.buildFingerprint = GetProperty("ro.build.fingerprint", "unknown"); - config.collectionInterval = std::chrono::seconds( - GetIntProperty("persist.profcollectd.collection_interval", - std::get(CONFIG_COLLECTION_INTERVAL_SEC.second))); - config.samplingPeriod = std::chrono::milliseconds(GetIntProperty( - "persist.profcollectd.sampling_period_ms", - std::get(CONFIG_SAMPLING_PERIOD_MS.second))); - config.binaryFilter = - GetProperty("persist.profcollectd.binary_filter", - std::get(CONFIG_BINARY_FILTER.second)); + config.buildFingerprint = getBuildFingerprint(); + config.collectionInterval = + std::chrono::seconds(getConfigFlagInt(CONFIG_COLLECTION_INTERVAL_SEC)); + config.samplingPeriod = + std::chrono::duration(getConfigFlagFloat(CONFIG_SAMPLING_PERIOD_SEC)); + config.binaryFilter = getConfigFlag(CONFIG_BINARY_FILTER); ClearOnConfigChange(config); return std::nullopt; @@ -155,7 +146,7 @@ OptError ProfcollectdScheduler::TerminateCollection() { } OptError ProfcollectdScheduler::TraceOnce(const std::string& tag) { - if(!hwtracer) { + if (!hwtracer) { return "No trace provider registered."; } @@ -169,13 +160,12 @@ OptError ProfcollectdScheduler::TraceOnce(const std::string& tag) { } OptError ProfcollectdScheduler::ProcessProfile() { - if(!hwtracer) { + if (!hwtracer) { return "No trace provider registered."; } const std::lock_guard lock(mu); - bool success = - hwtracer->Process(TRACE_DIR, OUTPUT_DIR, config.binaryFilter); + bool success = hwtracer->Process(TRACE_DIR, OUTPUT_DIR, config.binaryFilter); if (!success) { static std::string errmsg = "Process profiles failed"; return errmsg; @@ -191,8 +181,7 @@ OptError ProfcollectdScheduler::CreateProfileReport() { std::vector profiles; if (fs::exists(OUTPUT_DIR)) { - profiles.insert(profiles.begin(), fs::directory_iterator(OUTPUT_DIR), - fs::directory_iterator()); + profiles.insert(profiles.begin(), fs::directory_iterator(OUTPUT_DIR), fs::directory_iterator()); } bool success = CompressFiles(REPORT_FILE, profiles); if (!success) { @@ -210,10 +199,10 @@ OptError ProfcollectdScheduler::GetSupportedProvider(std::string& provider) { std::ostream& operator<<(std::ostream& os, const ProfcollectdScheduler::Config& config) { Json::Value root; const auto writer = std::make_unique(); - root[CONFIG_BUILD_FINGERPRINT.first] = config.buildFingerprint; - root[CONFIG_COLLECTION_INTERVAL_SEC.first] = config.collectionInterval.count(); - root[CONFIG_SAMPLING_PERIOD_MS.first] = config.samplingPeriod.count(); - root[CONFIG_BINARY_FILTER.first] = config.binaryFilter.c_str(); + root[CONFIG_BUILD_FINGERPRINT.name] = config.buildFingerprint; + root[CONFIG_COLLECTION_INTERVAL_SEC.name] = config.collectionInterval.count(); + root[CONFIG_SAMPLING_PERIOD_SEC.name] = config.samplingPeriod.count(); + root[CONFIG_BINARY_FILTER.name] = config.binaryFilter.c_str(); writer->write(os, root); return os; } @@ -226,12 +215,12 @@ std::istream& operator>>(std::istream& is, ProfcollectdScheduler::Config& config return is; } - config.buildFingerprint = root[CONFIG_BUILD_FINGERPRINT.first].asString(); + config.buildFingerprint = root[CONFIG_BUILD_FINGERPRINT.name].asString(); config.collectionInterval = - std::chrono::seconds(root[CONFIG_COLLECTION_INTERVAL_SEC.first].asInt64()); + std::chrono::seconds(root[CONFIG_COLLECTION_INTERVAL_SEC.name].asInt64()); config.samplingPeriod = - std::chrono::duration(root[CONFIG_SAMPLING_PERIOD_MS.first].asFloat()); - config.binaryFilter = root[CONFIG_BINARY_FILTER.first].asString(); + std::chrono::duration(root[CONFIG_SAMPLING_PERIOD_SEC.name].asFloat()); + config.binaryFilter = root[CONFIG_BINARY_FILTER.name].asString(); return is; } -- cgit v1.2.3