Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bf1e464 authored by Michael Sun's avatar Michael Sun Committed by Automerger Merge Worker
Browse files

Merge "BatteryStats: update to use new notifyWakeup with wakeup reasons" am:...

Merge "BatteryStats: update to use new notifyWakeup with wakeup reasons" am: 6f000144 am: 42f35b50

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1464467

Change-Id: Ie636060b04704b07f242bb68fc934371b9beba48
parents 0c6faf40 42f35b50
Loading
Loading
Loading
Loading
+43 −25
Original line number Diff line number Diff line
@@ -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 = {};
@@ -116,8 +117,24 @@ sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient();

class WakeupCallback : public BnSuspendCallback {
public:
    binder::Status notifyWakeup(bool success) override {
    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;