Merge "wahoo: power: switch to libperfmgr for powerhint"

This commit is contained in:
Thierry Strudel
2018-01-05 06:18:34 +00:00
committed by Android (Google) Code Review
16 changed files with 1576 additions and 39 deletions

View File

@@ -169,10 +169,10 @@ PRODUCT_COPY_FILES += \
# power HAL
PRODUCT_PACKAGES += \
android.hardware.power@1.2-service.wahoo
android.hardware.power@1.2-service.wahoo-libperfmgr
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/powerhint.xml:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.xml
$(LOCAL_PATH)/powerhint.json:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.json
# health HAL
PRODUCT_PACKAGES += \

View File

@@ -385,7 +385,6 @@ on zygote-start
# b/62837579 elabel directory
mkdir /data/misc/elabel 0700 system system
on early-boot
# wait for devices
wait_for_prop sys.qcom.devup 1
@@ -549,11 +548,20 @@ service vendor.per_proxy /vendor/bin/pm-proxy
disabled
on property:sys.post_boot.parsed=1
start vendor.perfd
# Setup permission for powerHAL
chown system system /dev/stune/top-app/schedtune.boost
chown system system /dev/cpu_dma_latency
chown system system /sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/min_freq
chown system system /sys/class/kgsl/kgsl-3d0/devfreq/min_freq
chown system system /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
chown system system /sys/class/devfreq/soc:qcom,gpubw/min_freq
chown system system /sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/bw_hwmon/hyst_trigger_count
chown system system /sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/bw_hwmon/hist_memory
chown system system /sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/bw_hwmon/hyst_length
chown system system /sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/min_freq
on property:sys.boot_completed=1
# Enable power setting and set sys.post_boot.parsed to 1
# to start perfd
start vendor.power_sh
# Enable UFS powersaving

View File

@@ -0,0 +1,37 @@
//
// 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.2-service.wahoo-libperfmgr",
relative_install_path: "hw",
init_rc: ["android.hardware.power@1.2-service.wahoo-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",
"libperfmgr",
],
proprietary: true,
}

View File

