diff --git a/Android.bp b/Android.bp index 9515b25..c028497 100644 --- a/Android.bp +++ b/Android.bp @@ -1,2 +1,5 @@ soong_namespace { + imports: [ + "hardware/google/pixel", + ], } diff --git a/BoardConfig.mk b/BoardConfig.mk index 058f8fb..5ba6d4f 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -61,6 +61,9 @@ TARGET_FS_CONFIG_GEN := $(DEVICE_PATH)/config.fs BOARD_HAVE_QCOM_FM := true BOARD_HAS_QCA_FM_SOC := "cherokee" +# HIDL +DEVICE_FRAMEWORK_MANIFEST_FILE := $(DEVICE_PATH)/framework_manifest.xml + # Partitions BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864 BOARD_RECOVERYIMAGE_PARTITION_SIZE := 67108864 diff --git a/device.mk b/device.mk index d84b120..f803e6c 100644 --- a/device.mk +++ b/device.mk @@ -103,14 +103,16 @@ PRODUCT_PRODUCT_PROPERTIES += \ # Power PRODUCT_PACKAGES += \ - android.hardware.power@1.3-service.lenovo-libperfmgr + android.hardware.power@1.3-service.lenovo-libperfmgr \ + android.hardware.power.stats@1.0-service.lenovo PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/powerhint.json:system/etc/powerhint.json # Soong namespaces PRODUCT_SOONG_NAMESPACES += \ - $(LOCAL_PATH) + $(LOCAL_PATH) \ + hardware/google/pixel # Telephony PRODUCT_PACKAGES += \ diff --git a/framework_manifest.xml b/framework_manifest.xml new file mode 100644 index 0000000..a8355d7 --- /dev/null +++ b/framework_manifest.xml @@ -0,0 +1,11 @@ + + + android.hardware.power.stats + hwbinder + 1.0 + + IPowerStats + default + + + diff --git a/powerstats/Android.bp b/powerstats/Android.bp new file mode 100644 index 0000000..b19c029 --- /dev/null +++ b/powerstats/Android.bp @@ -0,0 +1,39 @@ +// +// 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.lenovo", + relative_install_path: "hw", + init_rc: ["android.hardware.power.stats@1.0-service.lenovo.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", + ], +} diff --git a/powerstats/android.hardware.power.stats@1.0-service.lenovo.rc b/powerstats/android.hardware.power.stats@1.0-service.lenovo.rc new file mode 100644 index 0000000..be081b0 --- /dev/null +++ b/powerstats/android.hardware.power.stats@1.0-service.lenovo.rc @@ -0,0 +1,4 @@ +service vendor.power.stats-hal-1-0 /system/bin/hw/android.hardware.power.stats@1.0-service.lenovo + class hal + user system + group system diff --git a/powerstats/service.cpp b/powerstats/service.cpp new file mode 100644 index 0000000..133c9bd --- /dev/null +++ b/powerstats/service.cpp @@ -0,0 +1,155 @@ +/* + * 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 +#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::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."); + + bool isDebuggable = android::base::GetBoolProperty("ro.debuggable", false); + + 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 + std::vector socStateResidencyConfigs = { + {.name = "AOSD", + .header = "RPM Mode:aosd", + .entryCountSupported = true, + .entryCountPrefix = "count:", + .totalTimeSupported = true, + .totalTimePrefix = "actual last sleep(msec):", + .lastEntrySupported = false}, + {.name = "CXSD", + .header = "RPM Mode:cxsd", + .entryCountSupported = true, + .entryCountPrefix = "count:", + .totalTimeSupported = true, + .totalTimePrefix = "actual last sleep(msec):", + .lastEntrySupported = false}}; + + sp socSdp = + new GenericStateResidencyDataProvider("/sys/power/system_sleep/stats"); + + uint32_t socId = service->addPowerEntity("SoC", PowerEntityType::POWER_DOMAIN); + socSdp->addEntity(socId, PowerEntityConfig(socStateResidencyConfigs)); + + service->addStateResidencyDataProvider(socSdp); + + if (isDebuggable) { + // Add WLAN power entity + uint32_t wlanId = service->addPowerEntity("WLAN", PowerEntityType::SUBSYSTEM); + sp wlanSdp = + new WlanStateResidencyDataProvider(wlanId, "/d/wlan0/power_stats"); + service->addStateResidencyDataProvider(wlanSdp); + } + + // Add Power Entities that require the Aidl data provider + sp aidlSdp = new AidlStateResidencyDataProvider(); + uint32_t citadelId = service->addPowerEntity("Citadel", PowerEntityType::SUBSYSTEM); + aidlSdp->addEntity(citadelId, "Citadel", {"Last-Reset", "Active", "Deep-Sleep"}); + + 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; +}