Merge "BatteryStats: update to use new notifyWakeup with wakeup reasons" am: 6f000144cd am: 42f35b5081
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1464467 Change-Id: Ie636060b04704b07f242bb68fc934371b9beba48
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
#define LOG_TAG "BatteryStatsService"
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <climits>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
@@ -28,6 +27,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <climits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
@@ -46,15 +46,16 @@
|
||||
#include <utils/misc.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
using android::hardware::hidl_vec;
|
||||
using android::hardware::Return;
|
||||
using android::hardware::Void;
|
||||
using android::system::suspend::BnSuspendCallback;
|
||||
using android::hardware::power::stats::V1_0::IPowerStats;
|
||||
using android::hardware::power::V1_0::PowerStatePlatformSleepState;
|
||||
using android::hardware::power::V1_0::PowerStateVoter;
|
||||
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::system::suspend::BnSuspendCallback;
|
||||
using android::system::suspend::ISuspendControlService;
|
||||
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
|
||||
using IPowerV1_0 = android::hardware::power::V1_0::IPower;
|
||||
@@ -62,10 +63,9 @@ using IPowerV1_0 = android::hardware::power::V1_0::IPower;
|
||||
namespace android
|
||||
{
|
||||
|
||||
#define LAST_RESUME_REASON "/sys/kernel/wakeup_reasons/last_resume_reason"
|
||||
#define MAX_REASON_SIZE 512
|
||||
|
||||
static bool wakeup_init = false;
|
||||
static std::mutex mReasonsMutex;
|
||||
static std::vector<std::string> mWakeupReasons;
|
||||
static sem_t wakeup_sem;
|
||||
extern sp<IPowerV1_0> getPowerHalHidlV1_0();
|
||||
extern sp<IPowerV1_1> getPowerHalHidlV1_1();
|
||||
@@ -84,7 +84,8 @@ std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>>
|
||||
gPowerStatsHalStateNames = {};
|
||||
std::vector<uint32_t> gPowerStatsHalPlatformIds = {};
|
||||
std::vector<uint32_t> gPowerStatsHalSubsystemIds = {};
|
||||
sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHalV1_0 = nullptr;
|
||||
sp<IPowerStats> gPowerStatsHalV1_0 = nullptr;
|
||||
|
||||
std::function<void(JNIEnv*, jobject)> gGetLowPowerStatsImpl = {};
|
||||
std::function<jint(JNIEnv*, jobject)> gGetPlatformLowPowerStatsImpl = {};
|
||||
std::function<jint(JNIEnv*, jobject)> gGetSubsystemLowPowerStatsImpl = {};
|
||||
@@ -115,9 +116,25 @@ struct PowerHalDeathRecipient : virtual public hardware::hidl_death_recipient {
|
||||
sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient();
|
||||
|
||||
class WakeupCallback : public BnSuspendCallback {
|
||||
public:
|
||||
binder::Status notifyWakeup(bool success) override {
|
||||
public:
|
||||
binder::Status notifyWakeup(bool success,
|
||||
const std::vector<std::string>& wakeupReasons) override {
|
||||
ALOGI("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
|
||||
bool reasonsCaptured = false;
|
||||
{
|
||||
std::unique_lock<std::mutex> reasonsLock(mReasonsMutex, std::defer_lock);
|
||||
if (reasonsLock.try_lock() && mWakeupReasons.empty()) {
|
||||
mWakeupReasons = std::move(wakeupReasons);
|
||||
reasonsCaptured = true;
|
||||
}
|
||||
}
|
||||
if (!reasonsCaptured) {
|
||||
ALOGE("Failed to write wakeup reasons. Reasons dropped:");
|
||||
for (auto wakeupReason : wakeupReasons) {
|
||||
ALOGE("\t%s", wakeupReason.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int ret = sem_post(&wakeup_sem);
|
||||
if (ret < 0) {
|
||||
char buf[80];
|
||||
@@ -157,8 +174,6 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
|
||||
|
||||
// Wait for wakeup.
|
||||
ALOGV("Waiting for wakeup...");
|
||||
// TODO(b/116747600): device can suspend and wakeup after sem_wait() finishes and before wakeup
|
||||
// reason is recorded, i.e. BatteryStats might occasionally miss wakeup events.
|
||||
int ret = sem_wait(&wakeup_sem);
|
||||
if (ret < 0) {
|
||||
char buf[80];
|
||||
@@ -168,20 +183,27 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(LAST_RESUME_REASON, "r");
|
||||
if (fp == NULL) {
|
||||
ALOGE("Failed to open %s", LAST_RESUME_REASON);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* mergedreason = (char*)env->GetDirectBufferAddress(outBuf);
|
||||
int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf);
|
||||
|
||||
ALOGV("Reading wakeup reasons");
|
||||
std::vector<std::string> wakeupReasons;
|
||||
{
|
||||
std::unique_lock<std::mutex> reasonsLock(mReasonsMutex, std::defer_lock);
|
||||
if (reasonsLock.try_lock() && !mWakeupReasons.empty()) {
|
||||
wakeupReasons = std::move(mWakeupReasons);
|
||||
mWakeupReasons.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (wakeupReasons.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* mergedreasonpos = mergedreason;
|
||||
char reasonline[128];
|
||||
int i = 0;
|
||||
while (fgets(reasonline, sizeof(reasonline), fp) != NULL) {
|
||||
for (auto wakeupReason : wakeupReasons) {
|
||||
auto reasonline = const_cast<char*>(wakeupReason.c_str());
|
||||
char* pos = reasonline;
|
||||
char* endPos;
|
||||
int len;
|
||||
@@ -238,10 +260,6 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
|
||||
*mergedreasonpos = 0;
|
||||
}
|
||||
|
||||
if (fclose(fp) != 0) {
|
||||
ALOGE("Failed to close %s", LAST_RESUME_REASON);
|
||||
return -1;
|
||||
}
|
||||
return mergedreasonpos - mergedreason;
|
||||
}
|
||||
|
||||
@@ -340,7 +358,7 @@ static bool initializePowerStats() {
|
||||
// The caller must be holding gPowerHalMutex.
|
||||
static bool getPowerStatsHalLocked() {
|
||||
if (gPowerStatsHalV1_0 == nullptr) {
|
||||
gPowerStatsHalV1_0 = android::hardware::power::stats::V1_0::IPowerStats::getService();
|
||||
gPowerStatsHalV1_0 = IPowerStats::getService();
|
||||
if (gPowerStatsHalV1_0 == nullptr) {
|
||||
ALOGE("Unable to get power.stats HAL service.");
|
||||
return false;
|
||||
@@ -833,7 +851,7 @@ static jint getPowerHalSubsystemData(JNIEnv* env, jobject outBuf) {
|
||||
static void setUpPowerStatsLocked() {
|
||||
// First see if power.stats HAL is available. Fall back to power HAL if
|
||||
// power.stats HAL is unavailable.
|
||||
if (android::hardware::power::stats::V1_0::IPowerStats::getService() != nullptr) {
|
||||
if (IPowerStats::getService() != nullptr) {
|
||||
ALOGI("Using power.stats HAL");
|
||||
gGetLowPowerStatsImpl = getPowerStatsHalLowPowerData;
|
||||
gGetPlatformLowPowerStatsImpl = getPowerStatsHalPlatformData;
|
||||
|
||||
Reference in New Issue
Block a user