@@ -0,0 +1,244 @@
/*
* 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.2-service.wahoo-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/graphics/fb0/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

@@ -0,0 +1,71 @@
/*
* 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

346
power-libperfmgr/Power.cpp Normal file
View File

@@ -0,0 +1,346 @@
/*
* 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.2-service.wahoo-libperfmgr"
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <utils/Log.h>
#include "Power.h"
#include "power-helper.h"
/* RPM runs at 19.2Mhz. Divide by 19200 for msec */
#define RPM_CLK 19200
extern struct stat_pair rpm_stat_map[];
namespace android {
namespace hardware {
namespace power {
namespace V1_2 {
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(HintManager::GetFromJSON("/vendor/etc/powerhint.json")),
mInteractionHandler(mHintManager),
mVRModeOn(false),
mSustainedPerfModeOn(false),
mEncoderModeOn(false) {
mInteractionHandler.Init();
}
// 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()) {
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::VIDEO_ENCODE:
if (mVRModeOn || mSustainedPerfModeOn) {
ALOGV("%s: ignoring due to other active perf hints", __func__);
} else {
if (data) {
// Hint until canceled
mHintManager->DoHint("VIDEO_ENCODE");
ALOGD("VIDEO_ENCODE ON");
mEncoderModeOn = true;
} else {
mHintManager->EndHint("VIDEO_ENCODE");
ALOGD("VIDEO_ENCODE OFF");
mEncoderModeOn = false;
}
}
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");
ALOGD("LAUNCH ON");
} else {
mHintManager->EndHint("LAUNCH");
ALOGD("LAUNCH OFF");
}
}
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[MAX_PLATFORM_STATS * MAX_RPM_PARAMS] = {0};
uint64_t *values;
struct PowerStatePlatformSleepState *state;
int ret;
states.resize(PLATFORM_SLEEP_MODES_COUNT);
ret = extract_platform_stats(stats);
if (ret != 0) {
states.resize(0);
goto done;
}
/* Update statistics for XO_shutdown */
state = &states[RPM_MODE_XO];
state->name = "XO_shutdown";
values = stats + (RPM_MODE_XO * MAX_RPM_PARAMS);
state->residencyInMsecSinceBoot = values[1];
state->totalTransitions = values[0];
state->supportedOnlyInSuspend = false;
state->voters.resize(XO_VOTERS);
for(size_t i = 0; i < XO_VOTERS; i++) {
int voter = static_cast<int>(i + XO_VOTERS_START);
state->voters[i].name = rpm_stat_map[voter].label;
values = stats + (voter * MAX_RPM_PARAMS);
state->voters[i].totalTimeInMsecVotedForSinceBoot = values[0] / RPM_CLK;
state->voters[i].totalNumberOfTimesVotedSinceBoot = values[1];
}
/* Update statistics for VMIN state */
state = &states[RPM_MODE_VMIN];
state->name = "VMIN";
values = stats + (RPM_MODE_VMIN * MAX_RPM_PARAMS);
state->residencyInMsecSinceBoot = values[1];
state->totalTransitions = values[0];
state->supportedOnlyInSuspend = false;
state->voters.resize(VMIN_VOTERS);
//Note: No filling of state voters since VMIN_VOTERS = 0
done:
_hidl_cb(states, Status::SUCCESS);
return Void();
}
static int get_wlan_low_power_stats(struct PowerStateSubsystem &subsystem) {
uint64_t stats[WLAN_POWER_PARAMS_COUNT] = {0};
struct PowerStateSubsystemSleepState *state;
int ret;
ret = extract_wlan_stats(stats);
if (ret)
return ret;
subsystem.name = "wlan";
subsystem.states.resize(WLAN_STATES_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;
int ret;
subsystems.resize(SUBSYSTEM_COUNT);
//We currently have only one Subsystem for WLAN
ret = get_wlan_low_power_stats(subsystems[SUBSYSTEM_WLAN]);
if (ret != 0)
goto done;
//Add query for other subsystems here
done:
_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()) {
return Void();
}
switch(hint) {
case PowerHint_1_2::AUDIO_LOW_LATENCY:
if (data) {
// Hint until canceled
mHintManager->DoHint("AUDIO_LOW_LATENCY");
ALOGD("AUDIO LOW LATENCY ON");
} else {
mHintManager->EndHint("AUDIO_LOW_LATENCY");
ALOGD("AUDIO LOW LATENCY OFF");
}
break;
case PowerHint_1_2::AUDIO_STREAMING:
if (data) {
// Hint until canceled
mHintManager->DoHint("AUDIO_STREAMING");
ALOGD("AUDIO LOW LATENCY ON");
} else {
mHintManager->EndHint("AUDIO_STREAMING");
ALOGD("AUDIO LOW LATENCY OFF");
}
break;
case PowerHint_1_2::CAMERA_LAUNCH:
if (data > 0) {
mHintManager->DoHint("CAMERA_LAUNCH", std::chrono::milliseconds(data));
ALOGD("CAMERA LAUNCH ON: %d MS", data);
// boosts 2.5s for launching
mHintManager->DoHint("LAUNCH", std::chrono::milliseconds(2500));
} else if (data == 0) {
mHintManager->EndHint("CAMERA_LAUNCH");
ALOGD("CAMERA LAUNCH OFF");
} else {
ALOGE("CAMERA LAUNCH INVALID DATA: %d", data);
}
break;
case PowerHint_1_2::CAMERA_STREAMING:
if (data > 0) {
mHintManager->DoHint("CAMERA_STREAMING", std::chrono::milliseconds(data));
ALOGD("CAMERA STREAMING ON: %d MS", data);
} else if (data == 0) {
mHintManager->EndHint("CAMERA_STREAMING");
ALOGD("CAMERA STREAMING OFF");
} else {
ALOGE("CAMERA STREAMING INVALID DATA: %d", data);
}
break;
case PowerHint_1_2::CAMERA_SHOT:
if (data > 0) {
mHintManager->DoHint("CAMERA_SHOT", std::chrono::milliseconds(data));
ALOGD("CAMERA SHOT ON: %d MS", data);
} else if (data == 0) {
mHintManager->EndHint("CAMERA_SHOT");
ALOGD("CAMERA SHOT OFF");
} else {
ALOGE("CAMERA SHOT INVALID DATA: %d", data);
}
break;
default:
return powerHint(static_cast<PowerHint_1_0>(hint), data);
}
return Void();
}
} // namespace implementation
} // namespace V1_2
} // namespace power
} // namespace hardware
} // namespace android

