diff --git a/device.mk b/device.mk index c32b08ad..bd629ff4 100755 --- a/device.mk +++ b/device.mk @@ -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 += \ diff --git a/init.hardware.rc b/init.hardware.rc index df966230..8749ca09 100644 --- a/init.hardware.rc +++ b/init.hardware.rc @@ -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 diff --git a/power-libperfmgr/Android.bp b/power-libperfmgr/Android.bp new file mode 100644 index 00000000..8deca675 --- /dev/null +++ b/power-libperfmgr/Android.bp @@ -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, +} diff --git a/power-libperfmgr/InteractionHandler.cpp b/power-libperfmgr/InteractionHandler.cpp new file mode 100644 index 00000000..b8ce3ef1 --- /dev/null +++ b/power-libperfmgr/InteractionHandler.cpp @@ -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 +#include +#include +#include +#include +#include +#include + +#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 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 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( + new std::thread(&InteractionHandler::Routine, this)); + + return true; +} + +void InteractionHandler::Exit() { + std::unique_lock 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 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 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 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(); + } +} diff --git a/power-libperfmgr/InteractionHandler.h b/power-libperfmgr/InteractionHandler.h new file mode 100644 index 00000000..893c72f0 --- /dev/null +++ b/power-libperfmgr/InteractionHandler.h @@ -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 +#include +#include + +#include + +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 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 mThread; + std::mutex mLock; + std::condition_variable mCond; + std::shared_ptr mHintManager; +}; + +#endif //INTERACTIONHANDLER_H diff --git a/power-libperfmgr/Power.cpp b/power-libperfmgr/Power.cpp new file mode 100644 index 00000000..50608d52 --- /dev/null +++ b/power-libperfmgr/Power.cpp @@ -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 +#include +#include +#include +#include + +#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 Power::setInteractive(bool /* interactive */) { + return Void(); +} + +Return 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 Power::setFeature(Feature /*feature*/, bool /*activate*/) { + //Nothing to do + return Void(); +} + +Return Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) { + + hidl_vec 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(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 Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) { + + hidl_vec 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 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 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(hint), data); + } + return Void(); +} + +} // namespace implementation +} // namespace V1_2 +} // namespace power +} // namespace hardware +} // namespace android diff --git a/power-libperfmgr/Power.h b/power-libperfmgr/Power.h new file mode 100644 index 00000000..2d84fa57 --- /dev/null +++ b/power-libperfmgr/Power.h @@ -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 + +#include +#include +#include + +#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 setInteractive(bool /* interactive */) override; + Return powerHint(PowerHint_1_0 hint, int32_t data) override; + Return setFeature(Feature feature, bool activate) override; + Return getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override; + + // Methods from ::android::hardware::power::V1_1::IPower follow. + Return getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) override; + Return powerHintAsync(PowerHint_1_0 hint, int32_t data) override; + + // Methods from ::android::hardware::power::V1_2::IPower follow. + Return powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. + + private: + std::shared_ptr mHintManager; + InteractionHandler mInteractionHandler; + static bool isSupportedGovernor(); + std::atomic mVRModeOn; + std::atomic mSustainedPerfModeOn; + std::atomic mEncoderModeOn; +}; + +} // namespace implementation +} // namespace V1_2 +} // namespace power +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_POWER_V1_2_POWER_H diff --git a/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc b/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc new file mode 100644 index 00000000..65c43b67 --- /dev/null +++ b/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc @@ -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 diff --git a/power-libperfmgr/power-helper.c b/power-libperfmgr/power-helper.c new file mode 100644 index 00000000..e355710a --- /dev/null +++ b/power-libperfmgr/power-helper.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#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)); +} diff --git a/power-libperfmgr/power-helper.h b/power-libperfmgr/power-helper.h new file mode 100644 index 00000000..60646464 --- /dev/null +++ b/power-libperfmgr/power-helper.h @@ -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__ diff --git a/power-libperfmgr/service.cpp b/power-libperfmgr/service.cpp new file mode 100644 index 00000000..77fb1390 --- /dev/null +++ b/power-libperfmgr/service.cpp @@ -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 +#include + +#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 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; +} diff --git a/powerhint.json b/powerhint.json new file mode 100755 index 00000000..b641df33 --- /dev/null +++ b/powerhint.json @@ -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 + } + ] +} diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts index 2af2d30d..11839321 100644 --- a/sepolicy/vendor/file_contexts +++ b/sepolicy/vendor/file_contexts @@ -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 diff --git a/sepolicy/vendor/hal_camera.te b/sepolicy/vendor/hal_camera.te index 38edfc39..587e0782 100644 --- a/sepolicy/vendor/hal_camera.te +++ b/sepolicy/vendor/hal_camera.te @@ -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; diff --git a/sepolicy/vendor/hal_power_default.te b/sepolicy/vendor/hal_power_default.te index b588634b..3794e32b 100644 --- a/sepolicy/vendor/hal_power_default.te +++ b/sepolicy/vendor/hal_power_default.te @@ -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; diff --git a/sepolicy/vendor/perfd.te b/sepolicy/vendor/perfd.te index fa99d156..950e1d65 100644 --- a/sepolicy/vendor/perfd.te +++ b/sepolicy/vendor/perfd.te @@ -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;