Loading services/core/jni/com_android_server_am_BatteryStatsService.cpp +43 −25 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #define LOG_TAG "BatteryStatsService" //#define LOG_NDEBUG 0 #include <climits> #include <errno.h> #include <fcntl.h> #include <inttypes.h> Loading @@ -28,6 +27,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <climits> #include <unordered_map> #include <utility> Loading @@ -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; Loading @@ -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(); Loading @@ -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 = {}; Loading Loading @@ -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]; Loading Loading @@ -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]; Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading
services/core/jni/com_android_server_am_BatteryStatsService.cpp +43 −25 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #define LOG_TAG "BatteryStatsService" //#define LOG_NDEBUG 0 #include <climits> #include <errno.h> #include <fcntl.h> #include <inttypes.h> Loading @@ -28,6 +27,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <climits> #include <unordered_map> #include <utility> Loading @@ -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; Loading @@ -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(); Loading @@ -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 = {}; Loading Loading @@ -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]; Loading Loading @@ -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]; Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; Loading