77
power-libperfmgr/Power.h Normal file
View File

@@ -0,0 +1,77 @@
/*
* 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_2_POWER_H
#define ANDROID_HARDWARE_POWER_V1_2_POWER_H
#include <atomic>
#include <android/hardware/power/1.2/IPower.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include "InteractionHandler.h"
namespace android {
namespace hardware {
namespace power {
namespace V1_2 {
namespace implementation {
using ::android::hardware::power::V1_0::Feature;
using ::android::hardware::power::V1_2::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 ::android::perfmgr::HintManager;
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::hidl::base::V1_0::IBase follow.
private:
std::shared_ptr<HintManager> mHintManager;
InteractionHandler mInteractionHandler;
static bool isSupportedGovernor();
std::atomic<bool> mVRModeOn;
std::atomic<bool> mSustainedPerfModeOn;
std::atomic<bool> mEncoderModeOn;
};
} // namespace implementation
} // namespace V1_2
} // namespace power
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_POWER_V1_2_POWER_H

View File

@@ -0,0 +1,4 @@
service vendor.power-hal-1-2 /vendor/bin/hw/android.hardware.power@1.2-service.wahoo-libperfmgr
class hal
user system
group system

View File

@@ -0,0 +1,176 @@
/*
* 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.2-service.wahoo-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 RPM_SYSTEM_STAT
#define RPM_SYSTEM_STAT "/d/system_stats"
#endif
#ifndef WLAN_POWER_STAT
#define WLAN_POWER_STAT "/d/wlan0/power_stats"
#endif
#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
#define LINE_SIZE 128
const char *rpm_stat_params[MAX_RPM_PARAMS] = {
"count",
"actual last sleep(msec)",
};
const char *master_stat_params[MAX_RPM_PARAMS] = {
"Accumulated XO duration",
"XO Count",
};
struct stat_pair rpm_stat_map[] = {
{ RPM_MODE_XO, "RPM Mode:vlow", rpm_stat_params, ARRAY_SIZE(rpm_stat_params) },
{ RPM_MODE_VMIN, "RPM Mode:vmin", rpm_stat_params, ARRAY_SIZE(rpm_stat_params) },
{ VOTER_APSS, "APSS", master_stat_params, ARRAY_SIZE(master_stat_params) },
{ VOTER_MPSS, "MPSS", master_stat_params, ARRAY_SIZE(master_stat_params) },
{ VOTER_ADSP, "ADSP", master_stat_params, ARRAY_SIZE(master_stat_params) },
{ VOTER_SLPI, "SLPI", master_stat_params, ARRAY_SIZE(master_stat_params) },
};
const char *wlan_power_stat_params[] = {
"cumulative_sleep_time_ms",
"cumulative_total_on_time_ms",
"deep_sleep_enter_counter",
"last_deep_sleep_enter_tstamp_ms"
};
struct stat_pair wlan_stat_map[] = {
{ WLAN_POWER_DEBUG_STATS, "POWER DEBUG STATS", wlan_power_stat_params, ARRAY_SIZE(wlan_power_stat_params) },
};
static int parse_stats(const char **params, size_t params_size,
uint64_t *list, FILE *fp) {
ssize_t nread;
size_t len = LINE_SIZE;
char *line;
size_t params_read = 0;
size_t i;
line = malloc(len);
if (!line) {
ALOGE("%s: no memory to hold line", __func__);
return -ENOMEM;
}
while ((params_read < params_size) &&
(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 < params_size; i++) {
if (!strcmp(key, params[i])) {
list[i] = strtoull(value, NULL, 0);
params_read++;
break;
}
}
}
free(line);
return 0;
}
static int extract_stats(uint64_t *list, char *file,
struct stat_pair *map, size_t map_size) {
FILE *fp;
ssize_t read;
size_t len = LINE_SIZE;
char *line;
size_t i, 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;
}
while ((stats_read < map_size) && (read = getline(&line, &len, fp) != -1)) {
size_t begin = strspn(line, " \t");
for (i = 0; i < map_size; i++) {
if (!strncmp(line + begin, map[i].label, strlen(map[i].label))) {
stats_read++;
break;
}
}
if (i == map_size)
continue;
ret = parse_stats(map[i].parameters, map[i].num_parameters,
&list[map[i].stat * MAX_RPM_PARAMS], fp);
if (ret < 0)
break;
}
free(line);
fclose(fp);
return ret;
}
int extract_platform_stats(uint64_t *list) {
return extract_stats(list, RPM_SYSTEM_STAT, rpm_stat_map, ARRAY_SIZE(rpm_stat_map));
}
int extract_wlan_stats(uint64_t *list) {
return extract_stats(list, WLAN_POWER_STAT, wlan_stat_map, ARRAY_SIZE(wlan_stat_map));
}

View File

@@ -0,0 +1,100 @@
/*
* 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
enum stats_type {
//Platform Stats
RPM_MODE_XO = 0,
RPM_MODE_VMIN,
RPM_MODE_MAX,
XO_VOTERS_START = RPM_MODE_MAX,
VOTER_APSS = XO_VOTERS_START,
VOTER_MPSS,
VOTER_ADSP,
VOTER_SLPI,
MAX_PLATFORM_STATS,
//WLAN Stats
WLAN_POWER_DEBUG_STATS = 0,
MAX_WLAN_STATS,
};
enum subsystem_type {
SUBSYSTEM_WLAN = 0,
//Don't add any lines after this line
SUBSYSTEM_COUNT
};
enum wlan_sleep_states {
WLAN_STATE_ACTIVE = 0,
WLAN_STATE_DEEP_SLEEP,
//Don't add any lines after this line
WLAN_STATES_COUNT
};
enum wlan_power_params {
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_POWER_PARAMS_COUNT
};
#define PLATFORM_SLEEP_MODES_COUNT RPM_MODE_MAX
#define MAX_RPM_PARAMS 2
#define XO_VOTERS (MAX_PLATFORM_STATS - XO_VOTERS_START)
#define VMIN_VOTERS 0
struct stat_pair {
enum stats_type stat;
const char *label;
const char **parameters;
size_t num_parameters;
};
int extract_platform_stats(uint64_t *list);
int extract_wlan_stats(uint64_t *list);
#ifdef __cplusplus
}
#endif
#endif //__POWER_HELPER_H__

View File

@@ -0,0 +1,67 @@
/*
* 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.2-service.wahoo-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_2::IPower;
using android::hardware::power::V1_2::implementation::Power;
int main() {
status_t status;
android::sp<IPower> service = nullptr;
ALOGI("Power HAL Service 1.2 for Wahoo is starting.");
service = new Power();
if (service == nullptr) {
ALOGE("Can not create an instance of Power HAL Iface, exiting.");
goto shutdown;
}
configureRpcThreadpool(1, true /*callerWillJoin*/);
status = service->registerAsService();
if (status != OK) {
ALOGE("Could not register service for Power HAL Iface (%d).", status);
goto shutdown;
}
ALOGI("Power Service is ready");
joinRpcThreadpool();
//Should not pass this line
shutdown:
// In normal operation, we don't expect the thread pool to exit
ALOGE("Power Service is shutting down");
return 1;
}

