Merge "BatteryStats: update to use new notifyWakeup with wakeup reasons"
This commit is contained in:
@@ -17,7 +17,6 @@
|
|||||||
#define LOG_TAG "BatteryStatsService"
|
#define LOG_TAG "BatteryStatsService"
|
||||||
//#define LOG_NDEBUG 0
|
//#define LOG_NDEBUG 0
|
||||||
|
|
||||||
#include <climits>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -28,6 +27,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <climits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -46,15 +46,16 @@
|
|||||||
#include <utils/misc.h>
|
#include <utils/misc.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
|
|
||||||
|
using android::hardware::hidl_vec;
|
||||||
using android::hardware::Return;
|
using android::hardware::Return;
|
||||||
using android::hardware::Void;
|
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::PowerStatePlatformSleepState;
|
||||||
using android::hardware::power::V1_0::PowerStateVoter;
|
using android::hardware::power::V1_0::PowerStateVoter;
|
||||||
using android::hardware::power::V1_0::Status;
|
using android::hardware::power::V1_0::Status;
|
||||||
using android::hardware::power::V1_1::PowerStateSubsystem;
|
using android::hardware::power::V1_1::PowerStateSubsystem;
|
||||||
using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
|
using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
|
||||||
using android::hardware::hidl_vec;
|
using android::system::suspend::BnSuspendCallback;
|
||||||
using android::system::suspend::ISuspendControlService;
|
using android::system::suspend::ISuspendControlService;
|
||||||
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
|
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
|
||||||
using IPowerV1_0 = android::hardware::power::V1_0::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
|
namespace android
|
||||||
{
|
{
|
||||||
|
|
||||||
#define LAST_RESUME_REASON "/sys/kernel/wakeup_reasons/last_resume_reason"
|
|
||||||
#define MAX_REASON_SIZE 512
|
|
||||||
|
|
||||||
static bool wakeup_init = false;
|
static bool wakeup_init = false;
|
||||||
|
static std::mutex mReasonsMutex;
|
||||||
|
static std::vector<std::string> mWakeupReasons;
|
||||||
static sem_t wakeup_sem;
|
static sem_t wakeup_sem;
|
||||||
extern sp<IPowerV1_0> getPowerHalHidlV1_0();
|
extern sp<IPowerV1_0> getPowerHalHidlV1_0();
|
||||||
extern sp<IPowerV1_1> getPowerHalHidlV1_1();
|
extern sp<IPowerV1_1> getPowerHalHidlV1_1();
|
||||||
@@ -84,7 +84,8 @@ std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>>
|
|||||||
gPowerStatsHalStateNames = {};
|
gPowerStatsHalStateNames = {};
|
||||||
std::vector<uint32_t> gPowerStatsHalPlatformIds = {};
|
std::vector<uint32_t> gPowerStatsHalPlatformIds = {};
|
||||||
std::vector<uint32_t> gPowerStatsHalSubsystemIds = {};
|
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<void(JNIEnv*, jobject)> gGetLowPowerStatsImpl = {};
|
||||||
std::function<jint(JNIEnv*, jobject)> gGetPlatformLowPowerStatsImpl = {};
|
std::function<jint(JNIEnv*, jobject)> gGetPlatformLowPowerStatsImpl = {};
|
||||||
std::function<jint(JNIEnv*, jobject)> gGetSubsystemLowPowerStatsImpl = {};
|
std::function<jint(JNIEnv*, jobject)> gGetSubsystemLowPowerStatsImpl = {};
|
||||||
@@ -115,9 +116,25 @@ struct PowerHalDeathRecipient : virtual public hardware::hidl_death_recipient {
|
|||||||
sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient();
|
sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient();
|
||||||
|
|
||||||
class WakeupCallback : public BnSuspendCallback {
|
class WakeupCallback : public BnSuspendCallback {
|
||||||
public:
|
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");
|
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);
|
int ret = sem_post(&wakeup_sem);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
char buf[80];
|
char buf[80];
|
||||||
@@ -157,8 +174,6 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
|
|||||||
|
|
||||||
// Wait for wakeup.
|
// Wait for wakeup.
|
||||||
ALOGV("Waiting 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);
|
int ret = sem_wait(&wakeup_sem);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
char buf[80];
|
char buf[80];
|
||||||
@@ -168,20 +183,27 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
|
|||||||
return 0;
|
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);
|
char* mergedreason = (char*)env->GetDirectBufferAddress(outBuf);
|
||||||
int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf);
|
int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf);
|
||||||
|
|
||||||
ALOGV("Reading wakeup reasons");
|
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* mergedreasonpos = mergedreason;
|
||||||
char reasonline[128];
|
|
||||||
int i = 0;
|
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* pos = reasonline;
|
||||||
char* endPos;
|
char* endPos;
|
||||||
int len;
|
int len;
|
||||||
@@ -238,10 +260,6 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
|
|||||||
*mergedreasonpos = 0;
|
*mergedreasonpos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fclose(fp) != 0) {
|
|
||||||
ALOGE("Failed to close %s", LAST_RESUME_REASON);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return mergedreasonpos - mergedreason;
|
return mergedreasonpos - mergedreason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +358,7 @@ static bool initializePowerStats() {
|
|||||||
// The caller must be holding gPowerHalMutex.
|
// The caller must be holding gPowerHalMutex.
|
||||||
static bool getPowerStatsHalLocked() {
|
static bool getPowerStatsHalLocked() {
|
||||||
if (gPowerStatsHalV1_0 == nullptr) {
|
if (gPowerStatsHalV1_0 == nullptr) {
|
||||||
gPowerStatsHalV1_0 = android::hardware::power::stats::V1_0::IPowerStats::getService();
|
gPowerStatsHalV1_0 = IPowerStats::getService();
|
||||||
if (gPowerStatsHalV1_0 == nullptr) {
|
if (gPowerStatsHalV1_0 == nullptr) {
|
||||||
ALOGE("Unable to get power.stats HAL service.");
|
ALOGE("Unable to get power.stats HAL service.");
|
||||||
return false;
|
return false;
|
||||||
@@ -833,7 +851,7 @@ static jint getPowerHalSubsystemData(JNIEnv* env, jobject outBuf) {
|
|||||||
static void setUpPowerStatsLocked() {
|
static void setUpPowerStatsLocked() {
|
||||||
// First see if power.stats HAL is available. Fall back to power HAL if
|
// First see if power.stats HAL is available. Fall back to power HAL if
|
||||||
// power.stats HAL is unavailable.
|
// power.stats HAL is unavailable.
|
||||||
if (android::hardware::power::stats::V1_0::IPowerStats::getService() != nullptr) {
|
if (IPowerStats::getService() != nullptr) {
|
||||||
ALOGI("Using power.stats HAL");
|
ALOGI("Using power.stats HAL");
|
||||||
gGetLowPowerStatsImpl = getPowerStatsHalLowPowerData;
|
gGetLowPowerStatsImpl = getPowerStatsHalLowPowerData;
|
||||||
gGetPlatformLowPowerStatsImpl = getPowerStatsHalPlatformData;
|
gGetPlatformLowPowerStatsImpl = getPowerStatsHalPlatformData;
|
||||||
|
|||||||
Reference in New Issue
Block a user