summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michael Sun <michaelfsun@google.com> 2020-10-27 21:10:06 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2020-10-27 21:10:06 +0000
commit42f35b508150b91a9632c2cb3f9928dddd2eef07 (patch)
tree535cd72ee0e90502570e964555c065b2eeffad76
parented29b2da3c2da537384777220eae1ec9f2f6855d (diff)
parent6f000144cd4613e7f09e8f85046bb1634252a582 (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.cpp68
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;