431
powerhint.json Executable file
View File

@@ -0,0 +1,431 @@
{
"Nodes": [
{
"Name": "CPULittleClusterMinFreq",
"Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq",
"Values": [
"1900800",
"1555200",
"1512000",
"1478400",
"1134000",
"384000"
],
"ResetOnInit": true
},
{
"Name": "CPULittleClusterMaxFreq",
"Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq",
"Values": [
"1555200",
"1478400",
"1248000",
"1900800"
],
"ResetOnInit": true
},
{
"Name": "CPUBigClusterMinFreq",
"Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq",
"Values": [
"2457600",
"1574400",
"1420800",
"1344000",
"1132800",
"300000"
],
"ResetOnInit": true
},
{
"Name": "CPUBigClusterMaxFreq",
"Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq",
"Values": [
"1132800",
"1267200",
"1344000",
"1574400",
"1958400",
"2457600"
],
"ResetOnInit": true
},
{
"Name": "GPUMinFreq",
"Path": "/sys/class/kgsl/kgsl-3d0/devfreq/min_freq",
"Values": [
"515000000",
"414000000",
"257000000"
],
"ResetOnInit": true
},
{
"Name": "GPUMaxFreq",
"Path": "/sys/class/kgsl/kgsl-3d0/devfreq/max_freq",
"Values": [
"342000000",
"414000000",
"515000000",
"710000000"
],
"ResetOnInit": true
},
{
"Name": "GPUBusMinFreq",
"Path": "/sys/class/devfreq/soc:qcom,gpubw/min_freq",
"Values": [
"11863",
"7759",
"0"
],
"ResetOnInit": true
},
{
"Name": "TASchedtuneBoost",
"Path": "/dev/stune/top-app/schedtune.boost",
"Values": [
"50",
"10"
],
"ResetOnInit": true
},
{
"Name": "CPUBWHystTriggerCount",
"Path": "/sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/bw_hwmon/hyst_trigger_count",
"Values": [
"0",
"3"
],
"ResetOnInit": true
},
{
"Name": "CPUBWHistMemory",
"Path": "/sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/bw_hwmon/hist_memory",
"Values": [
"0",
"20"
],
"ResetOnInit": true
},
{
"Name": "CPUBWHystLength",
"Path": "/sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/bw_hwmon/hyst_length",
"Values": [
"0",
"10"
],
"ResetOnInit": true
},
{
"Name": "CPUBWMinFreq",
"Path": "/sys/devices/soc/soc:qcom,cpubw/devfreq/soc:qcom,cpubw/min_freq",
"Values": [
"13763",
"5195",
"1525",
"762"
],
"ResetOnInit": true
},
{
"Name": "PMQoSCpuDmaLatency",
"Path": "/dev/cpu_dma_latency",
"Values": [
"44",
"100"
],
"HoldFd": true
}
],
"Actions": [
{
"PowerHint": "VIDEO_ENCODE",
"Node": "CPUBigClusterMaxFreq",
"ValueIndex": 4,
"Duration": 0
},
{
"PowerHint": "SUSTAINED_PERFORMANCE",
"Node": "CPUBigClusterMaxFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "SUSTAINED_PERFORMANCE",
"Node": "CPULittleClusterMaxFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "SUSTAINED_PERFORMANCE",
"Node": "GPUMaxFreq",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "CPUBigClusterMaxFreq",
"ValueIndex": 3,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "CPULittleClusterMaxFreq",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "GPUMaxFreq",
"ValueIndex": 2,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "GPUMinFreq",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "VR_MODE",
"Node": "GPUBusMinFreq",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "CPUBigClusterMaxFreq",
"ValueIndex": 2,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 3,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "CPULittleClusterMaxFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 3,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "GPUMaxFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "GPUMaxFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "VR_SUSTAINED_PERFORMANCE",
"Node": "GPUBusMinFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 4,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 4,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "TASchedtuneBoost",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "CPUBWHystTriggerCount",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "CPUBWHystLength",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "CPUBWHistMemory",
"ValueIndex": 0,
"Duration": 0
},
{
"PowerHint": "INTERACTION",
"Node": "CPUBWMinFreq",
"ValueIndex": 1,
"Duration": 0
},
{
"PowerHint": "LAUNCH",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "LAUNCH",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "LAUNCH",
"Node": "PMQoSCpuDmaLatency",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "LAUNCH",
"Node": "CPUBWHystTriggerCount",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "LAUNCH",
"Node": "CPUBWHystLength",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "LAUNCH",
"Node": "CPUBWHistMemory",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "LAUNCH",
"Node": "CPUBWMinFreq",
"ValueIndex": 0,
"Duration": 5000
},
{
"PowerHint": "CAMERA_LAUNCH",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_LAUNCH",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_LAUNCH",
"Node": "PMQoSCpuDmaLatency",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_STREAMING",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_STREAMING",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_STREAMING",
"Node": "PMQoSCpuDmaLatency",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "CPULittleClusterMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "PMQoSCpuDmaLatency",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "CPUBWHystTriggerCount",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "CPUBWHystLength",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "CPUBWHistMemory",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "CAMERA_SHOT",
"Node": "CPUBWMinFreq",
"ValueIndex": 0,
"Duration": 1000
},
{
"PowerHint": "AUDIO_STREAMING",
"Node": "CPUBigClusterMinFreq",
"ValueIndex": 2,
"Duration": 2000
},
{
"PowerHint": "AUDIO_STREAMING",
"Node": "PMQoSCpuDmaLatency",
"ValueIndex": 0,
"Duration": 2000
},
{
"PowerHint": "AUDIO_LOW_LATENCY",
"Node": "PMQoSCpuDmaLatency",
"ValueIndex": 0,
"Duration": 0
}
]
}

