diff options
| author | 2020-10-27 21:10:06 +0000 | |
|---|---|---|
| committer | 2020-10-27 21:10:06 +0000 | |
| commit | 42f35b508150b91a9632c2cb3f9928dddd2eef07 (patch) | |
| tree | 535cd72ee0e90502570e964555c065b2eeffad76 | |
| parent | ed29b2da3c2da537384777220eae1ec9f2f6855d (diff) | |
| parent | 6f000144cd4613e7f09e8f85046bb1634252a582 (diff) | |
Merge "BatteryStats: update to use new notifyWakeup with wakeup reasons" am: 6f000144cd
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1464467
Change-Id: I4c49a8986be837fad68c3893d6a901c00a19998d
| -rw-r--r-- | services/core/jni/com_android_server_am_BatteryStatsService.cpp | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index b08868e2c7f8..0e68f5b89a91 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -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; |