Everyone must switch to aidl now. Change-Id: I9e812bf3f13dcdf40650c23dee3d5f33ad8fc79dtirimbino
parent
ae574f353d
commit
ec9752f6e3
@ -1,53 +0,0 @@ |
|||||||
// |
|
||||||
// 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. |
|
||||||
|
|
||||||
soong_namespace { |
|
||||||
imports: [ |
|
||||||
"hardware/google/pixel", |
|
||||||
], |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
cc_library_headers { |
|
||||||
name: "samsung_power_headers", |
|
||||||
vendor_available: true, |
|
||||||
export_include_dirs: ["."], |
|
||||||
} |
|
||||||
|
|
||||||
cc_binary { |
|
||||||
name: "android.hardware.power@1.3-service.samsung-libperfmgr", |
|
||||||
relative_install_path: "hw", |
|
||||||
vintf_fragments: ["android.hardware.power@1.3-service.samsung.xml"], |
|
||||||
init_rc: ["android.hardware.power@1.3-service.samsung-libperfmgr.rc"], |
|
||||||
srcs: ["service.cpp", "Power.cpp", "InteractionHandler.cpp"], |
|
||||||
cflags: [ |
|
||||||
"-Wall", |
|
||||||
"-Werror", |
|
||||||
], |
|
||||||
shared_libs: [ |
|
||||||
"libbase", |
|
||||||
"libhidlbase", |
|
||||||
"liblog", |
|
||||||
"libutils", |
|
||||||
"libcutils", |
|
||||||
"android.hardware.power@1.0", |
|
||||||
"android.hardware.power@1.1", |
|
||||||
"android.hardware.power@1.2", |
|
||||||
"android.hardware.power@1.3", |
|
||||||
"libperfmgr", |
|
||||||
"vendor.lineage.power@1.0", |
|
||||||
], |
|
||||||
proprietary: true, |
|
||||||
} |
|
@ -1,264 +0,0 @@ |
|||||||
/*
|
|
||||||
* 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.samsung-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; |
|
||||||
|
|
||||||
mIdleFd = fb_idle_open(); |
|
||||||
|
|
||||||
mEventFd = eventfd(0, EFD_NONBLOCK); |
|
||||||
if (mEventFd < 0) { |
|
||||||
ALOGE("Unable to create event fd (%d)", errno); |
|
||||||
if (mIdleFd >= 0) { |
|
||||||
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); |
|
||||||
if (mIdleFd >= 0) { |
|
||||||
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; |
|
||||||
} |
|
||||||
|
|
||||||
if (mIdleFd < 0) { |
|
||||||
ret = poll(pfd, 1, timeout_ms); |
|
||||||
if (ret > 0) { |
|
||||||
ALOGV("%s: wait for duration aborted", __func__); |
|
||||||
return; |
|
||||||
} else if (ret < 0) { |
|
||||||
ALOGE("%s: Error on waiting for duration (%zd)", __func__, ret); |
|
||||||
return; |
|
||||||
} |
|
||||||
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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,74 +0,0 @@ |
|||||||
/*
|
|
||||||
* 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_
|
|
@ -1,455 +0,0 @@ |
|||||||
/*
|
|
||||||
* 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.samsung-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 "Power.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; |
|
||||||
using namespace std::chrono_literals; |
|
||||||
|
|
||||||
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 kPowerHalProfileNumProp[] = "vendor.powerhal.perf_profiles"; |
|
||||||
constexpr char kPowerHalProfileProp[] = "vendor.powerhal.perf_profile"; |
|
||||||
constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json"; |
|
||||||
|
|
||||||
Power::Power() |
|
||||||
: mHintManager(nullptr), |
|
||||||
mInteractionHandler(nullptr), |
|
||||||
mVRModeOn(false), |
|
||||||
mSustainedPerfModeOn(false), |
|
||||||
mCameraStreamingMode(false), |
|
||||||
mReady(false), |
|
||||||
mDoubleTapEnabled(false), |
|
||||||
mNumPerfProfiles(0), |
|
||||||
mCurrentPerfProfile(PowerProfile::BALANCED) { |
|
||||||
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 = true; |
|
||||||
} 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"); |
|
||||||
} |
|
||||||
|
|
||||||
state = android::base::GetProperty(kPowerHalProfileProp, ""); |
|
||||||
if (state == "POWER_SAVE") { |
|
||||||
ALOGI("Initialize with POWER_SAVE profile"); |
|
||||||
setProfile(PowerProfile::POWER_SAVE); |
|
||||||
mCurrentPerfProfile = PowerProfile::POWER_SAVE; |
|
||||||
} else if (state == "BIAS_POWER_SAVE") { |
|
||||||
ALOGI("Initialize with BIAS_POWER_SAVE profile"); |
|
||||||
setProfile(PowerProfile::BIAS_POWER_SAVE); |
|
||||||
mCurrentPerfProfile = PowerProfile::BIAS_POWER_SAVE; |
|
||||||
} else if (state == "BIAS_PERFORMANCE") { |
|
||||||
ALOGI("Initialize with BIAS_PERFORMANCE profile"); |
|
||||||
setProfile(PowerProfile::BIAS_PERFORMANCE); |
|
||||||
mCurrentPerfProfile = PowerProfile::BIAS_PERFORMANCE; |
|
||||||
} else if (state == "HIGH_PERFORMANCE") { |
|
||||||
ALOGI("Initialize with HIGH_PERFORMANCE profile"); |
|
||||||
setProfile(PowerProfile::HIGH_PERFORMANCE); |
|
||||||
mCurrentPerfProfile = PowerProfile::HIGH_PERFORMANCE; |
|
||||||
} |
|
||||||
|
|
||||||
// Now start to take powerhint
|
|
||||||
mReady.store(true); |
|
||||||
ALOGI("PowerHAL ready to process hints"); |
|
||||||
|
|
||||||
// setFeature() is called before loading powerhint.json
|
|
||||||
// is finished so update dt2w state here
|
|
||||||
switchDT2W(mDoubleTapEnabled); |
|
||||||
}); |
|
||||||
mNumPerfProfiles = android::base::GetIntProperty(kPowerHalProfileNumProp, 0); |
|
||||||
mInitThread.detach(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::updateHint(const char *hint, bool enable) { |
|
||||||
if (!mReady) { |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
if (enable) { |
|
||||||
mHintManager->DoHint(hint); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint(hint); |
|
||||||
} |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::setProfile(PowerProfile profile) { |
|
||||||
if (mCurrentPerfProfile == profile) { |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
// End previous perf profile hints
|
|
||||||
switch (mCurrentPerfProfile) { |
|
||||||
case PowerProfile::POWER_SAVE: |
|
||||||
mHintManager->EndHint("PROFILE_POWER_SAVE"); |
|
||||||
break; |
|
||||||
case PowerProfile::BIAS_POWER_SAVE: |
|
||||||
mHintManager->EndHint("PROFILE_BIAS_POWER_SAVE"); |
|
||||||
break; |
|
||||||
case PowerProfile::BIAS_PERFORMANCE: |
|
||||||
mHintManager->EndHint("PROFILE_BIAS_PERFORMANCE"); |
|
||||||
break; |
|
||||||
case PowerProfile::HIGH_PERFORMANCE: |
|
||||||
mHintManager->EndHint("PROFILE_HIGH_PERFORMANCE"); |
|
||||||
break; |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
// Apply perf profile hints
|
|
||||||
switch (profile) { |
|
||||||
case PowerProfile::POWER_SAVE: |
|
||||||
mHintManager->DoHint("PROFILE_POWER_SAVE"); |
|
||||||
break; |
|
||||||
case PowerProfile::BIAS_POWER_SAVE: |
|
||||||
mHintManager->DoHint("PROFILE_BIAS_POWER_SAVE"); |
|
||||||
break; |
|
||||||
case PowerProfile::BIAS_PERFORMANCE: |
|
||||||
mHintManager->DoHint("PROFILE_BIAS_PERFORMANCE"); |
|
||||||
break; |
|
||||||
case PowerProfile::HIGH_PERFORMANCE: |
|
||||||
mHintManager->DoHint("PROFILE_HIGH_PERFORMANCE"); |
|
||||||
break; |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::switchDT2W(bool dt2w) { |
|
||||||
updateHint("DOUBLE_TAP_TO_WAKE", dt2w); |
|
||||||
std::this_thread::sleep_for(20ms); |
|
||||||
|
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
// Methods from ::android::hardware::power::V1_0::IPower follow.
|
|
||||||
Return<void> Power::setInteractive(bool interactive) { |
|
||||||
updateHint("NOT_INTERACTIVE", !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: |
|
||||||
break; |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::setFeature(Feature feature, bool activate) { |
|
||||||
switch (feature) { |
|
||||||
case Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE: |
|
||||||
mDoubleTapEnabled = activate; |
|
||||||
|
|
||||||
// this is only called when the device is booting up or
|
|
||||||
// the user changed the dt2w setting so the touchscreen
|
|
||||||
// should always be on when this is called
|
|
||||||
switchDT2W(activate); |
|
||||||
break; |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
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) { |
|
||||||
mHintManager->DoHint("AUDIO_STREAMING"); |
|
||||||
} else { |
|
||||||
mHintManager->EndHint("AUDIO_STREAMING"); |
|
||||||
} |
|
||||||
} |
|
||||||
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: { |
|
||||||
if (data > 0) { |
|
||||||
mHintManager->DoHint("CAMERA_STREAMING"); |
|
||||||
mCameraStreamingMode = true; |
|
||||||
} else { |
|
||||||
mHintManager->EndHint("CAMERA_STREAMING"); |
|
||||||
mCameraStreamingMode = false; |
|
||||||
} |
|
||||||
|
|
||||||
const auto prop = mCameraStreamingMode |
|
||||||
? "CAMERA_STREAMING" |
|
||||||
: ""; |
|
||||||
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(); |
|
||||||
} |
|
||||||
|
|
||||||
switch (static_cast<LineagePowerHint>(hint)) { |
|
||||||
case LineagePowerHint::SET_PROFILE: |
|
||||||
setProfile(static_cast<PowerProfile>(data)); |
|
||||||
mCurrentPerfProfile = static_cast<PowerProfile>(data); |
|
||||||
return Void(); |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
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(); |
|
||||||
} |
|
||||||
|
|
||||||
// Methods from ::vendor::lineage::power::V1_0::ILineagePower follow.
|
|
||||||
Return<int32_t> Power::getFeature(LineageFeature feature) { |
|
||||||
switch (feature) { |
|
||||||
case LineageFeature::SUPPORTED_PROFILES: |
|
||||||
return mNumPerfProfiles; |
|
||||||
default: |
|
||||||
return -1; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
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), |
|
||||||
boolToString(mCameraStreamingMode), |
|
||||||
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
|
|
@ -1,114 +0,0 @@ |
|||||||
/*
|
|
||||||
* 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 "InteractionHandler.h" |
|
||||||
|
|
||||||
#include <vendor/lineage/power/1.0/ILineagePower.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; |
|
||||||
|
|
||||||
using ::vendor::lineage::power::V1_0::ILineagePower; |
|
||||||
using ::vendor::lineage::power::V1_0::LineageFeature; |
|
||||||
using ::vendor::lineage::power::V1_0::LineagePowerHint; |
|
||||||
|
|
||||||
enum PowerProfile { |
|
||||||
POWER_SAVE = 0, |
|
||||||
BALANCED, |
|
||||||
HIGH_PERFORMANCE, |
|
||||||
BIAS_POWER_SAVE, |
|
||||||
BIAS_PERFORMANCE, |
|
||||||
MAX |
|
||||||
}; |
|
||||||
|
|
||||||
class Power : public IPower, public ILineagePower { |
|
||||||
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 ::vendor::lineage::power::V1_0::ILineagePower follow.
|
|
||||||
Return<int32_t> getFeature(LineageFeature feature) 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<bool> mCameraStreamingMode; |
|
||||||
std::atomic<bool> mReady; |
|
||||||
std::thread mInitThread; |
|
||||||
|
|
||||||
std::atomic<bool> mDoubleTapEnabled; |
|
||||||
|
|
||||||
int32_t mNumPerfProfiles; |
|
||||||
std::atomic<PowerProfile> mCurrentPerfProfile; |
|
||||||
|
|
||||||
Return<void> updateHint(const char *hint, bool enable); |
|
||||||
Return<void> setProfile(PowerProfile profile); |
|
||||||
Return<void> switchDT2W(bool dt2w); |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace V1_3
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
|
|
||||||
#endif // POWER_LIBPERFMGR_POWER_H_
|
|
@ -1,20 +0,0 @@ |
|||||||
service vendor.power-hal-1-3 /vendor/bin/hw/android.hardware.power@1.3-service.samsung-libperfmgr |
|
||||||
class hal |
|
||||||
user root |
|
||||||
group system radio |
|
||||||
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 |
|
||||||
|
|
||||||
# initialize powerHAL when boot is completed |
|
||||||
on property:sys.boot_completed=1 |
|
||||||
setprop vendor.powerhal.init 1 |
|
@ -1,11 +0,0 @@ |
|||||||
<manifest version="1.0" type="device"> |
|
||||||
<hal format="hidl" override="true"> |
|
||||||
<name>android.hardware.power</name> |
|
||||||
<transport>hwbinder</transport> |
|
||||||
<version>1.3</version> |
|
||||||
<interface> |
|
||||||
<name>IPower</name> |
|
||||||
<instance>default</instance> |
|
||||||
</interface> |
|
||||||
</hal> |
|
||||||
</manifest> |
|
@ -1,448 +0,0 @@ |
|||||||
{ |
|
||||||
"Nodes": [ |
|
||||||
{ |
|
||||||
"Name": "CPULittleClusterMaxFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1113600" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPULittleClusterMinFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1113600", |
|
||||||
"576000" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigClusterMaxFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"2016000", |
|
||||||
"1497600", |
|
||||||
"1401600" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigClusterMinFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1497600", |
|
||||||
"1401600", |
|
||||||
"1286400", |
|
||||||
"0" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu7/cpufreq/scaling_max_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"2016000", |
|
||||||
"1497600", |
|
||||||
"1401600" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "CPUBigPlusClusterMinFreq", |
|
||||||
"Path": "/sys/devices/system/cpu/cpu7/cpufreq/scaling_min_freq", |
|
||||||
"Values": [ |
|
||||||
"9999999", |
|
||||||
"1497600", |
|
||||||
"1401600", |
|
||||||
"1286400", |
|
||||||
"0" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "GPUMaxFreq", |
|
||||||
"Path": "/sys/class/kgsl/kgsl-3d0/devfreq/max_freq", |
|
||||||
"Values": [ |
|
||||||
"585000000", |
|
||||||
"427000000" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "GPUMinFreq", |
|
||||||
"Path": "/sys/class/kgsl/kgsl-3d0/devfreq/min_freq", |
|
||||||
"Values": [ |
|
||||||
"585000000", |
|
||||||
"427000000", |
|
||||||
"345000000", |
|
||||||
"257000000" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "TASchedtuneBoost", |
|
||||||
"Path": "/dev/stune/top-app/schedtune.boost", |
|
||||||
"Values": [ |
|
||||||
"30", |
|
||||||
"10" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PMQoSCpuDmaLatency", |
|
||||||
"Path": "/dev/cpu_dma_latency", |
|
||||||
"Values": [ |
|
||||||
"44", |
|
||||||
"100" |
|
||||||
], |
|
||||||
"HoldFd": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "TouchscreenEnable", |
|
||||||
"Path": "/sys/class/input/input3/enabled", |
|
||||||
"Values": [ |
|
||||||
"0", |
|
||||||
"1" |
|
||||||
], |
|
||||||
"ResetOnInit": true |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "DoubleTapToWakeEnable", |
|
||||||
"Path": "/sys/class/sec/tsp/cmd", |
|
||||||
"Values": [ |
|
||||||
"aot_enable,0", |
|
||||||
"aot_enable,1" |
|
||||||
], |
|
||||||
"DefaultIndex": 0, |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALMainState", |
|
||||||
"Path": "vendor.powerhal.state", |
|
||||||
"Values": [ |
|
||||||
"CAMERA_STREAMING", |
|
||||||
"SUSTAINED_PERFORMANCE", |
|
||||||
"VR_MODE", |
|
||||||
"VR_SUSTAINED_PERFORMANCE", |
|
||||||
"" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALAudioState", |
|
||||||
"Path": "vendor.powerhal.audio", |
|
||||||
"Values": [ |
|
||||||
"AUDIO_LOW_LATENCY", |
|
||||||
"" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALRenderingState", |
|
||||||
"Path": "vendor.powerhal.rendering", |
|
||||||
"Values": [ |
|
||||||
"EXPENSIVE_RENDERING", |
|
||||||
"" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"Name": "PowerHALPerfProfileState", |
|
||||||
"Path": "vendor.powerhal.perf_profile", |
|
||||||
"Values": [ |
|
||||||
"POWER_SAVE", |
|
||||||
"BIAS_POWER_SAVE", |
|
||||||
"BIAS_PERFORMANCE", |
|
||||||
"HIGH_PERFORMANCE" |
|
||||||
], |
|
||||||
"Type": "Property" |
|
||||||
} |
|
||||||
], |
|
||||||
"Actions": [ |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1286400" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1286400" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1113600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "INTERACTION", |
|
||||||
"Node": "TASchedtuneBoost", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "30" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "LAUNCH", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 5000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPULittleClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_LAUNCH", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_STREAMING", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "CAMERA_STREAMING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_STREAMING", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "2016000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_STREAMING", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "2016000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPUBigPlusClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPULittleClusterMaxFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "CPULittleClusterMinFreq", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "9999999" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "CAMERA_SHOT", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 1000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "AUDIO_STREAMING", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 2000, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "AUDIO_LOW_LATENCY", |
|
||||||
"Node": "PowerHALAudioState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "AUDIO_LOW_LATENCY" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "AUDIO_LOW_LATENCY", |
|
||||||
"Node": "PMQoSCpuDmaLatency", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "44" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "SUSTAINED_PERFORMANCE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "CPUBigClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1401600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "CPUBigPlusClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1401600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "CPULittleClusterMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "1113600" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "GPUMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "427000000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "VR_MODE", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "VR_MODE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "VR_SUSTAINED_PERFORMANCE", |
|
||||||
"Node": "PowerHALMainState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "VR_SUSTAINED_PERFORMANCE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "EXPENSIVE_RENDERING", |
|
||||||
"Node": "PowerHALRenderingState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "EXPENSIVE_RENDERING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "EXPENSIVE_RENDERING", |
|
||||||
"Node": "GPUMinFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "427000000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "EXPENSIVE_RENDERING", |
|
||||||
"Node": "GPUMaxFreq", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "585000000" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "NOT_INTERACTIVE", |
|
||||||
"Node": "TouchscreenEnable", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "0" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "DOUBLE_TAP_TO_WAKE", |
|
||||||
"Node": "DoubleTapToWakeEnable", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "aot_enable,1" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_POWER_SAVE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "POWER_SAVE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_BIAS_POWER_SAVE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "BIAS_POWER_SAVE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_BIAS_PERFORMANCE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "BIAS_PERFORMANCE" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"PowerHint": "PROFILE_HIGH_PERFORMANCE", |
|
||||||
"Node": "PowerHALPerfProfileState", |
|
||||||
"Duration": 0, |
|
||||||
"Value": "HIGH_PERFORMANCE" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
@ -1,59 +0,0 @@ |
|||||||
/*
|
|
||||||
* 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.samsung-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 Samsung 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; |
|
||||||
} |
|
@ -1,46 +0,0 @@ |
|||||||
#
|
|
||||||
# Copyright (C) 2020 The LineageOS 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
|
|
||||||
include $(CLEAR_VARS) |
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
|
||||||
Power.cpp \
|
|
||||||
service.cpp
|
|
||||||
|
|
||||||
LOCAL_C_INCLUDES := \
|
|
||||||
$(LOCAL_PATH)/include \
|
|
||||||
hardware/samsung/hidl/light/include
|
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES := \
|
|
||||||
libbase \
|
|
||||||
libbinder \
|
|
||||||
libhidlbase \
|
|
||||||
libutils \
|
|
||||||
android.hardware.power@1.0 \
|
|
||||||
vendor.lineage.power@1.0
|
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := libc++fs
|
|
||||||
|
|
||||||
LOCAL_MODULE := android.hardware.power@1.0-service.exynos
|
|
||||||
LOCAL_INIT_RC := android.hardware.power@1.0-service.exynos.rc
|
|
||||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
|
||||||
LOCAL_MODULE_TAGS := optional
|
|
||||||
LOCAL_MODULE_OWNER := samsung
|
|
||||||
LOCAL_VENDOR_MODULE := true
|
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE) |
|
@ -1,247 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The LineageOS 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.0-service.exynos" |
|
||||||
|
|
||||||
#include "Power.h" |
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <filesystem> |
|
||||||
#include <fstream> |
|
||||||
#include <iostream> |
|
||||||
#include "samsung_lights.h" |
|
||||||
#include "samsung_power.h" |
|
||||||
|
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace V1_0 { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
/*
|
|
||||||
* Write value to path and close file. |
|
||||||
*/ |
|
||||||
template <typename T> |
|
||||||
static void set(const std::string& path, const T& value) { |
|
||||||
std::ofstream file(path); |
|
||||||
file << value << std::endl; |
|
||||||
} |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
static T get(const std::string& path, const T& def) { |
|
||||||
std::ifstream file(path); |
|
||||||
T result; |
|
||||||
|
|
||||||
file >> result; |
|
||||||
return file.fail() ? def : result; |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::setInteractive(bool interactive) { |
|
||||||
if (!initialized) { |
|
||||||
initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
if (!interactive) { |
|
||||||
int32_t panel_brightness = get(PANEL_BRIGHTNESS_NODE, -1); |
|
||||||
|
|
||||||
if (panel_brightness > 0) { |
|
||||||
LOG(VERBOSE) << "Moving to non-interactive state, but screen is still on," |
|
||||||
<< "not disabling input devices"; |
|
||||||
goto out; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (!sec_touchscreen.empty()) { |
|
||||||
set(sec_touchscreen, interactive ? "1" : "0"); |
|
||||||
} |
|
||||||
|
|
||||||
if (!sec_touchkey.empty()) { |
|
||||||
if (!interactive) { |
|
||||||
int button_state = get(sec_touchkey, -1); |
|
||||||
|
|
||||||
if (button_state < 0) { |
|
||||||
LOG(ERROR) << "Failed to read touchkey state"; |
|
||||||
goto out; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* If button_state is 0, the keys have been disabled by another component |
|
||||||
* (for example lineagehw), which means we don't want them to be enabled when resuming |
|
||||||
* from suspend. |
|
||||||
*/ |
|
||||||
if (button_state == 0) { |
|
||||||
touchkeys_blocked = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (!touchkeys_blocked) { |
|
||||||
set(sec_touchkey, interactive ? "1" : "0"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
out: |
|
||||||
for (const std::string& interactivePath : cpuInteractivePaths) { |
|
||||||
set(interactivePath + "/io_is_busy", interactive ? "1" : "0"); |
|
||||||
} |
|
||||||
|
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::powerHint(PowerHint hint, int32_t data) { |
|
||||||
if (!initialized) { |
|
||||||
initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
/* Bail out if low-power mode is active */ |
|
||||||
if (current_profile == PowerProfile::POWER_SAVE && hint != PowerHint::LOW_POWER && |
|
||||||
hint != static_cast<PowerHint>(LineagePowerHint::SET_PROFILE)) { |
|
||||||
LOG(VERBOSE) << "PROFILE_POWER_SAVE active, ignoring hint " << static_cast<int32_t>(hint); |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
switch (hint) { |
|
||||||
case PowerHint::INTERACTION: |
|
||||||
case PowerHint::LAUNCH: |
|
||||||
sendBoostpulse(); |
|
||||||
break; |
|
||||||
case PowerHint::LOW_POWER: |
|
||||||
setProfile(data ? PowerProfile::POWER_SAVE : PowerProfile::BALANCED); |
|
||||||
break; |
|
||||||
default: |
|
||||||
if (hint == static_cast<PowerHint>(LineagePowerHint::SET_PROFILE)) { |
|
||||||
setProfile(static_cast<PowerProfile>(data)); |
|
||||||
} else if (hint == static_cast<PowerHint>(LineagePowerHint::CPU_BOOST)) { |
|
||||||
sendBoost(data); |
|
||||||
} else { |
|
||||||
LOG(INFO) << "Unknown power hint: " << static_cast<int32_t>(hint); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::setFeature(Feature feature __unused, bool activate __unused) { |
|
||||||
if (!initialized) { |
|
||||||
initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
#ifdef TAP_TO_WAKE_NODE |
|
||||||
if (feature == Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE) { |
|
||||||
set(TAP_TO_WAKE_NODE, activate ? "1" : "0"); |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) { |
|
||||||
_hidl_cb({}, Status::SUCCESS); |
|
||||||
return Void(); |
|
||||||
} |
|
||||||
|
|
||||||
Return<int32_t> Power::getFeature(LineageFeature feature) { |
|
||||||
switch (feature) { |
|
||||||
case LineageFeature::SUPPORTED_PROFILES: |
|
||||||
return static_cast<int32_t>(PowerProfile::MAX); |
|
||||||
default: |
|
||||||
return -1; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Power::initialize() { |
|
||||||
findInputNodes(); |
|
||||||
|
|
||||||
current_profile = PowerProfile::BALANCED; |
|
||||||
|
|
||||||
for (const std::string& interactivePath : cpuInteractivePaths) { |
|
||||||
hispeed_freqs.emplace_back(get<std::string>(interactivePath + "/hispeed_freq", "")); |
|
||||||
} |
|
||||||
|
|
||||||
for (const std::string& sysfsPath : cpuSysfsPaths) { |
|
||||||
max_freqs.emplace_back(get<std::string>(sysfsPath + "/cpufreq/scaling_max_freq", "")); |
|
||||||
} |
|
||||||
|
|
||||||
initialized = true; |
|
||||||
} |
|
||||||
|
|
||||||
void Power::findInputNodes() { |
|
||||||
std::error_code ec; |
|
||||||
for (auto& de : std::filesystem::directory_iterator("/sys/class/input/", ec)) { |
|
||||||
/* we are only interested in the input devices that we can access */ |
|
||||||
if (ec || de.path().string().find("/sys/class/input/input") == std::string::npos) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
for (auto& de2 : std::filesystem::directory_iterator(de.path(), ec)) { |
|
||||||
if (!ec && de2.path().string().find("/name") != std::string::npos) { |
|
||||||
std::string content = get<std::string>(de2.path(), ""); |
|
||||||
if (content == "sec_touchkey") { |
|
||||||
sec_touchkey = de.path().string().append("/enabled"); |
|
||||||
LOG(INFO) << "found sec_touchkey: " << sec_touchkey; |
|
||||||
} else if (content == "sec_touchscreen") { |
|
||||||
sec_touchscreen = de.path().string().append("/enabled"); |
|
||||||
LOG(INFO) << "found sec_touchscreen: " << sec_touchscreen; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Power::setProfile(PowerProfile profile) { |
|
||||||
if (current_profile == profile) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
switch (profile) { |
|
||||||
case PowerProfile::POWER_SAVE: |
|
||||||
// Limit to hispeed freq
|
|
||||||
for (int i = 0; i < cpuSysfsPaths.size(); i++) { |
|
||||||
if (hispeed_freqs.size() > i && !hispeed_freqs.at(i).empty()) { |
|
||||||
set(cpuSysfsPaths.at(i) + "/cpufreq/scaling_max_freq", hispeed_freqs.at(i)); |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
case PowerProfile::BALANCED: |
|
||||||
case PowerProfile::HIGH_PERFORMANCE: |
|
||||||
// Restore normal max freq
|
|
||||||
for (int i = 0; i < cpuSysfsPaths.size(); i++) { |
|
||||||
if (max_freqs.size() > i && !max_freqs.at(i).empty()) { |
|
||||||
set(cpuSysfsPaths.at(i) + "/cpufreq/scaling_max_freq", max_freqs.at(i)); |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
default: |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Power::sendBoostpulse() { |
|
||||||
// the boostpulse node is only valid for the LITTLE cluster
|
|
||||||
set(cpuInteractivePaths.front() + "/boostpulse", "1"); |
|
||||||
} |
|
||||||
|
|
||||||
void Power::sendBoost(int duration_us) { |
|
||||||
set(cpuInteractivePaths.front() + "/boost", "1"); |
|
||||||
|
|
||||||
usleep(duration_us); |
|
||||||
|
|
||||||
set(cpuInteractivePaths.front() + "/boost", "0"); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace V1_0
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
@ -1,82 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The LineageOS 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 ANDROID_HARDWARE_POWER_V1_0_POWER_H |
|
||||||
#define ANDROID_HARDWARE_POWER_V1_0_POWER_H |
|
||||||
|
|
||||||
#include <android/hardware/power/1.0/IPower.h> |
|
||||||
#include <hidl/MQDescriptor.h> |
|
||||||
#include <hidl/Status.h> |
|
||||||
#include <vendor/lineage/power/1.0/ILineagePower.h> |
|
||||||
|
|
||||||
namespace android { |
|
||||||
namespace hardware { |
|
||||||
namespace power { |
|
||||||
namespace V1_0 { |
|
||||||
namespace implementation { |
|
||||||
|
|
||||||
using ::android::sp; |
|
||||||
using ::android::hardware::hidl_array; |
|
||||||
using ::android::hardware::hidl_memory; |
|
||||||
using ::android::hardware::hidl_string; |
|
||||||
using ::android::hardware::hidl_vec; |
|
||||||
using ::android::hardware::Return; |
|
||||||
using ::android::hardware::Void; |
|
||||||
|
|
||||||
using ::vendor::lineage::power::V1_0::ILineagePower; |
|
||||||
using ::vendor::lineage::power::V1_0::LineageFeature; |
|
||||||
using ::vendor::lineage::power::V1_0::LineagePowerHint; |
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
enum PowerProfile { |
|
||||||
POWER_SAVE = 0, |
|
||||||
BALANCED, |
|
||||||
HIGH_PERFORMANCE, |
|
||||||
MAX |
|
||||||
}; |
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
struct Power : public IPower, public ILineagePower { |
|
||||||
Return<void> setInteractive(bool interactive) override; |
|
||||||
Return<void> powerHint(PowerHint hint, int32_t data) override; |
|
||||||
Return<void> setFeature(Feature feature, bool activate) override; |
|
||||||
Return<void> getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override; |
|
||||||
|
|
||||||
Return<int32_t> getFeature(LineageFeature feature) override; |
|
||||||
|
|
||||||
private: |
|
||||||
void initialize(); |
|
||||||
void findInputNodes(); |
|
||||||
void setProfile(PowerProfile profile); |
|
||||||
void sendBoostpulse(); |
|
||||||
void sendBoost(int duration_us); |
|
||||||
|
|
||||||
bool initialized; |
|
||||||
bool touchkeys_blocked; |
|
||||||
std::string sec_touchkey; |
|
||||||
std::string sec_touchscreen; |
|
||||||
PowerProfile current_profile; |
|
||||||
std::vector<std::string> hispeed_freqs; |
|
||||||
std::vector<std::string> max_freqs; |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace implementation
|
|
||||||
} // namespace V1_0
|
|
||||||
} // namespace power
|
|
||||||
} // namespace hardware
|
|
||||||
} // namespace android
|
|
||||||
|
|
||||||
#endif // ANDROID_HARDWARE_POWER_V1_0_POWER_H
|
|
@ -1,4 +0,0 @@ |
|||||||
service vendor.power-hal-1-0 /vendor/bin/hw/android.hardware.power@1.0-service.exynos |
|
||||||
class hal |
|
||||||
user system |
|
||||||
group system |
|
@ -1,42 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2016 The CyanogenMod Project |
|
||||||
* Copyright (C) 2020 The LineageOS 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 SAMSUNG_POWER_H |
|
||||||
#define SAMSUNG_POWER_H |
|
||||||
|
|
||||||
/*
|
|
||||||
* Board specific nodes |
|
||||||
* |
|
||||||
* If your kernel exposes these controls in another place, you can either |
|
||||||
* symlink to the locations given here, or override this header in your |
|
||||||
* device tree. |
|
||||||
*/ |
|
||||||
|
|
||||||
static const std::vector<std::string> cpuSysfsPaths = { |
|
||||||
"/sys/devices/system/cpu/cpu0", |
|
||||||
"/sys/devices/system/cpu/cpu4" |
|
||||||
}; |
|
||||||
|
|
||||||
static const std::vector<std::string> cpuInteractivePaths = { |
|
||||||
"/sys/devices/system/cpu/cpu0/cpufreq/interactive", |
|
||||||
"/sys/devices/system/cpu/cpu4/cpufreq/interactive" |
|
||||||
}; |
|
||||||
|
|
||||||
/* double tap to wake node */ |
|
||||||
//#define TAP_TO_WAKE_NODE "/sys/class/sec/tsp/dt2w_enable"
|
|
||||||
|
|
||||||
#endif // SAMSUNG_POWER_H
|
|
@ -1,60 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The LineageOS 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.0-service.exynos" |
|
||||||
|
|
||||||
#include <android-base/logging.h> |
|
||||||
#include <hidl/HidlTransportSupport.h> |
|
||||||
#include <utils/Errors.h> |
|
||||||
|
|
||||||
#include "Power.h" |
|
||||||
|
|
||||||
using android::hardware::configureRpcThreadpool; |
|
||||||
using android::hardware::joinRpcThreadpool; |
|
||||||
|
|
||||||
using android::hardware::power::V1_0::IPower; |
|
||||||
using android::hardware::power::V1_0::implementation::Power; |
|
||||||
|
|
||||||
using android::OK; |
|
||||||
using android::sp; |
|
||||||
using android::status_t; |
|
||||||
|
|
||||||
int main() { |
|
||||||
sp<Power> power = new Power(); |
|
||||||
status_t status = 0; |
|
||||||
|
|
||||||
configureRpcThreadpool(1, true); |
|
||||||
|
|
||||||
status = power->IPower::registerAsService(); |
|
||||||
if (status != OK) { |
|
||||||
LOG(ERROR) << "Could not register service (IPower) for Power HAL"; |
|
||||||
goto shutdown; |
|
||||||
} |
|
||||||
|
|
||||||
status = power->ILineagePower::registerAsService(); |
|
||||||
if (status != OK) { |
|
||||||
LOG(ERROR) << "Could not register service (ILineagePower) for Power HAL"; |
|
||||||
goto shutdown; |
|
||||||
} |
|
||||||
|
|
||||||
LOG(INFO) << "Power HAL service is Ready."; |
|
||||||
joinRpcThreadpool(); |
|
||||||
|
|
||||||
shutdown: |
|
||||||
// In normal operation, we don't expect the thread pool to shutdown
|
|
||||||
LOG(ERROR) << "Power HAL failed to join thread pool."; |
|
||||||
return 1; |
|
||||||
} |
|
Loading…
Reference in new issue