View File

@@ -169,6 +169,7 @@
/vendor/bin/oemlock-bridge u:object_r:hal_bootctl_default_exec:s0
/vendor/bin/hw/android\.hardware\.usb@1\.1-service.wahoo u:object_r:hal_usb_default_exec:s0
/vendor/bin/hw/android\.hardware\.power@1\.2-service.wahoo u:object_r:hal_power_default_exec:s0
/vendor/bin/hw/android\.hardware\.power@1\.2-service.wahoo-libperfmgr u:object_r:hal_power_default_exec:s0
/vendor/bin/hw/android\.hardware\.thermal@1\.0-service.wahoo u:object_r:hal_thermal_default_exec:s0
/vendor/bin/chre u:object_r:chre_exec:s0
/vendor/bin/time_daemon u:object_r:time_daemon_exec:s0

View File

@@ -1,7 +1,7 @@
# communicate with perfd
allow hal_camera perfd:unix_stream_socket connectto;
allow hal_camera perfd_socket:sock_file write;
allow hal_camera perfd_socket:sock_file w_file_perms;
dontaudit hal_camera perfd:unix_stream_socket connectto;
dontaudit hal_camera perfd_socket:sock_file write;
dontaudit hal_camera perfd_socket:sock_file w_file_perms;
allow hal_camera self:capability sys_nice;

