BatteryStats: update to use new notifyWakeup with wakeup reasons
As SystemSuspend support notifyWakeup callback with wakeup reason embedded, BatteryStats no longer required to pull such reasons from kernel files by itself. Test: adb shell dumpsys batterystats --history Bug: 171021049 Change-Id: I69717387586994b744297f5ac0f5b66ef2bdce32
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