mirror of
https://github.com/Evolution-X-Devices/device_google_wahoo
synced 2026-01-27 18:19:03 +00:00
power.stats: Port power.stats HAL to Pixel 2
Bug: 120301393 Test: run vts -m VtsHalPowerStatsV1_0Target Test: adb shell "lshal debug android.hardware.power.stats@1.0::IPowerStats/default" Change-Id: Ib46e205651e0972dd4008976209aaf7dbff4d5f8
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2016 The Android Open-Source Project
|
||||
# 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.
|
||||
@@ -197,6 +197,10 @@ PRODUCT_COPY_FILES += \
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.power@1.2-service.wahoo-libperfmgr
|
||||
|
||||
# power.stats HAL
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.power.stats@1.0-service.pixel
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/powerhint.json:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.json
|
||||
|
||||
|
||||
@@ -218,6 +218,15 @@
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.power.stats</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IPowerStats</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.radio.deprecated</name>
|
||||
<transport>hwbinder</transport>
|
||||
|
||||
38
powerstats/Android.bp
Normal file
38
powerstats/Android.bp
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// 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.pixel",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.power.stats@1.0-service.pixel.rc"],
|
||||
srcs: ["service.cpp", "EaselStateResidencyDataProvider.cpp"],
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
static_libs: [
|
||||
"libpixelpowerstats",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"libfmq",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"android.hardware.power.stats@1.0",
|
||||
],
|
||||
vendor: true,
|
||||
}
|
||||
105
powerstats/EaselStateResidencyDataProvider.cpp
Normal file
105
powerstats/EaselStateResidencyDataProvider.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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 "easelstateresidency"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <fstream>
|
||||
#include "EaselStateResidencyDataProvider.h"
|
||||
|
||||
namespace android {
|
||||
namespace device {
|
||||
namespace google {
|
||||
namespace wahoo {
|
||||
namespace powerstats {
|
||||
|
||||
const uint32_t EASEL_SYNTHETIC_SLEEP_ID = 0;
|
||||
|
||||
EaselStateResidencyDataProvider::EaselStateResidencyDataProvider(uint32_t id) :
|
||||
mPowerEntityId(id), mTotalOnSnapshotCount(0), mTotalNotOnSnapshotCount(0) {}
|
||||
|
||||
bool EaselStateResidencyDataProvider::getResults(
|
||||
std::map<uint32_t, PowerEntityStateResidencyResult> &results) {
|
||||
const std::string path = "/sys/devices/virtual/misc/mnh_sm/state";
|
||||
|
||||
enum easel_state {
|
||||
EASEL_OFF = 0,
|
||||
EASEL_ON,
|
||||
EASEL_SUSPENDED,
|
||||
NUM_EASEL_STATES
|
||||
};
|
||||
|
||||
// Since we are storing stats locally but can have multiple parallel
|
||||
// callers, locking is required to ensure stats are not corrupted.
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
|
||||
std::ifstream inFile(path, std::ifstream::in);
|
||||
if (!inFile.is_open()) {
|
||||
PLOG(ERROR) << __func__ << ":Failed to open file " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long currentState;
|
||||
if(!(inFile >> currentState) || currentState >= NUM_EASEL_STATES) {
|
||||
PLOG(ERROR) << __func__ << ":Failed to parse " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update statistics for synthetic sleep state. We combine OFF and
|
||||
// SUSPENDED to act as a composite "not on" state so the numbers will behave
|
||||
// like a real sleep state.
|
||||
if ((currentState == EASEL_OFF) || (currentState == EASEL_SUSPENDED)) {
|
||||
mTotalNotOnSnapshotCount++;
|
||||
} else {
|
||||
mTotalOnSnapshotCount++;
|
||||
}
|
||||
|
||||
// Update statistics for synthetic sleep state, where
|
||||
// totalStateEntryCount = cumulative count of Easel state0 and state2
|
||||
// (as seen by power.stats HAL)
|
||||
// totalTimeInStateMs = cumulative count of Easel state1 (as seen by
|
||||
// power.stats HAL)
|
||||
PowerEntityStateResidencyResult result = {
|
||||
.powerEntityId = mPowerEntityId,
|
||||
.stateResidencyData = {{.powerEntityStateId = EASEL_SYNTHETIC_SLEEP_ID,
|
||||
.totalStateEntryCount = mTotalOnSnapshotCount,
|
||||
.totalTimeInStateMs = mTotalNotOnSnapshotCount,
|
||||
.lastEntryTimestampMs = 0}}
|
||||
};
|
||||
|
||||
results.emplace(std::make_pair(mPowerEntityId, result));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PowerEntityStateSpace> EaselStateResidencyDataProvider::getStateSpaces() {
|
||||
return {
|
||||
{.powerEntityId = mPowerEntityId,
|
||||
.states = {
|
||||
{
|
||||
.powerEntityStateId = EASEL_SYNTHETIC_SLEEP_ID,
|
||||
.powerEntityStateName = "SyntheticSleep"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace powerstats
|
||||
} // namespace wahoo
|
||||
} // namespace google
|
||||
} // namespace device
|
||||
} // namespace android
|
||||
51
powerstats/EaselStateResidencyDataProvider.h
Normal file
51
powerstats/EaselStateResidencyDataProvider.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef DEVICE_GOOGLE_WAHOO_POWERSTATS_EASELSTATERESIDENCYDATAPROVIDER_H
|
||||
#define DEVICE_GOOGLE_WAHOO_POWERSTATS_EASELSTATERESIDENCYDATAPROVIDER_H
|
||||
|
||||
#include <pixelpowerstats/PowerStats.h>
|
||||
|
||||
using android::hardware::power::stats::V1_0::PowerEntityStateResidencyResult;
|
||||
using android::hardware::power::stats::V1_0::PowerEntityStateSpace;
|
||||
using android::hardware::google::pixel::powerstats::IStateResidencyDataProvider;
|
||||
|
||||
namespace android {
|
||||
namespace device {
|
||||
namespace google {
|
||||
namespace wahoo {
|
||||
namespace powerstats {
|
||||
|
||||
class EaselStateResidencyDataProvider : public IStateResidencyDataProvider {
|
||||
public:
|
||||
EaselStateResidencyDataProvider(uint32_t id);
|
||||
~EaselStateResidencyDataProvider() = default;
|
||||
bool getResults(std::map<uint32_t, PowerEntityStateResidencyResult> &results) override;
|
||||
std::vector<PowerEntityStateSpace> getStateSpaces() override;
|
||||
|
||||
private:
|
||||
std::mutex mLock;
|
||||
const uint32_t mPowerEntityId;
|
||||
uint64_t mTotalOnSnapshotCount;
|
||||
uint64_t mTotalNotOnSnapshotCount;
|
||||
};
|
||||
|
||||
} // namespace powerstats
|
||||
} // namespace wahoo
|
||||
} // namespace google
|
||||
} // namespace device
|
||||
} // namespace android
|
||||
|
||||
#endif // DEVICE_GOOGLE_WAHOO_POWERSTATS_EASELSTATERESIDENCYDATAPROVIDER_H
|
||||
@@ -0,0 +1,4 @@
|
||||
service vendor.power.stats-hal-1-0 /vendor/bin/hw/android.hardware.power.stats@1.0-service.pixel
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
135
powerstats/service.cpp
Normal file
135
powerstats/service.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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 <android/log.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
#include <pixelpowerstats/GenericStateResidencyDataProvider.h>
|
||||
#include <pixelpowerstats/PowerStats.h>
|
||||
#include <pixelpowerstats/WlanStateResidencyDataProvider.h>
|
||||
#include "EaselStateResidencyDataProvider.h"
|
||||
|
||||
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::GenericStateResidencyDataProvider;
|
||||
using android::hardware::google::pixel::powerstats::PowerEntityConfig;
|
||||
using android::hardware::google::pixel::powerstats::StateResidencyConfig;
|
||||
using android::hardware::google::pixel::powerstats::WlanStateResidencyDataProvider;
|
||||
|
||||
// Wahoo specific
|
||||
using android::device::google::wahoo::powerstats::EaselStateResidencyDataProvider;
|
||||
|
||||
int main(int /* argc */, char ** /* argv */) {
|
||||
ALOGI("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<uint64_t(uint64_t)> rpmConvertToMs = [](uint64_t a) { return a / RPM_CLK; };
|
||||
std::vector<StateResidencyConfig> rpmStateResidencyConfigs = {
|
||||
{.name = "XO_shutdown",
|
||||
.entryCountSupported = true,
|
||||
.entryCountPrefix = "XO Count:",
|
||||
.totalTimeSupported = true,
|
||||
.totalTimePrefix = "Accumulated XO duration:",
|
||||
.totalTimeTransform = rpmConvertToMs,
|
||||
.lastEntrySupported = false}};
|
||||
|
||||
auto rpmSdp =
|
||||
std::make_shared<GenericStateResidencyDataProvider>("/d/system_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 slpiId = service->addPowerEntity("SLPI", PowerEntityType::SUBSYSTEM);
|
||||
rpmSdp->addEntity(slpiId, PowerEntityConfig("SLPI", rpmStateResidencyConfigs));
|
||||
|
||||
service->addStateResidencyDataProvider(std::move(rpmSdp));
|
||||
|
||||
// Add SoC power entity
|
||||
std::vector<StateResidencyConfig> socStateResidencyConfigs = {
|
||||
{.name = "XO_shutdown",
|
||||
.header = "RPM Mode:vlow",
|
||||
.entryCountSupported = true,
|
||||
.entryCountPrefix = "count:",
|
||||
.totalTimeSupported = true,
|
||||
.totalTimePrefix = "actual last sleep(msec):",
|
||||
.lastEntrySupported = false},
|
||||
{.name = "VMIN",
|
||||
.header = "RPM Mode:vmin",
|
||||
.entryCountSupported = true,
|
||||
.entryCountPrefix = "count:",
|
||||
.totalTimeSupported = true,
|
||||
.totalTimePrefix = "actual last sleep(msec):",
|
||||
.lastEntrySupported = false}};
|
||||
|
||||
auto socSdp =
|
||||
std::make_shared<GenericStateResidencyDataProvider>("/d/system_stats");
|
||||
|
||||
uint32_t socId = service->addPowerEntity("SoC", PowerEntityType::POWER_DOMAIN);
|
||||
socSdp->addEntity(socId, PowerEntityConfig(socStateResidencyConfigs));
|
||||
|
||||
service->addStateResidencyDataProvider(std::move(socSdp));
|
||||
|
||||
// Add WLAN power entity
|
||||
uint32_t wlanId = service->addPowerEntity("WLAN", PowerEntityType::SUBSYSTEM);
|
||||
auto wlanSdp = std::make_shared<WlanStateResidencyDataProvider>(wlanId);
|
||||
service->addStateResidencyDataProvider(std::move(wlanSdp));
|
||||
|
||||
// Add Easel power entity
|
||||
uint32_t easelId = service->addPowerEntity("Easel", PowerEntityType::SUBSYSTEM);
|
||||
auto easelSdp = std::make_shared<EaselStateResidencyDataProvider>(easelId);
|
||||
service->addStateResidencyDataProvider(std::move(easelSdp));
|
||||
|
||||
// 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;
|
||||
}
|
||||
1
sepolicy/vendor/file_contexts
vendored
1
sepolicy/vendor/file_contexts
vendored
@@ -168,6 +168,7 @@
|
||||
/vendor/bin/oemlock-bridge u:object_r:hal_bootctl_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.usb@1\.1-service\.wahoo u:object_r:hal_usb_impl_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.power@1\.2-service\.wahoo-libperfmgr u:object_r:hal_power_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.power\.stats@1\.0-service\.pixel u:object_r:hal_power_stats_default_exec:s0
|
||||
/vendor/bin/chre u:object_r:chre_exec:s0
|
||||
/vendor/bin/time_daemon u:object_r:time_daemon_exec:s0
|
||||
/vendor/bin/imsrcsd u:object_r:hal_rcsservice_exec:s0
|
||||
|
||||
6
sepolicy/vendor/hal_power_stats_default.te
vendored
Normal file
6
sepolicy/vendor/hal_power_stats_default.te
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# power.stats HAL needs access to rpm, and wlan sysfs nodes in /d/
|
||||
r_dir_file(hal_power_stats_default, debugfs_rpm)
|
||||
r_dir_file(hal_power_stats_default, debugfs_wlan)
|
||||
|
||||
# power.stats HAL needs access to the easel sysfs node
|
||||
r_dir_file(hal_power_stats_default, sysfs_easel)
|
||||
Reference in New Issue
Block a user