View File

@@ -1,6 +1,3 @@
allow hal_power_default perfd:unix_stream_socket connectto;
allow hal_power_default perfd_socket:sock_file write;
allow hal_power_default sysfs_graphics:dir search;
allow hal_power_default sysfs_graphics:file r_file_perms;
@@ -8,3 +5,9 @@ allow hal_power_default debugfs_rpm:file r_file_perms;
allow hal_power_default debugfs_wlan:dir r_dir_perms;
allow hal_power_default debugfs_wlan:file r_file_perms;
# To do powerhint on nodes defined in powerhint.json
allow hal_power_default sysfs_msm_subsys:dir search;
allow hal_power_default sysfs_msm_subsys:file w_file_perms;
allow hal_power_default sysfs_devices_system_cpu:file w_file_perms;
allow hal_power_default latency_device:chr_file w_file_perms;

View File

@@ -2,31 +2,3 @@ type perfd, domain;
type perfd_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(perfd)
r_dir_file(perfd, sysfs_msm_subsys)
# perfd uses kill(pid, 0) to determine if a process exists.
# Determining if a process exists does not require the kill capability
# since a permission denied indicates the process exists.
dontaudit perfd self:capability kill;
allow perfd mediacodec:process signull;
allow perfd hal_power_default:process signull;
allow perfd cgroup:file r_file_perms;
allow perfd post_boot_prop:file r_file_perms;
allow perfd proc:file rw_file_perms;
allow perfd sysfs_clkscale:file r_file_perms;
allow perfd sysfs_graphics:dir search;
allow perfd sysfs_graphics:file r_file_perms;
allow perfd sysfs_soc:dir search;
allow perfd sysfs_soc:file r_file_perms;
allow perfd sysfs_graphics:dir search;
allow perfd sysfs_graphics:file r_file_perms;
allow perfd sysfs_msm_subsys:file w_file_perms;
allow perfd sysfs_devices_system_cpu:file w_file_perms;
allow perfd perfd_socket:sock_file write;
allow perfd latency_device:chr_file w_file_perms;