Power: add support for devices without display idle signals
To workaround b/141025174, adding support for devices without display idle signals. Also added a property to override idle display function. Besides the idle signal support, this CL also makes touch boost duration tunable through several new vendor properties. It also named display idle monitor thread and cleans out the obsolete HIDL Power HAL implementation. Bug: 168080943 Bug: 169065024 Bug: 171494137 Test: Boot and trace Change-Id: I76067d10958654d539624ec4cac8f346103e67bc
This commit is contained in:
parent
4ae5975c9a
commit
b51c3e681f
@ -17,30 +17,59 @@
|
|||||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||||
#define LOG_TAG "android.hardware.power-service.xiaomi-libperfmgr"
|
#define LOG_TAG "android.hardware.power-service.xiaomi-libperfmgr"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <android-base/properties.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
#include <utils/Trace.h>
|
#include <utils/Trace.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "InteractionHandler.h"
|
#include "InteractionHandler.h"
|
||||||
|
|
||||||
#define MAX_LENGTH 64
|
#define MAX_LENGTH 64
|
||||||
|
|
||||||
#define MSINSEC 1000L
|
#define MSINSEC 1000L
|
||||||
#define USINMS 1000000L
|
#define NSINMS 1000000L
|
||||||
|
|
||||||
static const std::vector<std::string> fb_idle_path = {"/sys/class/drm/card0/device/idle_state",
|
namespace aidl {
|
||||||
"/sys/class/graphics/fb0/idle_state"};
|
namespace google {
|
||||||
|
namespace hardware {
|
||||||
|
namespace power {
|
||||||
|
namespace impl {
|
||||||
|
namespace pixel {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static const bool kDisplayIdleSupport =
|
||||||
|
::android::base::GetBoolProperty("vendor.powerhal.disp.idle_support", true);
|
||||||
|
static const std::array<const char *, 2> kDispIdlePath = {"/sys/class/drm/card0/device/idle_state",
|
||||||
|
"/sys/class/graphics/fb0/idle_state"};
|
||||||
|
static const uint32_t kWaitMs =
|
||||||
|
::android::base::GetUintProperty("vendor.powerhal.disp.idle_wait", /*default*/ 100U);
|
||||||
|
static const uint32_t kMinDurationMs =
|
||||||
|
::android::base::GetUintProperty("vendor.powerhal.interaction.min", /*default*/ 1400U);
|
||||||
|
static const uint32_t kMaxDurationMs =
|
||||||
|
::android::base::GetUintProperty("vendor.powerhal.interaction.max", /*default*/ 5650U);
|
||||||
|
static const uint32_t kDurationOffsetMs =
|
||||||
|
::android::base::GetUintProperty("vendor.powerhal.interaction.offset", /*default*/ 650U);
|
||||||
|
|
||||||
|
static size_t CalcTimespecDiffMs(struct timespec start, struct timespec end) {
|
||||||
|
size_t diff_in_ms = 0;
|
||||||
|
diff_in_ms += (end.tv_sec - start.tv_sec) * MSINSEC;
|
||||||
|
diff_in_ms += (end.tv_nsec - start.tv_nsec) / NSINMS;
|
||||||
|
return diff_in_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const &hint_manager)
|
InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const &hint_manager)
|
||||||
: mState(INTERACTION_STATE_UNINITIALIZED),
|
: mState(INTERACTION_STATE_UNINITIALIZED),
|
||||||
mWaitMs(100),
|
|
||||||
mMinDurationMs(1400),
|
|
||||||
mMaxDurationMs(5650),
|
|
||||||
mDurationMs(0),
|
mDurationMs(0),
|
||||||
mHintManager(hint_manager) {}
|
mHintManager(hint_manager) {}
|
||||||
|
|
||||||
@ -50,8 +79,8 @@ InteractionHandler::~InteractionHandler() {
|
|||||||
|
|
||||||
static int fb_idle_open(void) {
|
static int fb_idle_open(void) {
|
||||||
int fd;
|
int fd;
|
||||||
for (auto &path : fb_idle_path) {
|
for (const auto &path : kDispIdlePath) {
|
||||||
fd = open(path.c_str(), O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -115,30 +144,27 @@ void InteractionHandler::PerfRel() {
|
|||||||
ATRACE_INT("interaction_lock", 0);
|
ATRACE_INT("interaction_lock", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start, struct timespec end) {
|
|
||||||
size_t diff_in_us = 0;
|
|
||||||
diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC;
|
|
||||||
diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS;
|
|
||||||
return diff_in_us;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InteractionHandler::Acquire(int32_t duration) {
|
void InteractionHandler::Acquire(int32_t duration) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(mLock);
|
std::lock_guard<std::mutex> lk(mLock);
|
||||||
if (mState == INTERACTION_STATE_UNINITIALIZED) {
|
|
||||||
ALOGW("%s: called while uninitialized", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int inputDuration = duration + 650;
|
int inputDuration = duration + kDurationOffsetMs;
|
||||||
int finalDuration;
|
int finalDuration;
|
||||||
if (inputDuration > mMaxDurationMs)
|
if (inputDuration > kMaxDurationMs)
|
||||||
finalDuration = mMaxDurationMs;
|
finalDuration = kMaxDurationMs;
|
||||||
else if (inputDuration > mMinDurationMs)
|
else if (inputDuration > kMinDurationMs)
|
||||||
finalDuration = inputDuration;
|
finalDuration = inputDuration;
|
||||||
else
|
else
|
||||||
finalDuration = mMinDurationMs;
|
finalDuration = kMinDurationMs;
|
||||||
|
|
||||||
|
// Fallback to do boost directly
|
||||||
|
// 1) override property is set OR
|
||||||
|
// 2) InteractionHandler not initialized
|
||||||
|
if (!kDisplayIdleSupport || mState == INTERACTION_STATE_UNINITIALIZED) {
|
||||||
|
mHintManager->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct timespec cur_timespec;
|
struct timespec cur_timespec;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
|
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
|
||||||
@ -235,6 +261,7 @@ void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::Routine() {
|
void InteractionHandler::Routine() {
|
||||||
|
pthread_setname_np(pthread_self(), "DisplayIdleMonitor");
|
||||||
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
|
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -245,7 +272,14 @@ void InteractionHandler::Routine() {
|
|||||||
mState = INTERACTION_STATE_WAITING;
|
mState = INTERACTION_STATE_WAITING;
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
|
|
||||||
WaitForIdle(mWaitMs, mDurationMs);
|
WaitForIdle(kWaitMs, mDurationMs);
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace pixel
|
||||||
|
} // namespace impl
|
||||||
|
} // namespace power
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace google
|
||||||
|
} // namespace aidl
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
#pragma once
|
||||||
#define POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -25,9 +24,16 @@
|
|||||||
|
|
||||||
#include <perfmgr/HintManager.h>
|
#include <perfmgr/HintManager.h>
|
||||||
|
|
||||||
|
namespace aidl {
|
||||||
|
namespace google {
|
||||||
|
namespace hardware {
|
||||||
|
namespace power {
|
||||||
|
namespace impl {
|
||||||
|
namespace pixel {
|
||||||
|
|
||||||
using ::android::perfmgr::HintManager;
|
using ::android::perfmgr::HintManager;
|
||||||
|
|
||||||
enum interaction_state {
|
enum InteractionState {
|
||||||
INTERACTION_STATE_UNINITIALIZED,
|
INTERACTION_STATE_UNINITIALIZED,
|
||||||
INTERACTION_STATE_IDLE,
|
INTERACTION_STATE_IDLE,
|
||||||
INTERACTION_STATE_INTERACTION,
|
INTERACTION_STATE_INTERACTION,
|
||||||
@ -51,24 +57,20 @@ class InteractionHandler {
|
|||||||
void PerfLock();
|
void PerfLock();
|
||||||
void PerfRel();
|
void PerfRel();
|
||||||
|
|
||||||
size_t CalcTimespecDiffMs(struct timespec start, struct timespec end);
|
enum InteractionState mState;
|
||||||
|
|
||||||
enum interaction_state mState;
|
|
||||||
|
|
||||||
int mIdleFd;
|
int mIdleFd;
|
||||||
int mEventFd;
|
int mEventFd;
|
||||||
|
|
||||||
int32_t mWaitMs;
|
|
||||||
int32_t mMinDurationMs;
|
|
||||||
int32_t mMaxDurationMs;
|
|
||||||
int32_t mDurationMs;
|
int32_t mDurationMs;
|
||||||
|
|
||||||
struct timespec mLastTimespec;
|
struct timespec mLastTimespec;
|
||||||
|
|
||||||
std::unique_ptr<std::thread> mThread;
|
std::unique_ptr<std::thread> mThread;
|
||||||
std::mutex mLock;
|
std::mutex mLock;
|
||||||
std::condition_variable mCond;
|
std::condition_variable mCond;
|
||||||
std::shared_ptr<HintManager> mHintManager;
|
std::shared_ptr<HintManager> mHintManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
} // namespace pixel
|
||||||
|
} // namespace impl
|
||||||
|
} // namespace power
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace google
|
||||||
|
} // namespace aidl
|
||||||
|
@ -32,7 +32,6 @@ namespace power {
|
|||||||
namespace impl {
|
namespace impl {
|
||||||
namespace pixel {
|
namespace pixel {
|
||||||
|
|
||||||
using ::InteractionHandler;
|
|
||||||
using ::aidl::android::hardware::power::Boost;
|
using ::aidl::android::hardware::power::Boost;
|
||||||
using ::aidl::android::hardware::power::Mode;
|
using ::aidl::android::hardware::power::Mode;
|
||||||
using ::android::perfmgr::HintManager;
|
using ::android::perfmgr::HintManager;
|
||||||
|
Loading…
Reference in New Issue
Block a user