summaryrefslogtreecommitdiff
path: root/power-libperfmgr
diff options
context:
space:
mode:
authorWei Wang <wvw@google.com>2020-03-06 16:49:16 -0800
committerWei Wang <wvw@google.com>2020-03-12 23:55:26 -0700
commit0338a0e0ea84e8bda9289ea413bb0068b277a9c4 (patch)
tree36c4fbfd0af05f94eb7e7dfbec45cae7d9fac3a8 /power-libperfmgr
parented79fefd066e76e8a5d646989863122a3477d202 (diff)
downloadpixel-0338a0e0ea84e8bda9289ea413bb0068b277a9c4.tar.gz
Add power hal aidl implementation
Bug: 147840817 Test: boot and check power hint Change-Id: I2a78f0428acd1110f2004db94f3feb6eaf2090b7
Diffstat (limited to 'power-libperfmgr')
-rw-r--r--power-libperfmgr/Android.bp22
-rw-r--r--power-libperfmgr/aidl/Power.cpp263
-rw-r--r--power-libperfmgr/aidl/Power.h60
-rw-r--r--power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc17
-rw-r--r--power-libperfmgr/aidl/android.hardware.power-service.pixel.xml6
-rw-r--r--power-libperfmgr/aidl/service.cpp40
6 files changed, 408 insertions, 0 deletions
diff --git a/power-libperfmgr/Android.bp b/power-libperfmgr/Android.bp
index 4b877736..fd5dee0e 100644
--- a/power-libperfmgr/Android.bp
+++ b/power-libperfmgr/Android.bp
@@ -60,3 +60,25 @@ cc_binary {
],
proprietary: true,
}
+
+cc_binary {
+ name: "android.hardware.power-service.pixel-libperfmgr",
+ relative_install_path: "hw",
+ init_rc: ["aidl/android.hardware.power-service.pixel-libperfmgr.rc"],
+ vintf_fragments: ["aidl/android.hardware.power-service.pixel.xml"],
+ vendor: true,
+ shared_libs: [
+ "android.hardware.power-ndk_platform",
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libbinder_ndk",
+ "libdisppower-pixel",
+ "libperfmgr",
+ ],
+ srcs: [
+ "aidl/service.cpp",
+ "aidl/Power.cpp",
+ ],
+}
diff --git a/power-libperfmgr/aidl/Power.cpp b/power-libperfmgr/aidl/Power.cpp
new file mode 100644
index 00000000..889b071c
--- /dev/null
+++ b/power-libperfmgr/aidl/Power.cpp
@@ -0,0 +1,263 @@
+/*
+ * 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-libperfmgr"
+
+#include "Power.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>
+
+#include "disp-power/display-helper.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace impl {
+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),
+ 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();
+
+ 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(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();
+}
+
+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) {
+ case Mode::LOW_POWER:
+ if (enabled) {
+ // Device in battery saver mode, enable display low power mode
+ set_display_lpm(true);
+ } else {
+ // Device exiting battery saver mode, disable display low power mode
+ set_display_lpm(false);
+ }
+ break;
+ case Mode::SUSTAINED_PERFORMANCE:
+ if (enabled && !mSustainedPerfModeOn) {
+ if (!mVRModeOn) { // Sustained mode only.
+ mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+ } else { // Sustained + VR mode.
+ mHintManager->EndHint("VR");
+ mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+ }
+ mSustainedPerfModeOn = true;
+ } else if (!enabled && mSustainedPerfModeOn) {
+ mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
+ mHintManager->EndHint("SUSTAINED_PERFORMANCE");
+ if (mVRModeOn) { // Switch back to VR Mode.
+ mHintManager->DoHint("VR");
+ }
+ mSustainedPerfModeOn = false;
+ }
+ break;
+ case Mode::VR:
+ if (enabled && !mVRModeOn) {
+ if (!mSustainedPerfModeOn) { // VR mode only.
+ mHintManager->DoHint("VR");
+ } else { // Sustained + VR mode.
+ mHintManager->EndHint("SUSTAINED_PERFORMANCE");
+ mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+ }
+ mVRModeOn = true;
+ } else if (!enabled && mVRModeOn) {
+ mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
+ mHintManager->EndHint("VR");
+ if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
+ mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+ }
+ mVRModeOn = false;
+ }
+ break;
+ case Mode::LAUNCH:
+ if (mVRModeOn || mSustainedPerfModeOn) {
+ break;
+ }
+ [[fallthrough]];
+ case Mode::DOUBLE_TAP_TO_WAKE:
+ [[fallthrough]];
+ case Mode::FIXED_PERFORMANCE:
+ [[fallthrough]];
+ case Mode::EXPENSIVE_RENDERING:
+ [[fallthrough]];
+ case Mode::INTERACTIVE:
+ [[fallthrough]];
+ case Mode::DEVICE_IDLE:
+ [[fallthrough]];
+ case Mode::DISPLAY_INACTIVE:
+ [[fallthrough]];
+ case Mode::AUDIO_STREAMING_LOW_LATENCY:
+ [[fallthrough]];
+ case Mode::CAMERA_STREAMING_SECURE:
+ [[fallthrough]];
+ case Mode::CAMERA_STREAMING_LOW:
+ [[fallthrough]];
+ case Mode::CAMERA_STREAMING_MID:
+ [[fallthrough]];
+ case Mode::CAMERA_STREAMING_HIGH:
+ [[fallthrough]];
+ default:
+ if (enabled) {
+ mHintManager->DoHint(toString(type));
+ } else {
+ mHintManager->EndHint(toString(type));
+ }
+ break;
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
+ bool supported = mHintManager->IsHintSupported(toString(type));
+ LOG(INFO) << "Power mode " << toString(type) << " isModeSupported: " << supported;
+ *_aidl_return = supported;
+ return ndk::ScopedAStatus::ok();
+}
+
+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) {
+ case Boost::INTERACTION:
+ case Boost::DISPLAY_UPDATE_IMMINENT:
+ case Boost::ML_ACC:
+ case Boost::AUDIO_LAUNCH:
+ case Boost::CAMERA_LAUNCH:
+ case Boost::CAMERA_SHOT:
+ [[fallthrough]];
+ default:
+ if (durationMs > 0) {
+ mHintManager->DoHint(toString(type), std::chrono::milliseconds(durationMs));
+ } else if (durationMs == 0) {
+ mHintManager->DoHint(toString(type));
+ } else {
+ mHintManager->EndHint(toString(type));
+ }
+ break;
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) {
+ bool supported = mHintManager->IsHintSupported(toString(type));
+ LOG(INFO) << "Power mode " << toString(type) << " isBoostSupported: " << supported;
+ *_aidl_return = supported;
+ return ndk::ScopedAStatus::ok();
+}
+
+constexpr const char *boolToString(bool b) {
+ return b ? "true" : "false";
+}
+
+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);
+ }
+ return STATUS_OK;
+}
+
+} // namespace pixel
+} // namespace impl
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/power-libperfmgr/aidl/Power.h b/power-libperfmgr/aidl/Power.h
new file mode 100644
index 00000000..460ca94d
--- /dev/null
+++ b/power-libperfmgr/aidl/Power.h
@@ -0,0 +1,60 @@
+/*
+ * 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/power/BnPower.h>
+#include <perfmgr/HintManager.h>
+
+#include "disp-power/InteractionHandler.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace impl {
+namespace pixel {
+
+using ::InteractionHandler;
+using ::android::perfmgr::HintManager;
+
+class Power : public BnPower {
+ public:
+ Power();
+ 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;
+ ndk::ScopedAStatus isBoostSupported(Boost type, bool *_aidl_return) override;
+ binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
+
+ private:
+ std::shared_ptr<HintManager> mHintManager;
+ std::unique_ptr<InteractionHandler> mInteractionHandler;
+ std::atomic<bool> mVRModeOn;
+ std::atomic<bool> mSustainedPerfModeOn;
+ std::atomic<bool> mReady;
+};
+
+} // namespace pixel
+} // namespace impl
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc b/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc
new file mode 100644
index 00000000..6f9ae7e4
--- /dev/null
+++ b/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc
@@ -0,0 +1,17 @@
+service vendor.power-hal-aidl /vendor/bin/hw/android.hardware.power-service.pixel-libperfmgr
+ class hal
+ user root
+ group system
+ priority -20
+
+# restart powerHAL when framework died
+on property:init.svc.zygote=restarting && property:vendor.powerhal.state=*
+ setprop vendor.powerhal.state ""
+ setprop vendor.powerhal.audio ""
+ setprop vendor.powerhal.rendering ""
+ restart vendor.power-hal-aidl
+
+# restart powerHAL when audioHAL died
+on property:init.svc.vendor.audio-hal-2-0=restarting && property:vendor.powerhal.audio=AUDIO_STREAMING_LOW_LATENCY
+ setprop vendor.powerhal.audio ""
+ restart vendor.power-hal-aidl
diff --git a/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml b/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml
new file mode 100644
index 00000000..caf6ea2d
--- /dev/null
+++ b/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.power</name>
+ <fqname>IPower/default</fqname>
+ </hal>
+</manifest>
diff --git a/power-libperfmgr/aidl/service.cpp b/power-libperfmgr/aidl/service.cpp
new file mode 100644
index 00000000..add78bdf
--- /dev/null
+++ b/power-libperfmgr/aidl/service.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 LOG_TAG "android.hardware.power-service.pixel-libperfmgr"
+
+#include "Power.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::power::impl::pixel::Power;
+
+int main() {
+ LOG(INFO) << "Power HAL AIDL Service for Pixel is starting.";
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>();
+
+ 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.";
+
+ ABinderProcess_joinThreadPool();
+ LOG(ERROR) << "Power HAL AIDL Service for Pixel died.";
+ return EXIT_FAILURE; // should not reach
+}