diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..c028497 --- /dev/null +++ b/Android.bp @@ -0,0 +1,5 @@ +soong_namespace { + imports: [ + "hardware/google/pixel", + ], +} diff --git a/common.mk b/common.mk index 7f63e95..95511f4 100644 --- a/common.mk +++ b/common.mk @@ -158,7 +158,8 @@ PRODUCT_USE_DYNAMIC_PARTITIONS := true # Power PRODUCT_PACKAGES += \ - android.hardware.power@1.3-service.xiaomi_sm6250-libperfmgr + android.hardware.power@1.3-service.xiaomi_sm6250-libperfmgr \ + android.hardware.power.stats@1.0-service.xiaomi_sm6250 # RCS PRODUCT_PACKAGES += \ @@ -184,7 +185,8 @@ PRODUCT_COPY_FILES += \ # Soong namespaces PRODUCT_SOONG_NAMESPACES += \ - $(LOCAL_PATH) + $(LOCAL_PATH) \ + hardware/google/pixel # Telephony PRODUCT_PACKAGES += \ diff --git a/powerstats/Android.bp b/powerstats/Android.bp new file mode 100644 index 0000000..64e412f --- /dev/null +++ b/powerstats/Android.bp @@ -0,0 +1,41 @@ +// +// 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. +cc_binary { + name: "android.hardware.power.stats@1.0-service.xiaomi_sm6250", + relative_install_path: "hw", + vintf_fragments: ["android.hardware.power.stats@1.0-service.xiaomi_sm6250.xml"], + init_rc: ["android.hardware.power.stats@1.0-service.xiaomi_sm6250.rc"], + srcs: ["service.cpp"], + cflags: [ + "-Wall", + "-Werror", + ], + static_libs: [ + "libpixelpowerstats", + ], + shared_libs: [ + "libbase", + "libcutils", + "libhidlbase", + "libhidltransport", + "libfmq", + "liblog", + "libutils", + "android.hardware.power.stats@1.0", + "pixelpowerstats_provider_aidl_interface-cpp", + "libbinder", + ], + vendor: true, +} diff --git a/powerstats/android.hardware.power.stats@1.0-service.xiaomi_sm6250.rc b/powerstats/android.hardware.power.stats@1.0-service.xiaomi_sm6250.rc new file mode 100644 index 0000000..cb9be66 --- /dev/null +++ b/powerstats/android.hardware.power.stats@1.0-service.xiaomi_sm6250.rc @@ -0,0 +1,4 @@ +service vendor.power.stats-hal-1-0 /vendor/bin/hw/android.hardware.power.stats@1.0-service.xiaomi_sm6250 + class hal + user system + group system diff --git a/powerstats/android.hardware.power.stats@1.0-service.xiaomi_sm6250.xml b/powerstats/android.hardware.power.stats@1.0-service.xiaomi_sm6250.xml new file mode 100644 index 0000000..de084e2 --- /dev/null +++ b/powerstats/android.hardware.power.stats@1.0-service.xiaomi_sm6250.xml @@ -0,0 +1,11 @@ + + + android.hardware.power.stats + hwbinder + 1.0 + + IPowerStats + default + + + diff --git a/powerstats/service.cpp b/powerstats/service.cpp new file mode 100644 index 0000000..d42558f --- /dev/null +++ b/powerstats/service.cpp @@ -0,0 +1,148 @@ +/* + * 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 LOG_TAG "android.hardware.power.stats@1.0-service.pixel" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using android::OK; +using android::sp; +using android::status_t; + +// libhwbinder: +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +// Generated HIDL files +using android::hardware::power::stats::V1_0::IPowerStats; +using android::hardware::power::stats::V1_0::PowerEntityInfo; +using android::hardware::power::stats::V1_0::PowerEntityStateSpace; +using android::hardware::power::stats::V1_0::PowerEntityType; +using android::hardware::power::stats::V1_0::implementation::PowerStats; + +// Pixel specific +using android::hardware::google::pixel::powerstats::AidlStateResidencyDataProvider; +using android::hardware::google::pixel::powerstats::generateGenericStateResidencyConfigs; +using android::hardware::google::pixel::powerstats::GenericStateResidencyDataProvider; +using android::hardware::google::pixel::powerstats::PowerEntityConfig; +using android::hardware::google::pixel::powerstats::StateResidencyConfig; +using android::hardware::google::pixel::powerstats::WlanStateResidencyDataProvider; + +int main(int /* argc */, char ** /* argv */) { + ALOGE("power.stats service 1.0 is starting."); + + + PowerStats *service = new PowerStats(); + + // Add power entities related to rpmh + const uint64_t RPM_CLK = 19200; // RPM runs at 19.2Mhz. Divide by 19200 for msec + std::function rpmConvertToMs = [](uint64_t a) { return a / RPM_CLK; }; + std::vector rpmStateResidencyConfigs = { + {.name = "Sleep", + .entryCountSupported = true, + .entryCountPrefix = "Sleep Count:", + .totalTimeSupported = true, + .totalTimePrefix = "Sleep Accumulated Duration:", + .totalTimeTransform = rpmConvertToMs, + .lastEntrySupported = true, + .lastEntryPrefix = "Sleep Last Entered At:", + .lastEntryTransform = rpmConvertToMs}}; + + sp rpmSdp = + new GenericStateResidencyDataProvider("/sys/power/rpmh_stats/master_stats"); + + uint32_t apssId = service->addPowerEntity("APSS", PowerEntityType::SUBSYSTEM); + rpmSdp->addEntity(apssId, PowerEntityConfig("APSS", rpmStateResidencyConfigs)); + + uint32_t mpssId = service->addPowerEntity("MPSS", PowerEntityType::SUBSYSTEM); + rpmSdp->addEntity(mpssId, PowerEntityConfig("MPSS", rpmStateResidencyConfigs)); + + uint32_t adspId = service->addPowerEntity("ADSP", PowerEntityType::SUBSYSTEM); + rpmSdp->addEntity(adspId, PowerEntityConfig("ADSP", rpmStateResidencyConfigs)); + + uint32_t cdspId = service->addPowerEntity("CDSP", PowerEntityType::SUBSYSTEM); + rpmSdp->addEntity(cdspId, PowerEntityConfig("CDSP", rpmStateResidencyConfigs)); + + service->addStateResidencyDataProvider(rpmSdp); + + // Add SoC power entity + StateResidencyConfig socStateConfig = { + .entryCountSupported = true, + .entryCountPrefix = "count:", + .totalTimeSupported = true, + .totalTimePrefix = "actual last sleep(msec):", + .lastEntrySupported = false + }; + std::vector> socStateHeaders = { + std::make_pair("AOSD", "RPM Mode:aosd"), + std::make_pair("CXSD", "RPM Mode:cxsd"), + std::make_pair("DDR", "RPM Mode:ddr"), + }; + + sp socSdp = + new GenericStateResidencyDataProvider("/sys/power/system_sleep/stats"); + + uint32_t socId = service->addPowerEntity("SoC", PowerEntityType::POWER_DOMAIN); + socSdp->addEntity(socId, + PowerEntityConfig(generateGenericStateResidencyConfigs(socStateConfig, socStateHeaders))); + + service->addStateResidencyDataProvider(socSdp); + + // Add WLAN power entity + uint32_t wlanId = service->addPowerEntity("WLAN", PowerEntityType::SUBSYSTEM); + sp wlanSdp = + new WlanStateResidencyDataProvider(wlanId, "/sys/kernel/wlan/power_stats"); + service->addStateResidencyDataProvider(wlanSdp); + + // Add Power Entities that require the Aidl data provider + sp aidlSdp = new AidlStateResidencyDataProvider(); + + auto serviceStatus = android::defaultServiceManager()->addService( + android::String16("power.stats-vendor"), aidlSdp); + if (serviceStatus != android::OK) { + ALOGE("Unable to register power.stats-vendor service %d", serviceStatus); + return 1; + } + sp ps{android::ProcessState::self()}; // Create non-HW binder threadpool + ps->startThreadPool(); + + service->addStateResidencyDataProvider(aidlSdp); + + // Configure the threadpool + configureRpcThreadpool(1, true /*callerWillJoin*/); + + status_t status = service->registerAsService(); + if (status != OK) { + ALOGE("Could not register service for power.stats HAL Iface (%d), exiting.", status); + return 1; + } + + ALOGI("power.stats service is ready"); + joinRpcThreadpool(); + + // In normal operation, we don't expect the thread pool to exit + ALOGE("power.stats service is shutting down"); + return 1; +}