summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mm/Android.bp8
-rwxr-xr-xmm/init.mm.logging.sh34
-rw-r--r--mm/pixel-mm-logd.rc19
-rw-r--r--pixelstats/SysfsCollector.cpp73
-rw-r--r--pixelstats/device.mk5
-rw-r--r--pixelstats/include/pixelstats/SysfsCollector.h3
-rw-r--r--pixelstats/pixelatoms.proto11
-rw-r--r--power-libperfmgr/Android.bp2
-rw-r--r--power-libperfmgr/aidl/Power.cpp115
-rw-r--r--power-libperfmgr/aidl/Power.h3
-rw-r--r--power-libperfmgr/aidl/PowerExt.cpp89
-rw-r--r--power-libperfmgr/aidl/PowerExt.h54
-rw-r--r--power-libperfmgr/aidl/service.cpp46
-rw-r--r--thermal/thermal-helper.cpp13
-rw-r--r--thermal/utils/thermal_watcher.cpp13
-rw-r--r--thermal/utils/thermal_watcher.h4
16 files changed, 381 insertions, 111 deletions
diff --git a/mm/Android.bp b/mm/Android.bp
new file mode 100644
index 00000000..f733d7e2
--- /dev/null
+++ b/mm/Android.bp
@@ -0,0 +1,8 @@
+sh_binary {
+ name: "mm_logd",
+ src: "init.mm.logging.sh",
+ vendor: true,
+ init_rc: [
+ "pixel-mm-logd.rc",
+ ],
+}
diff --git a/mm/init.mm.logging.sh b/mm/init.mm.logging.sh
new file mode 100755
index 00000000..38c54e0c
--- /dev/null
+++ b/mm/init.mm.logging.sh
@@ -0,0 +1,34 @@
+#!/vendor/bin/sh
+
+if [ $# -eq 1 ]; then
+ interval=$1
+else
+ exit 1
+fi
+
+kcompactd_pid=`pidof -x kcompactd0`
+kswapd_pid=`pidof -x kswapd0`
+
+while true
+do
+ log_time=`date '+%m-%d-%H-%M-%S'`
+
+ log_vmstat=`cat /proc/vmstat`
+ log_kcompactd=`cat /proc/$kcompactd_pid/stat`
+ log_kswapd=`cat /proc/$kswapd_pid/stat`
+ log_stat=`cat /proc/stat`
+
+ log_line="$log_time $log_vmstat"
+ echo $log_line >> /data/vendor/mm/vmstat/log
+
+ log_line="$log_time $log_kcompactd"
+ echo $log_line >> /data/vendor/mm/kcompactd/log
+
+ log_line="$log_time $log_kswapd"
+ echo $log_line >> /data/vendor/mm/kswapd/log
+
+ log_line="$log_time $log_stat"
+ echo $log_line >> /data/vendor/mm/stat/log
+
+ sleep $interval
+done
diff --git a/mm/pixel-mm-logd.rc b/mm/pixel-mm-logd.rc
new file mode 100644
index 00000000..40bcbe41
--- /dev/null
+++ b/mm/pixel-mm-logd.rc
@@ -0,0 +1,19 @@
+on property:persist.vendor.log.mm=1
+ mkdir /data/vendor/mm 0700 root system
+ mkdir /data/vendor/mm/vmstat 0700 root system
+ mkdir /data/vendor/mm/stat 0700 root system
+ mkdir /data/vendor/mm/kswapd 0700 root system
+ mkdir /data/vendor/mm/kcompactd 0700 root system
+ start vendor.mm.logd
+
+on property:persist.vendor.log.mm=0
+ stop vendor.mm.logd
+
+on property:persist.vendor.log.mm=1 && property:persist.vendor.log.mm.interval=*
+ restart vendor.mm.logd
+
+service vendor.mm.logd /vendor/bin/mm_logd ${persist.vendor.log.mm.interval:-60}
+ class main
+ user root
+ group root system
+ disabled
diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp
index e697605a..f9ae9282 100644
--- a/pixelstats/SysfsCollector.cpp
+++ b/pixelstats/SysfsCollector.cpp
@@ -29,6 +29,7 @@
#include <utils/Timers.h>
#include <sys/timerfd.h>
+#include <mntent.h>
#include <string>
namespace android {
@@ -38,6 +39,7 @@ namespace pixel {
using android::sp;
using android::base::ReadFileToString;
+using android::base::StartsWith;
using android::frameworks::stats::V1_0::ChargeCycles;
using android::frameworks::stats::V1_0::HardwareFailed;
using android::frameworks::stats::V1_0::IStats;
@@ -50,6 +52,7 @@ using android::hardware::google::pixel::PixelAtoms::StorageUfsHealth;
using android::hardware::google::pixel::PixelAtoms::F2fsStatsInfo;
using android::hardware::google::pixel::PixelAtoms::ZramMmStat;
using android::hardware::google::pixel::PixelAtoms::ZramBdStat;
+using android::hardware::google::pixel::PixelAtoms::BootStatsInfo;
SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths)
: kSlowioReadCntPath(sysfs_paths.SlowioReadCntPath),
@@ -81,6 +84,11 @@ bool SysfsCollector::ReadFileToInt(const char *const path, int *val) {
if (!ReadFileToString(path, &file_contents)) {
ALOGE("Unable to read %s - %s", path, strerror(errno));
return false;
+ } else if (StartsWith(file_contents, "0x")) {
+ if (sscanf(file_contents.c_str(), "0x%x", val) != 1) {
+ ALOGE("Unable to convert %s to hex - %s", path, strerror(errno));
+ return false;
+ }
} else if (sscanf(file_contents.c_str(), "%d", val) != 1) {
ALOGE("Unable to convert %s to int - %s", path, strerror(errno));
return false;
@@ -333,6 +341,22 @@ void SysfsCollector::logUFSLifetime() {
}
}
+static std::string getUserDataBlock() {
+ std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
+ if (fp == nullptr) {
+ ALOGE("Error opening /proc/mounts");
+ return "";
+ }
+
+ mntent* mentry;
+ while ((mentry = getmntent(fp.get())) != nullptr) {
+ if (strcmp(mentry->mnt_dir, "/data") == 0) {
+ return std::string(basename(mentry->mnt_fsname));
+ }
+ }
+ return "";
+}
+
void SysfsCollector::logF2fsStats() {
std::string userdataBlock;
int dirty, free, cp_calls_fg, gc_calls_fg, moved_block_fg, vblocks;
@@ -343,12 +367,7 @@ void SysfsCollector::logF2fsStats() {
return;
}
- if (kUserdataBlockProp == nullptr) {
- ALOGE("Userdata block property not specified");
- return;
- }
-
- userdataBlock = android::base::GetProperty(kUserdataBlockProp, "");
+ userdataBlock = getUserDataBlock();
if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/dirty_segments"), &dirty)) {
ALOGV("Unable to read dirty segments");
@@ -515,6 +534,44 @@ void SysfsCollector::logZramStats() {
reportZramBdStat();
}
+void SysfsCollector::logBootStats() {
+ std::string userdataBlock = getUserDataBlock();
+ int mounted_time_sec = 0;
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/mounted_time_sec"), &mounted_time_sec)) {
+ ALOGV("Unable to read mounted_time_sec");
+ return;
+ }
+
+ int fsck_time_ms = android::base::GetIntProperty("ro.boottime.init.fsck.data", 0);
+ int checkpoint_time_ms = android::base::GetIntProperty("ro.boottime.init.mount.data", 0);
+
+ if (fsck_time_ms == 0 && checkpoint_time_ms == 0) {
+ ALOGV("Not yet initialized");
+ return;
+ }
+
+ // Load values array
+ std::vector<VendorAtom::Value> values(3);
+ VendorAtom::Value tmp;
+ tmp.intValue(mounted_time_sec);
+ values[BootStatsInfo::kMountedTimeSecFieldNumber - kVendorAtomOffset] = tmp;
+ tmp.intValue(fsck_time_ms / 1000);
+ values[BootStatsInfo::kFsckTimeSecFieldNumber - kVendorAtomOffset] = tmp;
+ tmp.intValue(checkpoint_time_ms / 1000);
+ values[BootStatsInfo::kCheckpointTimeSecFieldNumber - kVendorAtomOffset] = tmp;
+
+ // Send vendor atom to IStats HAL
+ VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
+ .atomId = PixelAtoms::Ids::BOOT_STATS,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
+ if (!ret.isOk()) {
+ ALOGE("Unable to report Boot stats to Stats service");
+ } else {
+ log_once_reported = true;
+ }
+}
+
void SysfsCollector::logAll() {
stats_ = IStats::tryGetService();
if (!stats_) {
@@ -522,6 +579,10 @@ void SysfsCollector::logAll() {
return;
}
+ // Collect once per service init; can be multiple due to service reinit
+ if (!log_once_reported) {
+ logBootStats();
+ }
logBatteryChargeCycles();
logCodecFailed();
logCodec1Failed();
diff --git a/pixelstats/device.mk b/pixelstats/device.mk
new file mode 100644
index 00000000..cef2e992
--- /dev/null
+++ b/pixelstats/device.mk
@@ -0,0 +1,5 @@
+# Reliability reporting
+PRODUCT_PACKAGES += \
+ pixelstats-vendor
+
+BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/pixelstats
diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h
index 7ae15927..c6cc608c 100644
--- a/pixelstats/include/pixelstats/SysfsCollector.h
+++ b/pixelstats/include/pixelstats/SysfsCollector.h
@@ -70,6 +70,7 @@ class SysfsCollector {
void logUFSLifetime();
void logF2fsStats();
void logZramStats();
+ void logBootStats();
void reportSlowIoFromFile(const char *path, const SlowIo::IoOperation &operation_s);
void reportZramMmStat();
@@ -101,6 +102,8 @@ class SysfsCollector {
// store everything in the values array at the index of the field number
// -2.
const int kVendorAtomOffset = 2;
+
+ bool log_once_reported = false;
};
} // namespace pixel
diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto
index ac2c684b..86d18f28 100644
--- a/pixelstats/pixelatoms.proto
+++ b/pixelstats/pixelatoms.proto
@@ -41,6 +41,7 @@ enum Ids {
F2FS_STATS = 105004;
ZRAM_MM_STAT = 105005;
ZRAM_BD_STAT = 105006;
+ BOOT_STATS = 105007;
// AOSP atom ID range ends at 109999
}
@@ -186,3 +187,13 @@ message ZramBdStat {
/* The number of pages written to backing device */
optional int64 bd_writes = 4;
}
+
+/* A message containing boot times */
+message BootStatsInfo {
+ /* The F2FS fsck time in secs */
+ optional int32 fsck_time_sec = 2;
+ /* The F2FS mounted time in secs */
+ optional int32 mounted_time_sec = 3;
+ /* The F2FS checkpoint=disable time in secs */
+ optional int32 checkpoint_time_sec = 4;
+}
diff --git a/power-libperfmgr/Android.bp b/power-libperfmgr/Android.bp
index fd5dee0e..f829a729 100644
--- a/power-libperfmgr/Android.bp
+++ b/power-libperfmgr/Android.bp
@@ -76,9 +76,11 @@ cc_binary {
"libbinder_ndk",
"libdisppower-pixel",
"libperfmgr",
+ "pixel-power-ext-ndk_platform",
],
srcs: [
"aidl/service.cpp",
"aidl/Power.cpp",
+ "aidl/PowerExt.cpp",
],
}
diff --git a/power-libperfmgr/aidl/Power.cpp b/power-libperfmgr/aidl/Power.cpp
index 688a49c9..8b20dde3 100644
--- a/power-libperfmgr/aidl/Power.cpp
+++ b/power-libperfmgr/aidl/Power.cpp
@@ -41,69 +41,51 @@ namespace pixel {
constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
-constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
-constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json";
-Power::Power()
- : mHintManager(nullptr),
+Power::Power(std::shared_ptr<HintManager> hm)
+ : mHintManager(hm),
mInteractionHandler(nullptr),
mVRModeOn(false),
- mSustainedPerfModeOn(false),
- mReady(false) {
- // Parse config but do not start the looper
- mHintManager = HintManager::GetFromJSON(kPowerHalConfigPath, false);
- if (!mHintManager) {
- LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
- }
-
- std::thread initThread([this]() {
- ::android::base::WaitForProperty(kPowerHalInitProp, "1");
- mHintManager->Start();
- mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
- mInteractionHandler->Init();
+ mSustainedPerfModeOn(false) {
+ mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
+ mInteractionHandler->Init();
- std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
- if (state == "SUSTAINED_PERFORMANCE") {
- ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
- mHintManager->DoHint("SUSTAINED_PERFORMANCE");
- mSustainedPerfModeOn = true;
- } else if (state == "VR") {
- ALOGI("Initialize with VR on");
- mHintManager->DoHint(state);
- mVRModeOn = true;
- } else if (state == "VR_SUSTAINED_PERFORMANCE") {
- ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR on");
- mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
- mSustainedPerfModeOn = true;
- mVRModeOn = true;
- } else {
- ALOGI("Initialize PowerHAL");
- }
+ std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
+ if (state == "SUSTAINED_PERFORMANCE") {
+ ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
+ mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+ mSustainedPerfModeOn = true;
+ } else if (state == "VR") {
+ ALOGI("Initialize with VR on");
+ mHintManager->DoHint(state);
+ mVRModeOn = true;
+ } else if (state == "VR_SUSTAINED_PERFORMANCE") {
+ ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR on");
+ mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+ mSustainedPerfModeOn = true;
+ mVRModeOn = true;
+ } else {
+ ALOGI("Initialize PowerHAL");
+ }
- state = ::android::base::GetProperty(kPowerHalAudioProp, "");
- if (state == "AUDIO_STREAMING_LOW_LATENCY") {
- ALOGI("Initialize with AUDIO_LOW_LATENCY on");
- mHintManager->DoHint(state);
- }
+ state = ::android::base::GetProperty(kPowerHalAudioProp, "");
+ if (state == "AUDIO_STREAMING_LOW_LATENCY") {
+ ALOGI("Initialize with AUDIO_LOW_LATENCY on");
+ mHintManager->DoHint(state);
+ }
- state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
- if (state == "EXPENSIVE_RENDERING") {
- ALOGI("Initialize with EXPENSIVE_RENDERING on");
- mHintManager->DoHint("EXPENSIVE_RENDERING");
- }
+ state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
+ if (state == "EXPENSIVE_RENDERING") {
+ ALOGI("Initialize with EXPENSIVE_RENDERING on");
+ mHintManager->DoHint("EXPENSIVE_RENDERING");
+ }
- // Now start to take powerhint
- mReady.store(true);
- ALOGI("PowerHAL ready to process hints");
- });
- initThread.detach();
+ // Now start to take powerhint
+ ALOGI("PowerHAL ready to process hints");
}
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
- if (!mReady) {
- return ndk::ScopedAStatus::ok();
- }
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
ATRACE_INT(toString(type).c_str(), enabled);
switch (type) {
@@ -205,9 +187,6 @@ ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
}
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
- if (!mReady) {
- return ndk::ScopedAStatus::ok();
- }
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
ATRACE_INT(toString(type).c_str(), durationMs);
switch (type) {
@@ -246,7 +225,7 @@ ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) {
bool supported = mHintManager->IsHintSupported(toString(type));
- LOG(INFO) << "Power mode " << toString(type) << " isBoostSupported: " << supported;
+ LOG(INFO) << "Power boost " << toString(type) << " isBoostSupported: " << supported;
*_aidl_return = supported;
return ndk::ScopedAStatus::ok();
}
@@ -256,20 +235,18 @@ constexpr const char *boolToString(bool b) {
}
binder_status_t Power::dump(int fd, const char **, uint32_t) {
- if (mReady) {
- std::string buf(::android::base::StringPrintf(
- "HintManager Running: %s\n"
- "VRMode: %s\n"
- "SustainedPerformanceMode: %s\n",
- boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn),
- boolToString(mSustainedPerfModeOn)));
- // Dump nodes through libperfmgr
- mHintManager->DumpToFd(fd);
- if (!::android::base::WriteStringToFd(buf, fd)) {
- PLOG(ERROR) << "Failed to dump state to fd";
- }
- fsync(fd);
+ std::string buf(::android::base::StringPrintf(
+ "HintManager Running: %s\n"
+ "VRMode: %s\n"
+ "SustainedPerformanceMode: %s\n",
+ boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn),
+ boolToString(mSustainedPerfModeOn)));
+ // Dump nodes through libperfmgr
+ mHintManager->DumpToFd(fd);
+ if (!::android::base::WriteStringToFd(buf, fd)) {
+ PLOG(ERROR) << "Failed to dump state to fd";
}
+ fsync(fd);
return STATUS_OK;
}
diff --git a/power-libperfmgr/aidl/Power.h b/power-libperfmgr/aidl/Power.h
index 460ca94d..97805836 100644
--- a/power-libperfmgr/aidl/Power.h
+++ b/power-libperfmgr/aidl/Power.h
@@ -37,7 +37,7 @@ using ::android::perfmgr::HintManager;
class Power : public BnPower {
public:
- Power();
+ Power(std::shared_ptr<HintManager> hm);
ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override;
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
@@ -49,7 +49,6 @@ class Power : public BnPower {
std::unique_ptr<InteractionHandler> mInteractionHandler;
std::atomic<bool> mVRModeOn;
std::atomic<bool> mSustainedPerfModeOn;
- std::atomic<bool> mReady;
};
} // namespace pixel
diff --git a/power-libperfmgr/aidl/PowerExt.cpp b/power-libperfmgr/aidl/PowerExt.cpp
new file mode 100644
index 00000000..00eb0953
--- /dev/null
+++ b/power-libperfmgr/aidl/PowerExt.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
+#define LOG_TAG "android.hardware.power-service.pixel.ext-libperfmgr"
+
+#include "PowerExt.h"
+
+#include <mutex>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace pixel {
+namespace extension {
+namespace power {
+namespace impl {
+
+ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) {
+ LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled;
+ ATRACE_INT(mode.c_str(), enabled);
+
+ if (enabled) {
+ mHintManager->DoHint(mode);
+ } else {
+ mHintManager->EndHint(mode);
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode, bool *_aidl_return) {
+ bool supported = mHintManager->IsHintSupported(mode);
+ LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported;
+ *_aidl_return = supported;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t durationMs) {
+ LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
+ ATRACE_INT(boost.c_str(), durationMs);
+
+ if (durationMs > 0) {
+ mHintManager->DoHint(boost, std::chrono::milliseconds(durationMs));
+ } else if (durationMs == 0) {
+ mHintManager->DoHint(boost);
+ } else {
+ mHintManager->EndHint(boost);
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string &boost, bool *_aidl_return) {
+ bool supported = mHintManager->IsHintSupported(boost);
+ LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported;
+ *_aidl_return = supported;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace impl
+} // namespace power
+} // namespace extension
+} // namespace pixel
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/power-libperfmgr/aidl/PowerExt.h b/power-libperfmgr/aidl/PowerExt.h
new file mode 100644
index 00000000..9983dc6f
--- /dev/null
+++ b/power-libperfmgr/aidl/PowerExt.h
@@ -0,0 +1,54 @@
+/*
+ * 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 <atomic>
+#include <memory>
+#include <thread>
+
+#include <aidl/android/hardware/pixel/extension/power/BnPowerExt.h>
+#include <perfmgr/HintManager.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace pixel {
+namespace extension {
+namespace power {
+namespace impl {
+
+using ::android::perfmgr::HintManager;
+
+class PowerExt : public BnPowerExt {
+ public:
+ PowerExt(std::shared_ptr<HintManager> hm) : mHintManager(hm) {}
+ ndk::ScopedAStatus setMode(const std::string &mode, bool enabled) override;
+ ndk::ScopedAStatus isModeSupported(const std::string &mode, bool *_aidl_return) override;
+ ndk::ScopedAStatus setBoost(const std::string &boost, int32_t durationMs) override;
+ ndk::ScopedAStatus isBoostSupported(const std::string &boost, bool *_aidl_return) override;
+
+ private:
+ std::shared_ptr<HintManager> mHintManager;
+};
+
+} // namespace impl
+} // namespace power
+} // namespace extension
+} // namespace pixel
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/power-libperfmgr/aidl/service.cpp b/power-libperfmgr/aidl/service.cpp
index add78bdf..eb241700 100644
--- a/power-libperfmgr/aidl/service.cpp
+++ b/power-libperfmgr/aidl/service.cpp
@@ -16,25 +16,59 @@
#define LOG_TAG "android.hardware.power-service.pixel-libperfmgr"
-#include "Power.h"
+#include <thread>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include "Power.h"
+#include "PowerExt.h"
+
+using aidl::android::hardware::pixel::extension::power::impl::PowerExt;
using aidl::android::hardware::power::impl::pixel::Power;
+using ::android::perfmgr::HintManager;
+
+constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json";
+constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
int main() {
- LOG(INFO) << "Power HAL AIDL Service for Pixel is starting.";
+ LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting.";
+
+ // Parse config but do not start the looper
+ std::shared_ptr<HintManager> hm = HintManager::GetFromJSON(kPowerHalConfigPath, false);
+ if (!hm) {
+ LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
+ }
+
+ // single thread
ABinderProcess_setThreadPoolMaxThreadCount(0);
- std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>();
+
+ // core service
+ std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>(hm);
+ ndk::SpAIBinder pwBinder = pw->asBinder();
+
+ // extension service
+ std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>(hm);
+
+ // attach the extension to the same binder we will be registering
+ CHECK(STATUS_OK == AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get()));
const std::string instance = std::string() + Power::descriptor + "/default";
binder_status_t status = AServiceManager_addService(pw->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
- LOG(INFO) << "Power HAL AIDL Service for Pixel is started.";
+ LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started.";
+
+ std::thread initThread([&]() {
+ ::android::base::WaitForProperty(kPowerHalInitProp, "1");
+ hm->Start();
+ });
+ initThread.detach();
ABinderProcess_joinThreadPool();
- LOG(ERROR) << "Power HAL AIDL Service for Pixel died.";
- return EXIT_FAILURE; // should not reach
+
+ // should not reach
+ LOG(ERROR) << "Pixel Power HAL AIDL Service with Extension just died.";
+ return EXIT_FAILURE;
}
diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp
index 732d1817..f41cb74f 100644
--- a/thermal/thermal-helper.cpp
+++ b/thermal/thermal-helper.cpp
@@ -198,17 +198,6 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb)
if (!is_initialized_) {
LOG(FATAL) << "ThermalHAL could not be initialized properly.";
}
- std::set<std::string> cdev_paths;
- std::transform(cooling_device_info_map_.cbegin(), cooling_device_info_map_.cend(),
- std::inserter(cdev_paths, cdev_paths.begin()),
- [this](std::pair<std::string, const CoolingType> const &cdev) {
- std::string path =
- cooling_devices_.getThermalFilePath(std::string_view(cdev.first));
- if (!path.empty())
- return path;
- else
- return std::string();
- });
std::set<std::string> monitored_sensors;
std::transform(sensor_info_map_.cbegin(), sensor_info_map_.cend(),
std::inserter(monitored_sensors, monitored_sensors.begin()),
@@ -219,7 +208,7 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb)
return std::string();
});
- thermal_watcher_->registerFilesToWatch(monitored_sensors, cdev_paths, initializeTrip(tz_map));
+ thermal_watcher_->registerFilesToWatch(monitored_sensors, initializeTrip(tz_map));
// Need start watching after status map initialized
is_initialized_ = thermal_watcher_->startWatchingDeviceFiles();
diff --git a/thermal/utils/thermal_watcher.cpp b/thermal/utils/thermal_watcher.cpp
index 08a7e390..31a89a05 100644
--- a/thermal/utils/thermal_watcher.cpp
+++ b/thermal/utils/thermal_watcher.cpp
@@ -36,20 +36,7 @@ namespace implementation {
using std::chrono_literals::operator""ms;
void ThermalWatcher::registerFilesToWatch(const std::set<std::string> &sensors_to_watch,
- const std::set<std::string> &cdev_to_watch,
bool uevent_monitor) {
- int flags = O_RDONLY | O_CLOEXEC | O_BINARY;
-
- for (const auto &path : cdev_to_watch) {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags)));
- if (fd == -1) {
- PLOG(ERROR) << "failed to watch: " << path;
- continue;
- }
- watch_to_file_path_map_.emplace(fd.get(), path);
- looper_->addFd(fd.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr);
- fds_.emplace_back(std::move(fd));
- }
monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end());
if (!uevent_monitor) {
is_polling_ = true;
diff --git a/thermal/utils/thermal_watcher.h b/thermal/utils/thermal_watcher.h
index be94ab09..f8cd0449 100644
--- a/thermal/utils/thermal_watcher.h
+++ b/thermal/utils/thermal_watcher.h
@@ -58,8 +58,7 @@ class ThermalWatcher : public ::android::Thread {
// Give the file watcher a list of files to start watching. This helper
// class will by default wait for modifications to the file with a looper.
// This should be called before starting watcher thread.
- void registerFilesToWatch(const std::set<std::string> &sensors_to_watch,
- const std::set<std::string> &cdev_to_watch, bool uevent_monitor);
+ void registerFilesToWatch(const std::set<std::string> &sensors_to_watch, bool uevent_monitor);
// Wake up the looper thus the worker thread, immediately. This can be called
// in any thread.
void wake();
@@ -76,7 +75,6 @@ class ThermalWatcher : public ::android::Thread {
// Maps watcher filer descriptor to watched file path.
std::unordered_map<int, std::string> watch_to_file_path_map_;
- std::vector<android::base::unique_fd> fds_;
// The callback function. Called whenever thermal uevent is seen.
// The function passed in should expect a string in the form (type).