mirror of
https://github.com/Evolution-X-Devices/device_google_wahoo
synced 2026-02-01 07:50:47 +00:00
While snapshot Easel power data is captured in bugreports via dumpstate, Easel does not provide low power stats on a recurring basis via PowerHAL, which is the type of data need to detect the presence and scope of power drain issues in the field. As a temporary workaround, this set of changes keeps cumulative counts of the number of times PowerHAL saw Easel's state (an existing sysfs node) as "on" (state 1) or "not on" (state 0 or 2), and logs the "on" count as cumulative count and the "not on" count as cumulative duration. This does not sufficiently address the long term need for cumulative stats, since this will just be comprised of essentially random snapshots of Easel's current state. However, for the known issue already being investigated, this should be enough to gauge the scope of the issue. sepolicy updates allow hal_power to search/read the directory/file containing Easel's current state: /sys/devices/virtual/misc/mnh_sm/state Bug: 77208137 Bug: 36576572 Test: Installed on taimen, used camera for various functions, used easel debug commands and properties to force it into different states, captured a bugreport and verified the content against observed "current state" values from monitoring the state file while performing similar camera functions. Change-Id: Ib1ee92db477d2a6c9d6f293fb4fcc2f753b8335a
543 lines
21 KiB
C++
543 lines
21 KiB
C++
/*
|
|
* 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.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 <android-base/stringprintf.h>
|
|
|
|
#include <mutex>
|
|
|
|
#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 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();
|
|
|
|
std::string state = android::base::GetProperty(kPowerHalStateProp, "");
|
|
if (state == "VIDEO_ENCODE") {
|
|
ALOGI("Initialize with VIDEO_ENCODE on");
|
|
mHintManager->DoHint("VIDEO_ENCODE");
|
|
mEncoderModeOn = 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 == "LOW_LATENCY") {
|
|
ALOGI("Initialize with AUDIO_LOW_LATENCY on");
|
|
mHintManager->DoHint("AUDIO_LOW_LATENCY");
|
|
}
|
|
}
|
|
|
|
// 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__);
|
|
break;
|
|
}
|
|
ATRACE_BEGIN("video_encode");
|
|
if (mVRModeOn || mSustainedPerfModeOn) {
|
|
ALOGV("%s: ignoring due to other active perf hints", __func__);
|
|
} else {
|
|
if (data) {
|
|
// Hint until canceled
|
|
ATRACE_INT("video_encode_lock", 1);
|
|
mHintManager->DoHint("VIDEO_ENCODE");
|
|
ALOGD("VIDEO_ENCODE ON");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "VIDEO_ENCODE")) {
|
|
ALOGE("%s: could not set powerHAL state property to VIDEO_ENCODE", __func__);
|
|
}
|
|
mEncoderModeOn = true;
|
|
} else {
|
|
ATRACE_INT("video_encode_lock", 0);
|
|
mHintManager->EndHint("VIDEO_ENCODE");
|
|
ALOGD("VIDEO_ENCODE OFF");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "")) {
|
|
ALOGE("%s: could not clear powerHAL state property", __func__);
|
|
}
|
|
mEncoderModeOn = false;
|
|
}
|
|
}
|
|
ATRACE_END();
|
|
break;
|
|
case PowerHint_1_0::SUSTAINED_PERFORMANCE:
|
|
if (data && !mSustainedPerfModeOn) {
|
|
ALOGD("SUSTAINED_PERFORMANCE ON");
|
|
if (!mVRModeOn) { // Sustained mode only.
|
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "SUSTAINED_PERFORMANCE")) {
|
|
ALOGE("%s: could not set powerHAL state property to SUSTAINED_PERFORMANCE", __func__);
|
|
}
|
|
} else { // Sustained + VR mode.
|
|
mHintManager->EndHint("VR_MODE");
|
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "VR_SUSTAINED_PERFORMANCE")) {
|
|
ALOGE("%s: could not set powerHAL state property to VR_SUSTAINED_PERFORMANCE", __func__);
|
|
}
|
|
}
|
|
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");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "VR_MODE")) {
|
|
ALOGE("%s: could not set powerHAL state property to VR_MODE", __func__);
|
|
}
|
|
} else {
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "")) {
|
|
ALOGE("%s: could not clear powerHAL state property", __func__);
|
|
}
|
|
}
|
|
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");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "VR_MODE")) {
|
|
ALOGE("%s: could not set powerHAL state property to VR_MODE", __func__);
|
|
}
|
|
} else { // Sustained + VR mode.
|
|
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "VR_SUSTAINED_PERFORMANCE")) {
|
|
ALOGE("%s: could not set powerHAL state property to VR_SUSTAINED_PERFORMANCE", __func__);
|
|
}
|
|
}
|
|
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");
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "SUSTAINED_PERFORMANCE")) {
|
|
ALOGE("%s: could not set powerHAL state property to SUSTAINED_PERFORMANCE", __func__);
|
|
}
|
|
} else {
|
|
if (!android::base::SetProperty(kPowerHalStateProp, "")) {
|
|
ALOGE("%s: could not clear powerHAL state property", __func__);
|
|
}
|
|
}
|
|
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[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;
|
|
|
|
subsystem->name = "wlan";
|
|
|
|
if (extract_wlan_stats(stats) != 0) {
|
|
subsystem->states.resize(0);
|
|
return -1;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
enum easel_state {
|
|
EASEL_OFF = 0,
|
|
EASEL_ON,
|
|
EASEL_SUSPENDED,
|
|
NUM_EASEL_STATES
|
|
};
|
|
|
|
// Get low power stats for easel subsystem
|
|
static int get_easel_low_power_stats(struct PowerStateSubsystem *subsystem) {
|
|
// This implementation is a workaround to provide minimal visibility into
|
|
// Easel state behavior until canonical low power stats are supported.
|
|
// It takes an "external observer" snapshot of the current Easel state every
|
|
// time it is called, and synthesizes an artificial sleep state that will
|
|
// behave similarly to real stats if Easel gets "wedged" in the "on" state.
|
|
static std::mutex statsLock;
|
|
static uint64_t totalOnSnapshotCount = 0;
|
|
static uint64_t totalNotOnSnapshotCount = 0;
|
|
unsigned long currentState;
|
|
struct PowerStateSubsystemSleepState *state;
|
|
|
|
subsystem->name = "Easel";
|
|
|
|
if (get_easel_state(¤tState) != 0) {
|
|
subsystem->states.resize(0);
|
|
return -1;
|
|
}
|
|
|
|
if (currentState >= NUM_EASEL_STATES) {
|
|
ALOGE("%s: unrecognized Easel state(%lu)", __func__, currentState);
|
|
return -1;
|
|
}
|
|
|
|
subsystem->states.resize(1);
|
|
|
|
// Since we are storing stats locally but can have multiple parallel
|
|
// callers, locking is required to ensure stats are not corrupted.
|
|
std::lock_guard<std::mutex> lk(statsLock);
|
|
|
|
// Update statistics for synthetic sleep state. We combine OFF and
|
|
// SUSPENDED to act as a composite "not on" state so the numbers will behave
|
|
// like a real sleep state.
|
|
if ((currentState == EASEL_OFF) || (currentState == EASEL_SUSPENDED)) {
|
|
totalNotOnSnapshotCount++;
|
|
} else {
|
|
totalOnSnapshotCount++;
|
|
}
|
|
|
|
// Update statistics for synthetic sleep state, where
|
|
// totalTransitions = cumulative count of Easel state0 (as seen by PowerHAL)
|
|
// residencyInMsecsSinceBoot = cumulative count of Easel state1 (as seen by
|
|
// PowerHAL)
|
|
// lastEntryTimestampMs = cumulative count of Easel state2 (as seen by
|
|
// PowerHAL)
|
|
state = &subsystem->states[0];
|
|
state->name = "SyntheticSleep";
|
|
state->totalTransitions = totalOnSnapshotCount;
|
|
state->residencyInMsecSinceBoot = totalNotOnSnapshotCount;
|
|
state->lastEntryTimestampMs = 0; // No added value for the workaround
|
|
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(SUBSYSTEM_COUNT);
|
|
|
|
// Get WLAN subsystem low power stats.
|
|
if (get_wlan_low_power_stats(&subsystems[SUBSYSTEM_WLAN]) != 0) {
|
|
ALOGE("%s: failed to process wlan stats", __func__);
|
|
}
|
|
|
|
// Get Easel subsystem low power stats.
|
|
if (get_easel_low_power_stats(&subsystems[SUBSYSTEM_EASEL]) != 0) {
|
|
ALOGE("%s: failed to process Easel 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()) {
|
|
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");
|
|
if (!android::base::SetProperty(kPowerHalAudioProp, "LOW_LATENCY")) {
|
|
ALOGE("%s: could not set powerHAL audio state property to LOW_LATENCY", __func__);
|
|
}
|
|
} else {
|
|
ATRACE_INT("audio_low_latency_lock", 0);
|
|
mHintManager->EndHint("AUDIO_LOW_LATENCY");
|
|
ALOGD("AUDIO LOW LATENCY OFF");
|
|
if (!android::base::SetProperty(kPowerHalAudioProp, "")) {
|
|
ALOGE("%s: could not clear powerHAL audio state property", __func__);
|
|
}
|
|
}
|
|
ATRACE_END();
|
|
break;
|
|
case PowerHint_1_2::AUDIO_STREAMING:
|
|
ATRACE_BEGIN("audio_streaming");
|
|
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", std::chrono::milliseconds(data));
|
|
ALOGD("CAMERA STREAMING ON: %d MS", data);
|
|
} else if (data == 0) {
|
|
ATRACE_INT("camera_streaming_lock", 0);
|
|
mHintManager->EndHint("CAMERA_STREAMING");
|
|
ALOGD("CAMERA STREAMING OFF");
|
|
} 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();
|
|
}
|
|
|
|
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) {
|
|
int fd = handle->data[0];
|
|
|
|
std::string buf(android::base::StringPrintf("HintManager Running: %s\n"
|
|
"VRMode: %s\n"
|
|
"SustainedPerformanceMode: %s\n"
|
|
"VideoEncodeMode: %s\n",
|
|
boolToString(mHintManager->IsRunning()),
|
|
boolToString(mVRModeOn),
|
|
boolToString(mSustainedPerfModeOn),
|
|
boolToString(mEncoderModeOn)));
|
|
// 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_2
|
|
} // namespace power
|
|
} // namespace hardware
|
|
} // namespace android
|