sdm845-common: Migrate to Xiaomi power AIDL HAL

Change-Id: I42170d51a517170b58d532addd9c38496e43457c
This commit is contained in:
Bruno Martins 2021-02-16 13:44:18 +00:00
parent 0c18729c97
commit 8d92bd277b
13 changed files with 10 additions and 1385 deletions

View File

@ -1,5 +1,7 @@
soong_namespace {
imports: [
"hardware/google/interfaces",
"hardware/google/pixel",
"hardware/xiaomi",
],
}

View File

@ -1,39 +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.
cc_binary {
name: "android.hardware.power@1.3-service.xiaomi_sdm845-libperfmgr",
relative_install_path: "hw",
init_rc: ["android.hardware.power@1.3-service.xiaomi_sdm845-libperfmgr.rc"],
srcs: ["service.cpp", "Power.cpp", "InteractionHandler.cpp", "power-helper.c"],
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,
}

View File

@ -1,244 +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_NDEBUG 0
#define LOG_TAG "android.hardware.power@1.3-service.xiaomi_sdm845-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 "InteractionHandler.h"
#define FB_IDLE_PATH "/sys/class/drm/card0/device/idle_state"
#define MAX_LENGTH 64
#define MSINSEC 1000L
#define USINMS 1000000L
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();
}
bool InteractionHandler::Init() {
std::lock_guard<std::mutex> lk(mLock);
if (mState != INTERACTION_STATE_UNINITIALIZED)
return true;
mIdleFd = open(FB_IDLE_PATH, O_RDONLY);
if (mIdleFd < 0) {
ALOGE("Unable to open idle state path (%d)", errno);
return false;
}
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);
}
long long InteractionHandler::CalcTimespecDiffMs(struct timespec start,
struct timespec end) {
long long 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) {
long long 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__, mDurationMs, finalDuration, 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();
}
}

View File

