hardware/google/pixel/power-libperfmgr from android-10.0.0_r39 Change-Id: I969f76219e6507627d3689b3c2dc025983bcfde4 Signed-off-by: Jesse Chan <jc@lineageos.org>tirimbino
parent
ccd5c4c52b
commit
87f97d145b
@ -0,0 +1,47 @@ |
|||||||
|
// |
||||||
|
// 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_library_headers { |
||||||
|
name: "pixel_power_headers", |
||||||
|
vendor_available: true, |
||||||
|
export_include_dirs: ["."], |
||||||
|
} |
||||||
|
|
||||||
|
cc_binary { |
||||||
|
name: "android.hardware.power@1.3-service.pixel-libperfmgr", |
||||||
|
relative_install_path: "hw", |
||||||
|
vintf_fragments: ["android.hardware.power@1.3-service.pixel.xml"], |
||||||
|
init_rc: ["android.hardware.power@1.3-service.pixel-libperfmgr.rc"], |
||||||
|
srcs: ["service.cpp", "Power.cpp", "InteractionHandler.cpp", |
||||||
|
"display-helper.cpp"], |
||||||
|
cflags: [ |
||||||
|
"-Wall", |
||||||
|
"-Werror", |
||||||
|
], |
||||||
|
shared_libs: [ |
||||||
|
"libbase", |
||||||
|
"libhidlbase", |
||||||
|
"libhidltransport", |
||||||
|
"liblog", |
||||||
|
"libutils", |
||||||
|
"libcutils", |
||||||
|
"android.hardware.power@1.0", |
||||||
|
"android.hardware.power@1.1", |
||||||
|
"android.hardware.power@1.2", |
||||||
|
"android.hardware.power@1.3", |
||||||
|
"libperfmgr", |
||||||
|
], |
||||||
|
proprietary: true, |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 POWER_LIBPERFMGR_AUDIOSTREAMING_H_ |
||||||
|
#define POWER_LIBPERFMGR_AUDIOSTREAMING_H_ |
||||||
|
|
||||||
|
enum AUDIO_STREAMING_HINT { |
||||||
|
AUDIO_STREAMING_OFF = 0, |
||||||
|
AUDIO_STREAMING_ON = 1, |
||||||
|
TPU_BOOST_OFF = 1000, |
||||||
|
TPU_BOOST_SHORT = 1001, |
||||||
|
TPU_BOOST_LONG = 1002 |
||||||
|
}; |
||||||
|
|
||||||
|
enum TPU_HINT_DURATION_MS { SHORT = 200, LONG = 2000 }; |
||||||
|
|
||||||
|
#endif // POWER_LIBPERFMGR_AUDIOSTREAMING_H_
|
@ -0,0 +1,30 @@ |
|||||||
|
/*
|
||||||
|
* 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 POWER_LIBPERFMGR_CAMERAMODE_H_ |
||||||
|
#define POWER_LIBPERFMGR_CAMERAMODE_H_ |
||||||
|
|
||||||
|
enum CameraStreamingMode { |
||||||
|
CAMERA_STREAMING_OFF = 0, |
||||||
|
CAMERA_STREAMING, |
||||||
|
CAMERA_STREAMING_1080P, |
||||||
|
CAMERA_STREAMING_60FPS, |
||||||
|
CAMERA_STREAMING_4K, |
||||||
|
CAMERA_STREAMING_SECURE, |
||||||
|
CAMERA_STREAMING_MAX |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // POWER_LIBPERFMGR_CAMERAMODE_H_
|
@ -0,0 +1,251 @@ |
|||||||
|
/*
|
||||||
|
* 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@1.3-service.pixel-libperfmgr" |
||||||
|
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) |
||||||
|
|
||||||
|
#include <fcntl.h> |
||||||
|
#include <poll.h> |
||||||
|
#include <sys/eventfd.h> |
||||||
|
#include <time.h> |
||||||
|
#include <unistd.h> |
||||||
|
#include <utils/Log.h> |
||||||
|
#include <utils/Trace.h> |
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include "InteractionHandler.h" |
||||||
|
|
||||||
|
#define MAX_LENGTH 64 |
||||||
|
|
||||||
|
#define MSINSEC 1000L |
||||||
|
#define USINMS 1000000L |
||||||
|
|
||||||
|
static const std::vector<std::string> fb_idle_patch = {"/sys/class/drm/card0/device/idle_state", |
||||||
|
"/sys/class/graphics/fb0/idle_state"}; |
||||||
|
|
||||||
|
InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const &hint_manager) |
||||||
|
: mState(INTERACTION_STATE_UNINITIALIZED), |
||||||
|
mWaitMs(100), |
||||||
|
mMinDurationMs(1400), |
||||||
|
mMaxDurationMs(5650), |
||||||
|
mDurationMs(0), |
||||||
|
mHintManager(hint_manager) {} |
||||||
|
|
||||||
|
InteractionHandler::~InteractionHandler() { |
||||||
|
Exit(); |
||||||
|
} |
||||||
|
|
||||||
|
static int fb_idle_open(void) { |
||||||
|
int fd; |
||||||
|
for (auto &path : fb_idle_patch) { |
||||||
|
fd = open(path.c_str(), O_RDONLY); |
||||||
|
if (fd >= 0) |
||||||
|
return fd; |
||||||
|
} |
||||||
|
ALOGE("Unable to open fb idle state path (%d)", errno); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
bool InteractionHandler::Init() { |
||||||
|
std::lock_guard<std::mutex> lk(mLock); |
||||||
|
|
||||||
|
if (mState != INTERACTION_STATE_UNINITIALIZED) |
||||||
|
return true; |
||||||
|
|
||||||
|
int fd = fb_idle_open(); |
||||||
|
if (fd < 0) |
||||||
|
return false; |
||||||
|
mIdleFd = fd; |
||||||
|
|
||||||
|
mEventFd = eventfd(0, EFD_NONBLOCK); |
||||||
|
if (mEventFd < 0) { |
||||||
|
ALOGE("Unable to create event fd (%d)", errno); |
||||||
|
close(mIdleFd); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
mState = INTERACTION_STATE_IDLE; |
||||||
|
mThread = std::unique_ptr<std::thread>(new std::thread(&InteractionHandler::Routine, this)); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::Exit() { |
||||||
|
std::unique_lock<std::mutex> lk(mLock); |
||||||
|
if (mState == INTERACTION_STATE_UNINITIALIZED) |
||||||
|
return; |
||||||
|
|
||||||
|
AbortWaitLocked(); |
||||||
|
mState = INTERACTION_STATE_UNINITIALIZED; |
||||||
|
lk.unlock(); |
||||||
|
|
||||||
|
mCond.notify_all(); |
||||||
|
mThread->join(); |
||||||
|
|
||||||
|
close(mEventFd); |
||||||
|
close(mIdleFd); |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::PerfLock() { |
||||||
|
ALOGV("%s: acquiring perf lock", __func__); |
||||||
|
if (!mHintManager->DoHint("INTERACTION")) { |
||||||
|
ALOGE("%s: do hint INTERACTION failed", __func__); |
||||||
|
} |
||||||
|
ATRACE_INT("interaction_lock", 1); |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::PerfRel() { |
||||||
|
ALOGV("%s: releasing perf lock", __func__); |
||||||
|
if (!mHintManager->EndHint("INTERACTION")) { |
||||||
|
ALOGE("%s: end hint INTERACTION failed", __func__); |
||||||
|
} |
||||||
|
ATRACE_INT("interaction_lock", 0); |
||||||
|
} |
||||||
|
|
||||||
|
size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start, struct timespec end) { |
||||||
|
size_t diff_in_us = 0; |
||||||
|
diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC; |
||||||
|
diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS; |
||||||
|
return diff_in_us; |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::Acquire(int32_t duration) { |
||||||
|
ATRACE_CALL(); |
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lk(mLock); |
||||||
|
if (mState == INTERACTION_STATE_UNINITIALIZED) { |
||||||
|
ALOGW("%s: called while uninitialized", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
int inputDuration = duration + 650; |
||||||
|
int finalDuration; |
||||||
|
if (inputDuration > mMaxDurationMs) |
||||||
|
finalDuration = mMaxDurationMs; |
||||||
|
else if (inputDuration > mMinDurationMs) |
||||||
|
finalDuration = inputDuration; |
||||||
|
else |
||||||
|
finalDuration = mMinDurationMs; |
||||||
|
|
||||||
|
struct timespec cur_timespec; |
||||||
|
clock_gettime(CLOCK_MONOTONIC, &cur_timespec); |
||||||
|
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) { |
||||||
|
size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec); |
||||||
|
// don't hint if previous hint's duration covers this hint's duration
|
||||||
|
if (elapsed_time <= (mDurationMs - finalDuration)) { |
||||||
|
ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__, |
||||||
|
static_cast<int>(mDurationMs), static_cast<int>(finalDuration), |
||||||
|
static_cast<long long>(elapsed_time)); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
mLastTimespec = cur_timespec; |
||||||
|
mDurationMs = finalDuration; |
||||||
|
|
||||||
|
ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration); |
||||||
|
|
||||||
|
if (mState == INTERACTION_STATE_WAITING) |
||||||
|
AbortWaitLocked(); |
||||||
|
else if (mState == INTERACTION_STATE_IDLE) |
||||||
|
PerfLock(); |
||||||
|
|
||||||
|
mState = INTERACTION_STATE_INTERACTION; |
||||||
|
mCond.notify_one(); |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::Release() { |
||||||
|
std::lock_guard<std::mutex> lk(mLock); |
||||||
|
if (mState == INTERACTION_STATE_WAITING) { |
||||||
|
ATRACE_CALL(); |
||||||
|
PerfRel(); |
||||||
|
mState = INTERACTION_STATE_IDLE; |
||||||
|
} else { |
||||||
|
// clear any wait aborts pending in event fd
|
||||||
|
uint64_t val; |
||||||
|
ssize_t ret = read(mEventFd, &val, sizeof(val)); |
||||||
|
|
||||||
|
ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret, errno); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// should be called while locked
|
||||||
|
void InteractionHandler::AbortWaitLocked() { |
||||||
|
uint64_t val = 1; |
||||||
|
ssize_t ret = write(mEventFd, &val, sizeof(val)); |
||||||
|
if (ret != sizeof(val)) |
||||||
|
ALOGW("Unable to write to event fd (%zd)", ret); |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) { |
||||||
|
char data[MAX_LENGTH]; |
||||||
|
ssize_t ret; |
||||||
|
struct pollfd pfd[2]; |
||||||
|
|
||||||
|
ATRACE_CALL(); |
||||||
|
|
||||||
|
ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms); |
||||||
|
|
||||||
|
pfd[0].fd = mEventFd; |
||||||
|
pfd[0].events = POLLIN; |
||||||
|
pfd[1].fd = mIdleFd; |
||||||
|
pfd[1].events = POLLPRI | POLLERR; |
||||||
|
|
||||||
|
ret = poll(pfd, 1, wait_ms); |
||||||
|
if (ret > 0) { |
||||||
|
ALOGV("%s: wait aborted", __func__); |
||||||
|
return; |
||||||
|
} else if (ret < 0) { |
||||||
|
ALOGE("%s: error in poll while waiting", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
ret = pread(mIdleFd, data, sizeof(data), 0); |
||||||
|
if (!ret) { |
||||||
|
ALOGE("%s: Unexpected EOF!", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (!strncmp(data, "idle", 4)) { |
||||||
|
ALOGV("%s: already idle", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
ret = poll(pfd, 2, timeout_ms); |
||||||
|
if (ret < 0) |
||||||
|
ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret); |
||||||
|
else if (ret == 0) |
||||||
|
ALOGV("%s: timed out waiting for idle", __func__); |
||||||
|
else if (pfd[0].revents) |
||||||
|
ALOGV("%s: wait for idle aborted", __func__); |
||||||
|
else if (pfd[1].revents) |
||||||
|
ALOGV("%s: idle detected", __func__); |
||||||
|
} |
||||||
|
|
||||||
|
void InteractionHandler::Routine() { |
||||||
|
std::unique_lock<std::mutex> lk(mLock, std::defer_lock); |
||||||
|
|
||||||
|
while (true) { |
||||||
|
lk.lock(); |
||||||
|
mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; }); |
||||||
|
if (mState == INTERACTION_STATE_UNINITIALIZED) |
||||||
|
return; |
||||||
|
mState = INTERACTION_STATE_WAITING; |
||||||
|
lk.unlock(); |
||||||
|
|
||||||
|
WaitForIdle(mWaitMs, mDurationMs); |
||||||
|
Release(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
/*
|
||||||
|
* 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 POWER_LIBPERFMGR_INTERACTIONHANDLER_H_ |
||||||
|
#define POWER_LIBPERFMGR_INTERACTIONHANDLER_H_ |
||||||
|
|
||||||
|
#include <condition_variable> |
||||||
|
#include <memory> |
||||||
|
#include <mutex> |
||||||
|
#include <string> |
||||||
|
#include <thread> |
||||||
|
|
||||||
|
#include <perfmgr/HintManager.h> |
||||||
|
|
||||||
|
using ::android::perfmgr::HintManager; |
||||||
|
|
||||||
|
enum interaction_state { |
||||||
|
INTERACTION_STATE_UNINITIALIZED, |
||||||
|
INTERACTION_STATE_IDLE, |
||||||
|
INTERACTION_STATE_INTERACTION, |
||||||
|
INTERACTION_STATE_WAITING, |
||||||
|
}; |
||||||
|
|
||||||
|
class InteractionHandler { |
||||||
|
public: |
||||||
|
InteractionHandler(std::shared_ptr<HintManager> const &hint_manager); |
||||||
|
~InteractionHandler(); |
||||||
|
bool Init(); |
||||||
|
void Exit(); |
||||||
|
void Acquire(int32_t duration); |
||||||
|
|
||||||
|
private: |
||||||
|
void Release(); |
||||||
|
void WaitForIdle(int32_t wait_ms, int32_t timeout_ms); |
||||||
|
void AbortWaitLocked(); |
||||||
|
void Routine(); |
||||||
|
|
||||||
|
void PerfLock(); |
||||||
|
void PerfRel(); |
||||||
|
|
||||||
|
size_t CalcTimespecDiffMs(struct timespec start, struct timespec end); |
||||||
|
|
||||||
|
enum interaction_state mState; |
||||||
|
|
||||||
|
int mIdleFd; |
||||||
|
int mEventFd; |
||||||
|
|
||||||
|
int32_t mWaitMs; |
||||||
|
int32_t mMinDurationMs; |
||||||
|
int32_t mMaxDurationMs; |
||||||
|
int32_t mDurationMs; |
||||||
|
|
||||||
|
struct timespec mLastTimespec; |
||||||
|
|
||||||
|
std::unique_ptr<std::thread> mThread; |
||||||
|
std::mutex mLock; |
||||||
|
std::condition_variable mCond; |
||||||
|
std::shared_ptr<HintManager> mHintManager; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
@ -0,0 +1,390 @@ |
|||||||
|
/*
|
||||||
|
* 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 ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) |
||||||
|
#define LOG_TAG "android.hardware.power@1.3-service.pixel-libperfmgr" |
||||||
|
|
||||||
|
#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 <mutex> |
||||||
|
|
||||||
|
#include <utils/Log.h> |
||||||
|
#include <utils/Trace.h> |
||||||
|
|
||||||
|
#include "AudioStreaming.h" |
||||||
|
#include "Power.h" |
||||||
|
#include "display-helper.h" |
||||||
|
|
||||||
|
namespace android { |
||||||
|
namespace hardware { |
||||||
|
namespace power { |
||||||
|
namespace V1_3 { |
||||||
|
namespace implementation { |
||||||
|
|
||||||
|
using ::android::hardware::hidl_vec; |
||||||
|
using ::android::hardware::Return; |
||||||
|
using ::android::hardware::Void; |
||||||
|
using ::android::hardware::power::V1_0::Feature; |
||||||
|
using ::android::hardware::power::V1_0::Status; |
||||||
|
|
||||||
|
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"; |
||||||
|
|
||||||
|
static const std::map<enum CameraStreamingMode, std::string> kCamStreamingHint = { |
||||||
|
{CAMERA_STREAMING_OFF, "CAMERA_STREAMING_OFF"}, |
||||||
|
{CAMERA_STREAMING, "CAMERA_STREAMING"}, |
||||||
|
{CAMERA_STREAMING_1080P, "CAMERA_STREAMING_1080P"}, |
||||||
|
{CAMERA_STREAMING_60FPS, "CAMERA_STREAMING_60FPS"}, |
||||||
|
{CAMERA_STREAMING_4K, "CAMERA_STREAMING_4K"}, |
||||||
|
{CAMERA_STREAMING_SECURE, "CAMERA_STREAMING_SECURE"}}; |
||||||
|
|
||||||
|
Power::Power() |
||||||
|
: mHintManager(nullptr), |
||||||
|
mInteractionHandler(nullptr), |
||||||
|
mVRModeOn(false), |
||||||
|
mSustainedPerfModeOn(false), |
||||||
|
mCameraStreamingMode(CAMERA_STREAMING_OFF), |
||||||
|
mReady(false) { |
||||||
|
mInitThread = std::thread([this]() { |
||||||
|
android::base::WaitForProperty(kPowerHalInitProp, "1"); |
||||||
|
mHintManager = HintManager::GetFromJSON(kPowerHalConfigPath); |
||||||
|
if (!mHintManager) { |
||||||
|
LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath; |
||||||
|
} |
||||||
|
mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager); |
||||||
|
mInteractionHandler->Init(); |
||||||
|
std::string state = android::base::GetProperty(kPowerHalStateProp, ""); |
||||||
|
if (state == "CAMERA_STREAMING") { |
||||||
|
ALOGI("Initialize with CAMERA_STREAMING on"); |
||||||
|
mHintManager->DoHint("CAMERA_STREAMING"); |
||||||
|
mCameraStreamingMode = CAMERA_STREAMING; |
||||||
|
} else if (state == "CAMERA_STREAMING_1080P") { |
||||||
|
ALOGI("Initialize CAMERA_STREAMING_1080P on"); |
||||||
|
mHintManager->DoHint("CAMERA_STREAMING_1080P"); |
||||||
|
mCameraStreamingMode = CAMERA_STREAMING_1080P; |
||||||
|
} else if (state == "CAMERA_STREAMING_60FPS") { |
||||||
|
ALOGI("Initialize CAMERA_STREAMING_60FPS on"); |
||||||
|
mHintManager->DoHint("CAMERA_STREAMING_60FPS"); |
||||||
|
mCameraStreamingMode = CAMERA_STREAMING_60FPS; |
||||||
|
} else if (state == "CAMERA_STREAMING_4K") { |
||||||
|
ALOGI("Initialize with CAMERA_STREAMING_4K on"); |
||||||
|
mHintManager->DoHint("CAMERA_STREAMING_4K"); |
||||||
|
mCameraStreamingMode = CAMERA_STREAMING_4K; |
||||||
|
} else if (state == "CAMERA_STREAMING_SECURE") { |
||||||
|
ALOGI("Initialize with CAMERA_STREAMING_SECURE on"); |
||||||
|
mHintManager->DoHint("CAMERA_STREAMING_SECURE"); |
||||||
|
mCameraStreamingMode = CAMERA_STREAMING_SECURE; |
||||||
|
} else if (state == "SUSTAINED_PERFORMANCE") { |
||||||
|
ALOGI("Initialize with SUSTAINED_PERFORMANCE on"); |
||||||
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE"); |
||||||
|
mSustainedPerfModeOn = true; |
||||||
|
} else if (state == "VR_MODE") { |
||||||
|
ALOGI("Initialize with VR_MODE on"); |
||||||
|
mHintManager->DoHint("VR_MODE"); |
||||||
|
mVRModeOn = true; |
||||||
|
} else if (state == "VR_SUSTAINED_PERFORMANCE") { |
||||||
|
ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR_MODE on"); |
||||||
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE"); |
||||||
|
mSustainedPerfModeOn = true; |
||||||
|
mVRModeOn = true; |
||||||
|
} else { |
||||||
|
ALOGI("Initialize PowerHAL"); |
||||||
|
} |
||||||
|
|
||||||
|
state = android::base::GetProperty(kPowerHalAudioProp, ""); |
||||||
|
if (state == "AUDIO_LOW_LATENCY") { |
||||||
|
ALOGI("Initialize with AUDIO_LOW_LATENCY on"); |
||||||
|
mHintManager->DoHint("AUDIO_LOW_LATENCY"); |
||||||
|
} |
||||||
|
|
||||||
|
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"); |
||||||
|
}); |
||||||
|
mInitThread.detach(); |
||||||
|
} |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_0::IPower follow.
|
||||||
|
Return<void> Power::setInteractive(bool /* interactive */) { |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
Return<void> Power::powerHint(PowerHint_1_0 hint, int32_t data) { |
||||||
|
if (!mReady) { |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
ATRACE_INT(android::hardware::power::V1_0::toString(hint).c_str(), data); |
||||||
|
ALOGD_IF(hint != PowerHint_1_0::INTERACTION, "%s: %d", |
||||||
|
android::hardware::power::V1_0::toString(hint).c_str(), static_cast<int>(data)); |
||||||
|
switch (hint) { |
||||||
|
case PowerHint_1_0::INTERACTION: |
||||||
|
if (mVRModeOn || mSustainedPerfModeOn) { |
||||||
|
ALOGV("%s: ignoring due to other active perf hints", __func__); |
||||||
|
} else { |
||||||
|
mInteractionHandler->Acquire(data); |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_0::SUSTAINED_PERFORMANCE: |
||||||
|
if (data && !mSustainedPerfModeOn) { |
||||||
|
if (!mVRModeOn) { // Sustained mode only.
|
||||||
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE"); |
||||||
|
} else { // Sustained + VR mode.
|
||||||
|
mHintManager->EndHint("VR_MODE"); |
||||||
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE"); |
||||||
|
} |
||||||
|
mSustainedPerfModeOn = true; |
||||||
|
} else if (!data && mSustainedPerfModeOn) { |
||||||
|
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE"); |
||||||
|
mHintManager->EndHint("SUSTAINED_PERFORMANCE"); |
||||||
|
if (mVRModeOn) { // Switch back to VR Mode.
|
||||||
|
mHintManager->DoHint("VR_MODE"); |
||||||
|
} |
||||||
|
mSustainedPerfModeOn = false; |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_0::VR_MODE: |
||||||
|
if (data && !mVRModeOn) { |
||||||
|
if (!mSustainedPerfModeOn) { // VR mode only.
|
||||||
|
mHintManager->DoHint("VR_MODE"); |
||||||
|
} else { // Sustained + VR mode.
|
||||||
|
mHintManager->EndHint("SUSTAINED_PERFORMANCE"); |
||||||
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE"); |
||||||
|
} |
||||||
|
mVRModeOn = true; |
||||||
|
} else if (!data && mVRModeOn) { |
||||||
|
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE"); |
||||||
|
mHintManager->EndHint("VR_MODE"); |
||||||
|
if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
|
||||||
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE"); |
||||||
|
} |
||||||
|
mVRModeOn = false; |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_0::LAUNCH: |
||||||
|
if (mVRModeOn || mSustainedPerfModeOn) { |
||||||
|
ALOGV("%s: ignoring due to other active perf hints", __func__); |
||||||
|
} else { |
||||||
|
if (data) { |
||||||
|
// Hint until canceled
|
||||||
|
mHintManager->DoHint("LAUNCH"); |
||||||
|
} else { |
||||||
|
mHintManager->EndHint("LAUNCH"); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_0::LOW_POWER: |
||||||
|
if (data) { |
||||||
|
// 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; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
Return<void> Power::setFeature(Feature /*feature*/, bool /*activate*/) { |
||||||
|
// Nothing to do
|
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) { |
||||||
|
LOG(ERROR) << "getPlatformLowPowerStats not supported. Use IPowerStats HAL."; |
||||||
|
_hidl_cb({}, Status::SUCCESS); |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_1::IPower follow.
|
||||||
|
Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) { |
||||||
|
LOG(ERROR) << "getSubsystemLowPowerStats not supported. Use IPowerStats HAL."; |
||||||
|
_hidl_cb({}, Status::SUCCESS); |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
Return<void> Power::powerHintAsync(PowerHint_1_0 hint, int32_t data) { |
||||||
|
// just call the normal power hint in this oneway function
|
||||||
|
return powerHint(hint, data); |
||||||
|
} |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_2::IPower follow.
|
||||||
|
Return<void> Power::powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) { |
||||||
|
if (!mReady) { |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
ATRACE_INT(android::hardware::power::V1_2::toString(hint).c_str(), data); |
||||||
|
ALOGD_IF(hint >= PowerHint_1_2::AUDIO_STREAMING, "%s: %d", |
||||||
|
android::hardware::power::V1_2::toString(hint).c_str(), static_cast<int>(data)); |
||||||
|
|
||||||
|
switch (hint) { |
||||||
|
case PowerHint_1_2::AUDIO_LOW_LATENCY: |
||||||
|
if (data) { |
||||||
|
// Hint until canceled
|
||||||
|
mHintManager->DoHint("AUDIO_LOW_LATENCY"); |
||||||
|
} else { |
||||||
|
mHintManager->EndHint("AUDIO_LOW_LATENCY"); |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_2::AUDIO_STREAMING: |
||||||
|
if (mVRModeOn || mSustainedPerfModeOn) { |
||||||
|
ALOGV("%s: ignoring due to other active perf hints", __func__); |
||||||
|
} else { |
||||||
|
if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::AUDIO_STREAMING_ON)) { |
||||||
|
mHintManager->DoHint("AUDIO_STREAMING"); |
||||||
|
} else if (data == |
||||||
|
static_cast<int32_t>(AUDIO_STREAMING_HINT::AUDIO_STREAMING_OFF)) { |
||||||
|
mHintManager->EndHint("AUDIO_STREAMING"); |
||||||
|
} else if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::TPU_BOOST_SHORT)) { |
||||||
|
mHintManager->DoHint("TPU_BOOST", |
||||||
|
std::chrono::milliseconds(TPU_HINT_DURATION_MS::SHORT)); |
||||||
|
} else if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::TPU_BOOST_LONG)) { |
||||||
|
mHintManager->DoHint("TPU_BOOST", |
||||||
|
std::chrono::milliseconds(TPU_HINT_DURATION_MS::LONG)); |
||||||
|
} else if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::TPU_BOOST_OFF)) { |
||||||
|
mHintManager->EndHint("TPU_BOOST"); |
||||||
|
} else { |
||||||
|
ALOGE("AUDIO STREAMING INVALID DATA: %d", data); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_2::CAMERA_LAUNCH: |
||||||
|
if (data > 0) { |
||||||
|
mHintManager->DoHint("CAMERA_LAUNCH"); |
||||||
|
} else if (data == 0) { |
||||||
|
mHintManager->EndHint("CAMERA_LAUNCH"); |
||||||
|
} else { |
||||||
|
ALOGE("CAMERA LAUNCH INVALID DATA: %d", data); |
||||||
|
} |
||||||
|
break; |
||||||
|
case PowerHint_1_2::CAMERA_STREAMING: { |
||||||
|
const enum CameraStreamingMode mode = static_cast<enum CameraStreamingMode>(data); |
||||||
|
if (mode < CAMERA_STREAMING_OFF || mode >= CAMERA_STREAMING_MAX) { |
||||||
|
ALOGE("CAMERA STREAMING INVALID Mode: %d", mode); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
if (mCameraStreamingMode == mode) |
||||||
|
break; |
||||||
|
|
||||||
|
// turn it off first if any previous hint.
|
||||||
|
if ((mCameraStreamingMode != CAMERA_STREAMING_OFF)) { |
||||||
|
const auto modeValue = kCamStreamingHint.at(mCameraStreamingMode); |
||||||
|
mHintManager->EndHint(modeValue); |
||||||
|
if ((mCameraStreamingMode != CAMERA_STREAMING_SECURE)) { |
||||||
|
// Boost 1s for tear down if not secure streaming use case
|
||||||
|
mHintManager->DoHint("CAMERA_LAUNCH", std::chrono::seconds(1)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (mode != CAMERA_STREAMING_OFF) { |
||||||
|
const auto hintValue = kCamStreamingHint.at(mode); |
||||||
|
mHintManager->DoHint(hintValue); |
||||||
|
} |
||||||
|
|
||||||
|
mCameraStreamingMode = mode; |
||||||
|
const auto prop = (mCameraStreamingMode == CAMERA_STREAMING_OFF) |
||||||
|
? "" |
||||||
|
: kCamStreamingHint.at(mode).c_str(); |
||||||
|
if (!android::base::SetProperty(kPowerHalStateProp, prop)) { |
||||||
|
ALOGE("%s: could set powerHAL state %s property", __func__, prop); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case PowerHint_1_2::CAMERA_SHOT: |
||||||
|
if (data > 0) { |
||||||
|
mHintManager->DoHint("CAMERA_SHOT", std::chrono::milliseconds(data)); |
||||||
|
} else if (data == 0) { |
||||||
|
mHintManager->EndHint("CAMERA_SHOT"); |
||||||
|
} else { |
||||||
|
ALOGE("CAMERA SHOT INVALID DATA: %d", data); |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
return powerHint(static_cast<PowerHint_1_0>(hint), data); |
||||||
|
} |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_3::IPower follow.
|
||||||
|
Return<void> Power::powerHintAsync_1_3(PowerHint_1_3 hint, int32_t data) { |
||||||
|
if (!mReady) { |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
if (hint == PowerHint_1_3::EXPENSIVE_RENDERING) { |
||||||
|
ATRACE_INT(android::hardware::power::V1_3::toString(hint).c_str(), data); |
||||||
|
if (mVRModeOn || mSustainedPerfModeOn) { |
||||||
|
ALOGV("%s: ignoring due to other active perf hints", __func__); |
||||||
|
} else { |
||||||
|
if (data > 0) { |
||||||
|
mHintManager->DoHint("EXPENSIVE_RENDERING"); |
||||||
|
} else { |
||||||
|
mHintManager->EndHint("EXPENSIVE_RENDERING"); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
return powerHintAsync_1_2(static_cast<PowerHint_1_2>(hint), data); |
||||||
|
} |
||||||
|
return Void(); |
||||||
|
} |
||||||
|
|
||||||
|
constexpr const char *boolToString(bool b) { |
||||||
|
return b ? "true" : "false"; |
||||||
|
} |
||||||
|
|
||||||
|
Return<void> Power::debug(const hidl_handle &handle, const hidl_vec<hidl_string> &) { |
||||||
|
if (handle != nullptr && handle->numFds >= 1 && mReady) { |
||||||
|
int fd = handle->data[0]; |
||||||
|
|
||||||
|
std::string buf(android::base::StringPrintf( |
||||||
|
"HintManager Running: %s\n" |
||||||
|
"VRMode: %s\n" |
||||||
|
"CameraStreamingMode: %s\n" |
||||||
|
"SustainedPerformanceMode: %s\n", |
||||||
|
boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn), |
||||||
|
kCamStreamingHint.at(mCameraStreamingMode).c_str(), |
||||||
|
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 Void(); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_3
|
||||||
|
} // namespace power
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
@ -0,0 +1,88 @@ |
|||||||
|
/*
|
||||||
|
* 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 POWER_LIBPERFMGR_POWER_H_ |
||||||
|
#define POWER_LIBPERFMGR_POWER_H_ |
||||||
|
|
||||||
|
#include <atomic> |
||||||
|
#include <memory> |
||||||
|
#include <thread> |
||||||
|
|
||||||
|
#include <android/hardware/power/1.3/IPower.h> |
||||||
|
#include <hidl/MQDescriptor.h> |
||||||
|
#include <hidl/Status.h> |
||||||
|
#include <perfmgr/HintManager.h> |
||||||
|
|
||||||
|
#include "CameraMode.h" |
||||||
|
#include "InteractionHandler.h" |
||||||
|
|
||||||
|
namespace android { |
||||||
|
namespace hardware { |
||||||
|
namespace power { |
||||||
|
namespace V1_3 { |
||||||
|
namespace implementation { |
||||||
|
|
||||||
|
using ::InteractionHandler; |
||||||
|
using ::android::hardware::Return; |
||||||
|
using ::android::hardware::Void; |
||||||
|
using ::android::hardware::power::V1_0::Feature; |
||||||
|
using ::android::hardware::power::V1_3::IPower; |
||||||
|
using PowerHint_1_0 = ::android::hardware::power::V1_0::PowerHint; |
||||||
|
using PowerHint_1_2 = ::android::hardware::power::V1_2::PowerHint; |
||||||
|
using PowerHint_1_3 = ::android::hardware::power::V1_3::PowerHint; |
||||||
|
using ::android::perfmgr::HintManager; |
||||||
|
|
||||||
|
class Power : public IPower { |
||||||
|
public: |
||||||
|
// Methods from ::android::hardware::power::V1_0::IPower follow.
|
||||||
|
|
||||||
|
Power(); |
||||||
|
|
||||||
|
Return<void> setInteractive(bool /* interactive */) override; |
||||||
|
Return<void> powerHint(PowerHint_1_0 hint, int32_t data) override; |
||||||
|
Return<void> setFeature(Feature feature, bool activate) override; |
||||||
|
Return<void> getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override; |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_1::IPower follow.
|
||||||
|
Return<void> getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) override; |
||||||
|
Return<void> powerHintAsync(PowerHint_1_0 hint, int32_t data) override; |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_2::IPower follow.
|
||||||
|
Return<void> powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) override; |
||||||
|
|
||||||
|
// Methods from ::android::hardware::power::V1_3::IPower follow.
|
||||||
|
Return<void> powerHintAsync_1_3(PowerHint_1_3 hint, int32_t data) override; |
||||||
|
|
||||||
|
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||||
|
Return<void> debug(const hidl_handle &fd, const hidl_vec<hidl_string> &args) override; |
||||||
|
|
||||||
|
private: |
||||||
|
std::shared_ptr<HintManager> mHintManager; |
||||||
|
std::unique_ptr<InteractionHandler> mInteractionHandler; |
||||||
|
std::atomic<bool> mVRModeOn; |
||||||
|
std::atomic<bool> mSustainedPerfModeOn; |
||||||
|
std::atomic<enum CameraStreamingMode> mCameraStreamingMode; |
||||||
|
std::atomic<bool> mReady; |
||||||
|
std::thread mInitThread; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace implementation
|
||||||
|
} // namespace V1_3
|
||||||
|
} // namespace power
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // POWER_LIBPERFMGR_POWER_H_
|
@ -0,0 +1,26 @@ |
|||||||
|
service vendor.power-hal-1-3 /vendor/bin/hw/android.hardware.power@1.3-service.pixel-libperfmgr |
||||||
|
class hal |
||||||
|
user root |
||||||
|
group system |
||||||
|
priority -20 |
||||||
|
interface android.hardware.power@1.0::IPower default |
||||||
|
interface android.hardware.power@1.1::IPower default |
||||||
|
interface android.hardware.power@1.2::IPower default |
||||||
|
interface android.hardware.power@1.3::IPower default |
||||||
|
|
||||||
|
# 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-1-3 |
||||||
|
|
||||||
|
# restart powerHAL when cameraHAL died |
||||||
|
on property:init.svc.vendor.camera-provider-2-4=restarting && property:vendor.powerhal.state=CAMERA_STREAMING |
||||||
|
setprop vendor.powerhal.state "" |
||||||
|
restart vendor.power-hal-1-3 |
||||||
|
|
||||||
|
# restart powerHAL when audioHAL died |
||||||
|
on property:init.svc.vendor.audio-hal-2-0=restarting && property:vendor.powerhal.audio=AUDIO_LOW_LATENCY |
||||||
|
setprop vendor.powerhal.audio "" |
||||||
|
restart vendor.power-hal-1-3 |
@ -0,0 +1,11 @@ |
|||||||
|
<manifest version="1.0" type="device"> |
||||||
|
<hal format="hidl"> |
||||||
|
<name>android.hardware.power</name> |
||||||
|
<transport>hwbinder</transport> |
||||||
|
<version>1.3</version> |
||||||
|
<interface> |
||||||
|
<name>IPower</name> |
||||||
|
<instance>default</instance> |
||||||
|
</interface> |
||||||
|
</hal> |
||||||
|
</manifest> |
@ -0,0 +1,74 @@ |
|||||||
|
/*
|
||||||
|
* 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_NIDEBUG 0 |
||||||
|
#define LOG_TAG "android.hardware.power@1.3-service.pixel-libperfmgr" |
||||||
|
|
||||||
|
#include <dlfcn.h> |
||||||
|
#include <errno.h> |
||||||
|
#include <fcntl.h> |
||||||
|
#include <inttypes.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
#include <sys/stat.h> |
||||||
|
#include <sys/types.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <cutils/sockets.h> |
||||||
|
#include <log/log.h> |
||||||
|
|
||||||
|
#include "display-helper.h" |
||||||
|
|
||||||
|
#define DAEMON_SOCKET "pps" |
||||||
|
|
||||||
|
static int daemon_socket = -1; |
||||||
|
|
||||||
|
static int connectPPDaemon() { |
||||||
|
// Setup socket connection, if not already done.
|
||||||
|
if (daemon_socket < 0) |
||||||
|
daemon_socket = |
||||||
|
socket_local_client(DAEMON_SOCKET, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); |
||||||
|
|
||||||
|
if (daemon_socket < 0) { |
||||||
|
ALOGE("Connecting to socket failed: %s", strerror(errno)); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int ppdComm(const char *cmd) { |
||||||
|
int ret = -1; |
||||||
|
|
||||||
|
ret = connectPPDaemon(); |
||||||
|
if (ret < 0) |
||||||
|
return ret; |
||||||
|
|
||||||
|
ret = write(daemon_socket, cmd, strlen(cmd)); |
||||||
|
if (ret < 0) { |
||||||
|
ALOGE("Failed to send data over socket, %s", strerror(errno)); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void set_display_lpm(int enable) { |
||||||
|
ALOGI("set_display_lpm state: %d", enable); |
||||||
|
if (enable) { |
||||||
|
ppdComm("foss:on"); |
||||||
|
} else { |
||||||
|
ppdComm("foss:off"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
/*
|
||||||
|
* 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 POWER_LIBPERFMGR_DISPLAY_HELPER_H_ |
||||||
|
#define POWER_LIBPERFMGR_DISPLAY_HELPER_H_ |
||||||
|
|
||||||
|
enum display_lpm_state { |
||||||
|
DISPLAY_LPM_OFF = 0, |
||||||
|
DISPLAY_LPM_ON, |
||||||
|
DISPLAY_LPM_UNKNOWN, |
||||||
|
}; |
||||||
|
|
||||||
|
void set_display_lpm(int enable); |
||||||
|
|
||||||
|
#endif // POWER_LIBPERFMGR_DISPLAY_HELPER_H_
|
@ -0,0 +1,59 @@ |
|||||||
|
/*
|
||||||
|
* 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@1.3-service.pixel-libperfmgr" |
||||||
|
|
||||||
|
#include <android/log.h> |
||||||
|
#include <hidl/HidlTransportSupport.h> |
||||||
|
|
||||||
|
#include "Power.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::V1_3::IPower; |
||||||
|
using android::hardware::power::V1_3::implementation::Power; |
||||||
|
|
||||||
|
int main(int /* argc */, char ** /* argv */) { |
||||||
|
ALOGI("Power HAL Service 1.3 for Pixel is starting."); |
||||||
|
|
||||||
|
android::sp<IPower> service = new Power(); |
||||||
|
if (service == nullptr) { |
||||||
|
ALOGE("Can not create an instance of Power HAL Iface, exiting."); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
android::hardware::setMinSchedulerPolicy(service, SCHED_NORMAL, -20); |
||||||
|
configureRpcThreadpool(1, true /*callerWillJoin*/); |
||||||
|
|
||||||
|
status_t status = service->registerAsService(); |
||||||
|
if (status != OK) { |
||||||
|
ALOGE("Could not register service for Power HAL Iface (%d), exiting.", status); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
ALOGI("Power Service is ready"); |
||||||
|
joinRpcThreadpool(); |
||||||
|
|
||||||
|
// In normal operation, we don't expect the thread pool to exit
|
||||||
|
ALOGE("Power Service is shutting down"); |
||||||
|
return 1; |
||||||
|
} |
Loading…
Reference in new issue