@ -1,71 +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 INTERACTIONHANDLER_H
#define INTERACTIONHANDLER_H
#include <condition_variable>
#include <mutex>
#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,
};
struct InteractionHandler {
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();
long long 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 //INTERACTIONHANDLER_H

View File

@ -1,489 +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.xiaomi_sdm845-libperfmgr"
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include "Power.h"
#include "power-helper.h"
/* RPM runs at 19.2Mhz. Divide by 19200 for msec */
#define RPM_CLK 19200
extern struct stats_section master_sections[];
namespace android {
namespace hardware {
namespace power {
namespace V1_3 {
namespace implementation {
using ::android::hardware::power::V1_0::Feature;
using ::android::hardware::power::V1_0::PowerStatePlatformSleepState;
using ::android::hardware::power::V1_0::Status;
using ::android::hardware::power::V1_1::PowerStateSubsystem;
using ::android::hardware::power::V1_1::PowerStateSubsystemSleepState;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
Power::Power() :
mHintManager(nullptr),
mInteractionHandler(nullptr),
mVRModeOn(false),
mSustainedPerfModeOn(false),
mCameraStreamingModeOn(false),
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");
mCameraStreamingModeOn = 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");
}
// Now start to take powerhint
mReady.store(true);
});
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 (!isSupportedGovernor() || !mReady) {
return Void();
}
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) {
ALOGD("SUSTAINED_PERFORMANCE ON");
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) {
ALOGD("SUSTAINED_PERFORMANCE OFF");
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) {
ALOGD("VR_MODE ON");
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) {
ALOGD("VR_MODE OFF");
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:
ATRACE_BEGIN("launch");
if (mVRModeOn || mSustainedPerfModeOn) {
ALOGV("%s: ignoring due to other active perf hints", __func__);
} else {
if (data) {
// Hint until canceled
ATRACE_INT("launch_lock", 1);
mHintManager->DoHint("LAUNCH");
ALOGD("LAUNCH ON");
} else {
ATRACE_INT("launch_lock", 0);
mHintManager->EndHint("LAUNCH");
ALOGD("LAUNCH OFF");
}
}
ATRACE_END();
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) {
hidl_vec<PowerStatePlatformSleepState> states;
uint64_t stats[SYSTEM_SLEEP_STATE_COUNT * SYSTEM_STATE_STATS_COUNT] = {0};
uint64_t *state_stats;
struct PowerStatePlatformSleepState *state;
states.resize(SYSTEM_SLEEP_STATE_COUNT);
if (extract_system_stats(stats, ARRAY_SIZE(stats)) != 0) {
states.resize(0);
goto done;
}
/* Update statistics for AOSD */
state = &states[SYSTEM_STATE_AOSD];
state->name = "AOSD";
state_stats = &stats[SYSTEM_STATE_AOSD * SYSTEM_STATE_STATS_COUNT];
state->residencyInMsecSinceBoot = state_stats[ACCUMULATED_TIME_MS];
state->totalTransitions = state_stats[TOTAL_COUNT];
state->supportedOnlyInSuspend = false;
state->voters.resize(0);
/* Update statistics for CXSD */
state = &states[SYSTEM_STATE_CXSD];
state->name = "CXSD";
state_stats = &stats[SYSTEM_STATE_CXSD * SYSTEM_STATE_STATS_COUNT];
state->residencyInMsecSinceBoot = state_stats[ACCUMULATED_TIME_MS];
state->totalTransitions = state_stats[TOTAL_COUNT];
state->supportedOnlyInSuspend = false;
state->voters.resize(0);
done:
_hidl_cb(states, Status::SUCCESS);
return Void();
}
static int get_master_low_power_stats(hidl_vec<PowerStateSubsystem> *subsystems) {
uint64_t all_stats[MASTER_COUNT * MASTER_STATS_COUNT] = {0};
uint64_t *section_stats;
struct PowerStateSubsystem *subsystem;
struct PowerStateSubsystemSleepState *state;
if (extract_master_stats(all_stats, ARRAY_SIZE(all_stats)) != 0) {
for (size_t i = 0; i < MASTER_COUNT; i++) {
(*subsystems)[i].name = master_sections[i].label;
(*subsystems)[i].states.resize(0);
}
return -1;
}
for (size_t i = 0; i < MASTER_COUNT; i++) {
subsystem = &(*subsystems)[i];
subsystem->name = master_sections[i].label;
subsystem->states.resize(MASTER_SLEEP_STATE_COUNT);
state = &(subsystem->states[MASTER_SLEEP]);
section_stats = &all_stats[i * MASTER_STATS_COUNT];
state->name = "Sleep";
state->totalTransitions = section_stats[SLEEP_ENTER_COUNT];
state->residencyInMsecSinceBoot = section_stats[SLEEP_CUMULATIVE_DURATION_MS] / RPM_CLK;
state->lastEntryTimestampMs = section_stats[SLEEP_LAST_ENTER_TSTAMP_MS] / RPM_CLK;
state->supportedOnlyInSuspend = false;
}
return 0;
}
static int get_wlan_low_power_stats(struct PowerStateSubsystem *subsystem) {
uint64_t stats[WLAN_STATS_COUNT] = {0};
struct PowerStateSubsystemSleepState *state;
subsystem->name = "wlan";
if (extract_wlan_stats(stats, ARRAY_SIZE(stats)) != 0) {
subsystem->states.resize(0);
return -1;
}
subsystem->states.resize(WLAN_SLEEP_STATE_COUNT);
/* Update statistics for Active State */
state = &subsystem->states[WLAN_STATE_ACTIVE];
state->name = "Active";
state->residencyInMsecSinceBoot = stats[CUMULATIVE_TOTAL_ON_TIME_MS];
state->totalTransitions = stats[DEEP_SLEEP_ENTER_COUNTER];
state->lastEntryTimestampMs = 0; //FIXME need a new value from Qcom
state->supportedOnlyInSuspend = false;
/* Update statistics for Deep-Sleep state */
state = &subsystem->states[WLAN_STATE_DEEP_SLEEP];
state->name = "Deep-Sleep";
state->residencyInMsecSinceBoot = stats[CUMULATIVE_SLEEP_TIME_MS];
state->totalTransitions = stats[DEEP_SLEEP_ENTER_COUNTER];
state->lastEntryTimestampMs = stats[LAST_DEEP_SLEEP_ENTER_TSTAMP_MS];
state->supportedOnlyInSuspend = false;
return 0;
}
// Methods from ::android::hardware::power::V1_1::IPower follow.
Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) {
hidl_vec<PowerStateSubsystem> subsystems;
subsystems.resize(STATS_SOURCE_COUNT);
// Get low power stats for all of the system masters.
if (get_master_low_power_stats(&subsystems) != 0) {
ALOGE("%s: failed to process master stats", __func__);
}
// Get WLAN subsystem low power stats.
if (get_wlan_low_power_stats(&subsystems[SUBSYSTEM_WLAN]) != 0) {
ALOGE("%s: failed to process wlan stats", __func__);
}
_hidl_cb(subsystems, Status::SUCCESS);
return Void();
}
bool Power::isSupportedGovernor() {
std::string buf;
if (android::base::ReadFileToString("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", &buf)) {
buf = android::base::Trim(buf);
}
// Only support EAS 1.2, legacy EAS
if (buf == "schedutil" || buf == "sched") {
return true;
} else {
LOG(ERROR) << "Governor not supported by powerHAL, skipping";
return false;
}
}
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 (!isSupportedGovernor() || !mReady) {
return Void();
}
switch(hint) {
case PowerHint_1_2::AUDIO_LOW_LATENCY:
ATRACE_BEGIN("audio_low_latency");
if (data) {
// Hint until canceled
ATRACE_INT("audio_low_latency_lock", 1);
mHintManager->DoHint("AUDIO_LOW_LATENCY");
ALOGD("AUDIO LOW LATENCY ON");
} else {
ATRACE_INT("audio_low_latency_lock", 0);
mHintManager->EndHint("AUDIO_LOW_LATENCY");
ALOGD("AUDIO LOW LATENCY OFF");
}
ATRACE_END();
break;
case PowerHint_1_2::AUDIO_STREAMING:
ATRACE_BEGIN("audio_streaming");
if (mVRModeOn || mSustainedPerfModeOn) {
ALOGV("%s: ignoring due to other active perf hints", __func__);
} else {
if (data) {
// Hint until canceled
ATRACE_INT("audio_streaming_lock", 1);
mHintManager->DoHint("AUDIO_STREAMING");
ALOGD("AUDIO STREAMING ON");
} else {
ATRACE_INT("audio_streaming_lock", 0);
mHintManager->EndHint("AUDIO_STREAMING");
ALOGD("AUDIO STREAMING OFF");
}
}
ATRACE_END();
break;
case PowerHint_1_2::CAMERA_LAUNCH:
ATRACE_BEGIN("camera_launch");
if (data > 0) {
ATRACE_INT("camera_launch_lock", 1);
mHintManager->DoHint("CAMERA_LAUNCH", std::chrono::milliseconds(data));
ALOGD("CAMERA LAUNCH ON: %d MS, LAUNCH ON: 2500 MS", data);
// boosts 2.5s for launching
mHintManager->DoHint("LAUNCH", std::chrono::milliseconds(2500));
} else if (data == 0) {
ATRACE_INT("camera_launch_lock", 0);
mHintManager->EndHint("CAMERA_LAUNCH");
ALOGD("CAMERA LAUNCH OFF");
} else {
ALOGE("CAMERA LAUNCH INVALID DATA: %d", data);
}
ATRACE_END();
break;
case PowerHint_1_2::CAMERA_STREAMING:
ATRACE_BEGIN("camera_streaming");
if (data > 0) {
ATRACE_INT("camera_streaming_lock", 1);
mHintManager->DoHint("CAMERA_STREAMING");
ALOGD("CAMERA STREAMING ON");
mCameraStreamingModeOn = true;
} else if (data == 0) {
ATRACE_INT("camera_streaming_lock", 0);
mHintManager->EndHint("CAMERA_STREAMING");
ALOGD("CAMERA STREAMING OFF");
mCameraStreamingModeOn = false;
} else {
ALOGE("CAMERA STREAMING INVALID DATA: %d", data);
}
ATRACE_END();
break;
case PowerHint_1_2::CAMERA_SHOT:
ATRACE_BEGIN("camera_shot");
if (data > 0) {
ATRACE_INT("camera_shot_lock", 1);
mHintManager->DoHint("CAMERA_SHOT", std::chrono::milliseconds(data));
ALOGD("CAMERA SHOT ON: %d MS", data);
} else if (data == 0) {
ATRACE_INT("camera_shot_lock", 0);
mHintManager->EndHint("CAMERA_SHOT");
ALOGD("CAMERA SHOT OFF");
} else {
ALOGE("CAMERA SHOT INVALID DATA: %d", data);
}
ATRACE_END();
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 (!isSupportedGovernor() || !mReady) {
return Void();
}
if (hint == PowerHint_1_3::EXPENSIVE_RENDERING) {
if (mVRModeOn || mSustainedPerfModeOn) {
ALOGV("%s: ignoring due to other active perf hints", __func__);
return Void();
}
if (data > 0) {
ATRACE_INT("EXPENSIVE_RENDERING", 1);
mHintManager->DoHint("EXPENSIVE_RENDERING");
} else {
ATRACE_INT("EXPENSIVE_RENDERING", 0);
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),
boolToString(mCameraStreamingModeOn),
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

View File

@ -1,93 +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 ANDROID_HARDWARE_POWER_V1_3_POWER_H
#define ANDROID_HARDWARE_POWER_V1_3_POWER_H
#include <atomic>
#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"
namespace android {
namespace hardware {
namespace power {
namespace V1_3 {
namespace implementation {
using ::android::hardware::power::V1_0::Feature;
using ::android::hardware::power::V1_3::IPower;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::InteractionHandler;
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;
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";
struct Power : public IPower {
// 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:
static bool isSupportedGovernor();
std::shared_ptr<HintManager> mHintManager;
std::unique_ptr<InteractionHandler> mInteractionHandler;
std::atomic<bool> mVRModeOn;
std::atomic<bool> mSustainedPerfModeOn;
std::atomic<bool> mCameraStreamingModeOn;
std::atomic<bool> mReady;
std::thread mInitThread;
};
} // namespace implementation
} // namespace V1_3
} // namespace power
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_POWER_V1_3_POWER_H

View File

@ -1,21 +0,0 @@
service vendor.power-hal-1-3 /vendor/bin/hw/android.hardware.power@1.3-service.xiaomi_sdm845-libperfmgr
class hal
user root
group system
# 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

View File

@ -1,226 +0,0 @@
/*
* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_NIDEBUG 0
#define LOG_TAG "android.hardware.power@1.3-service.xiaomi_sdm845-libperfmgr"
#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <log/log.h>
#include "power-helper.h"
#ifndef MASTER_STATS_FILE
#define MASTER_STATS_FILE "/sys/power/rpmh_stats/master_stats"
#endif
#ifndef WLAN_STATS_FILE
#define WLAN_STATS_FILE "/d/wlan0/power_stats"
#endif
#ifndef SYSTEM_STATS_FILE
#define SYSTEM_STATS_FILE "/sys/power/system_sleep/stats"
#endif
#define LINE_SIZE 128
const char *master_stats_labels[MASTER_STATS_COUNT] = {
"Sleep Accumulated Duration",
"Sleep Count",
"Sleep Last Entered At",
};
struct stats_section master_sections[MASTER_COUNT] = {
{ MASTER_APSS, "APSS", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
{ MASTER_MPSS, "MPSS", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
{ MASTER_ADSP, "ADSP", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
{ MASTER_SLPI, "SLPI", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
// The following masters are currently unused
//{ MASTER_CDSP, "CDSP", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
//{ MASTER_GPU, "GPU", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
//{ MASTER_DISPLAY, "DISPLAY", master_stats_labels, ARRAY_SIZE(master_stats_labels) },
};
const char *wlan_stats_labels[WLAN_STATS_COUNT] = {
"cumulative_sleep_time_ms",
"cumulative_total_on_time_ms",
"deep_sleep_enter_counter",
"last_deep_sleep_enter_tstamp_ms"
};
struct stats_section wlan_sections[] = {
{ SUBSYSTEM_WLAN, "POWER DEBUG STATS", wlan_stats_labels, ARRAY_SIZE(wlan_stats_labels) },
};
const char *system_stats_labels[SYSTEM_STATE_STATS_COUNT] = {
"count",
"actual last sleep(msec)"
};
struct stats_section system_sections[] = {
{ SYSTEM_STATES, "RPM Mode:aosd", system_stats_labels, ARRAY_SIZE(system_stats_labels) },
{ SYSTEM_STATES, "RPM Mode:cxsd", system_stats_labels, ARRAY_SIZE(system_stats_labels) },
};
static int parse_stats(const char **stat_labels, size_t num_stats,
uint64_t *list, FILE *fp) {
ssize_t nread;
size_t len = LINE_SIZE;
char *line;
size_t stats_read = 0;
size_t i;
line = malloc(len);
if (!line) {
ALOGE("%s: no memory to hold line", __func__);
return -ENOMEM;
}
while ((stats_read < num_stats) &&
(nread = getline(&line, &len, fp) > 0)) {
char *key = line + strspn(line, " \t");
char *value = strchr(key, ':');
if (!value || (value > (line + len)))
continue;
*value++ = '\0';
for (i = 0; i < num_stats; i++) {
if (!strncmp(key, stat_labels[i], strlen(stat_labels[i]))) {
list[i] = strtoull(value, NULL, 0);
stats_read++;
break;
}
}
}
free(line);
return stats_read;
}
static int extract_stats(uint64_t *stats_list, size_t entries_per_section, char *file,
struct stats_section *sections, size_t num_sections) {
FILE *fp;
ssize_t read;
size_t len = LINE_SIZE;
char *line;
size_t i;
size_t sections_read = 0;
size_t stats_read = 0;
int ret = 0;
fp = fopen(file, "re");
if (fp == NULL) {
ALOGE("%s: failed to open: %s Error = %s", __func__, file, strerror(errno));
return -errno;
}
line = malloc(len);
if (!line) {
ALOGE("%s: no memory to hold line", __func__);
fclose(fp);
return -ENOMEM;
}
// Ensure that any missing stats default to 0
for (i = 0; i < (entries_per_section * num_sections); i++) {
stats_list[i] = 0L;
}
// Iterate over the sections we expect to find in the file, calling parse_stats()
// to process each section as we detect section headers
while ((sections_read < num_sections) && (read = getline(&line, &len, fp) != -1)) {
size_t begin = strspn(line, " \t");
for (i = 0; i < num_sections; i++) {
if (!strncmp(line + begin, sections[i].label, strlen(sections[i].label))) {
sections_read++;
break;
}
}
if (i == num_sections) {
continue;
}
stats_read = parse_stats(sections[i].stats_labels, sections[i].num_stats,
&stats_list[i * entries_per_section], fp);
// If we don't find all of the stats we expect in this section, our understanding of
// the input is wrong, and we can't just carry on as if everything is okay. Better
// to log the error and give up than potentially return incorrect data as stats.
if (stats_read != sections[i].num_stats) {
ALOGE("%s: failed to read all stats for %s section (%zu of %zu)", __func__,
sections[i].label, stats_read, sections[i].num_stats);
break;
}
}
free(line);
fclose(fp);
return ret;
}
int extract_master_stats(uint64_t *list, size_t list_length) {
size_t entries_per_section = list_length / ARRAY_SIZE(master_sections);
if (list_length % entries_per_section != 0) {
ALOGW("%s: stats list size not an even multiple of section count", __func__);
}
return extract_stats(list, entries_per_section, MASTER_STATS_FILE,
master_sections, ARRAY_SIZE(master_sections));
}
int extract_wlan_stats(uint64_t *list, size_t list_length) {
size_t entries_per_section = list_length / ARRAY_SIZE(wlan_sections);
if (list_length % entries_per_section != 0) {
ALOGW("%s: stats list size not an even multiple of section count", __func__);
}
return extract_stats(list, entries_per_section, WLAN_STATS_FILE,
wlan_sections, ARRAY_SIZE(wlan_sections));
}
int extract_system_stats(uint64_t *list, size_t list_length) {
size_t entries_per_section = list_length / ARRAY_SIZE(system_sections);
if (list_length % entries_per_section != 0) {
ALOGW("%s: stats list size not an even multiple of section count", __func__);
}
return extract_stats(list, entries_per_section, SYSTEM_STATS_FILE,
system_sections, ARRAY_SIZE(system_sections));
}

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __POWER_HELPER_H__
#define __POWER_HELPER_H__
#ifdef __cplusplus
extern "C" {
#endif
// These values are used as indices in getSubsystemLowPowerStats(), as source IDs
// in stats_section instances, and (in the case of the _COUNT values) to dimension
// containers. The values used as indices need to be contiguous, but others do
// not (which is why SYSTEM_STATES is all the way at the end; it is not used as
// an index, but only as a source ID).
enum stats_source {
// Master stats
MASTER_APSS = 0,
MASTER_MPSS,
MASTER_ADSP,
MASTER_SLPI,
// The following 3 masters are supported by the RPMh stats driver, but not
// in use on our devices.
// MASTER_CDSP,
// MASTER_GPU,
// MASTER_DISPLAY,
MASTER_COUNT, // Total master sources
// Subsystem stats. (Numbering starts at MASTER_COUNT to preserve
// contiguous source numbering.)
SUBSYSTEM_WLAN = MASTER_COUNT,
// Uncomment when Citadel returns
//SUBSYSTEM_CITADEL,
// Don't add any lines after this line
STATS_SOURCE_COUNT, // Total sources of any kind excluding system states
SUBSYSTEM_COUNT = STATS_SOURCE_COUNT - MASTER_COUNT,
SYSTEM_STATES
};
enum master_sleep_states {
MASTER_SLEEP = 0,
//Don't add any lines after this line
MASTER_SLEEP_STATE_COUNT
};
enum master_stats {
SLEEP_CUMULATIVE_DURATION_MS = 0,
SLEEP_ENTER_COUNT,
SLEEP_LAST_ENTER_TSTAMP_MS,
//Don't add any lines after this line
MASTER_STATS_COUNT
};
enum wlan_sleep_states {
WLAN_STATE_ACTIVE = 0,
WLAN_STATE_DEEP_SLEEP,
//Don't add any lines after this line
WLAN_SLEEP_STATE_COUNT
};
// Note that stats for both WLAN sleep states are in a single section of the
// source file, so there's only 1 stats section despite having 2 states
enum wlan_stats {
CUMULATIVE_SLEEP_TIME_MS = 0,
CUMULATIVE_TOTAL_ON_TIME_MS,
DEEP_SLEEP_ENTER_COUNTER,
LAST_DEEP_SLEEP_ENTER_TSTAMP_MS,
//Don't add any lines after this line
WLAN_STATS_COUNT
};
enum system_sleep_states {
SYSTEM_STATE_AOSD = 0,
SYSTEM_STATE_CXSD,
//Don't add any lines after this line
SYSTEM_SLEEP_STATE_COUNT
};
enum system_state_stats {
TOTAL_COUNT = 0,
ACCUMULATED_TIME_MS,
//Don't add any lines after this line
SYSTEM_STATE_STATS_COUNT
};
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
#endif
struct stats_section {
enum stats_source source;
const char *label;
const char **stats_labels;
size_t num_stats;
};
int extract_master_stats(uint64_t *list, size_t list_length);
int extract_wlan_stats(uint64_t *list, size_t list_length);
int extract_system_stats(uint64_t *list, size_t list_length);
#ifdef __cplusplus
}
#endif
#endif //__POWER_HELPER_H__

View File

@ -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.xiaomi_sdm845-libperfmgr"
#include <android/log.h>
#include <hidl/HidlTransportSupport.h>
#include "Power.h"
using android::sp;
using android::status_t;
using android::OK;
// 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 is starting.");
android::sp<IPower> service = new Power();
if (service == nullptr) {
ALOGE("Can not create an instance of Power HAL Iface, exiting.");
return 1;
}
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;
}

View File

@ -57,10 +57,11 @@ int open_ts_input() {
} // anonymous namespace
namespace aidl {
namespace android {
namespace google {
namespace hardware {
namespace power {
namespace impl {
namespace pixel {
static constexpr int kInputEventWakeupModeOff = 4;
static constexpr int kInputEventWakeupModeOn = 5;
@ -99,8 +100,9 @@ bool setDeviceSpecificMode(Mode type, bool enabled) {
}
}
} // namespace pixel
} // namespace impl
} // namespace power
} // namespace hardware
} // namespace android
} // namespace google
} // namespace aidl

View File

@ -248,7 +248,7 @@ PRODUCT_PACKAGES += \
# Power
PRODUCT_PACKAGES += \
android.hardware.power@1.3-service.xiaomi_sdm845-libperfmgr
android.hardware.power-service.xiaomi-libperfmgr
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/power/configs/powerhint.json:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.json
@ -292,6 +292,8 @@ PRODUCT_PACKAGES += \
# Soong namespaces
PRODUCT_SOONG_NAMESPACES += \
$(LOCAL_PATH) \
hardware/google/interfaces \
hardware/google/pixel \
hardware/xiaomi
# Telephony

View File

@ -44,7 +44,7 @@
/vendor/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service\.xiaomi_sdm845 u:object_r:hal_fingerprint_default_exec:s0
/vendor/bin/hw/android\.hardware\.light@2\.0-service\.xiaomi_sdm845 u:object_r:hal_light_default_exec:s0
/vendor/bin/hw/android\.hardware\.neuralnetworks@1\.2-service-qti u:object_r:hal_neuralnetworks_default_exec:s0
/vendor/bin/hw/android\.hardware\.power@1\.3-service\.xiaomi_sdm845-libperfmgr u:object_r:hal_power_default_exec:s0
/vendor/bin/hw/android\.hardware\.power-service\.xiaomi-libperfmgr u:object_r:hal_power_default_exec:s0
/vendor/bin/hw/vendor\.lineage\.biometrics\.fingerprint\.inscreen@1.0-service\.xiaomi_sdm845 u:object_r:hal_lineage_fod_sdm845_exec:s0
/vendor/bin/hw/vendor\.lineage\.livedisplay@2\.0-service\.xiaomi_sdm845 u:object_r:hal_lineage_livedisplay_qti_exec:s0