diff options
| -rw-r--r-- | services/core/jni/com_android_server_am_BatteryStatsService.cpp | 91 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_power_PowerManagerService.cpp | 77 |
2 files changed, 100 insertions, 68 deletions
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index ec36df1d9a12..57bb9fedc135 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -57,6 +57,8 @@ namespace android static bool wakeup_init = false; static sem_t wakeup_sem; extern sp<IPower> gPowerHal; +extern std::mutex gPowerHalMutex; +extern bool getPowerHal(); static void wakeup_callback(bool success) { @@ -191,41 +193,26 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o return -1; } - if (gPowerHal == nullptr) { - ALOGE("gPowerHal not loaded"); - return -1; - } + { + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (!getPowerHal()) { + ALOGE("Power Hal not loaded"); + return -1; + } - gPowerHal->getPlatformLowPowerStats( - [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states, - Status status) { - if (status != Status::SUCCESS) - return; - for (size_t i = 0; i < states.size(); i++) { - int added; - const PowerStatePlatformSleepState& state = states[i]; - - added = snprintf(offset, remaining, - "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", - i + 1, state.name.c_str(), state.residencyInMsecSinceBoot, - state.totalTransitions); - if (added < 0) { - break; - } - if (added > remaining) { - added = remaining; - } - offset += added; - remaining -= added; - total_added += added; + Return<void> ret = gPowerHal->getPlatformLowPowerStats( + [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states, + Status status) { + if (status != Status::SUCCESS) + return; + for (size_t i = 0; i < states.size(); i++) { + int added; + const PowerStatePlatformSleepState& state = states[i]; - for (size_t j = 0; j < state.voters.size(); j++) { - const PowerStateVoter& voter = state.voters[j]; added = snprintf(offset, remaining, - "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", - j + 1, voter.name.c_str(), - voter.totalTimeInMsecVotedForSinceBoot, - voter.totalNumberOfTimesVotedSinceBoot); + "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", + i + 1, state.name.c_str(), state.residencyInMsecSinceBoot, + state.totalTransitions); if (added < 0) { break; } @@ -235,18 +222,42 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o offset += added; remaining -= added; total_added += added; - } - if (remaining <= 0) { - /* rewrite NULL character*/ - offset--; - total_added--; - ALOGE("PowerHal: buffer not enough"); - break; + for (size_t j = 0; j < state.voters.size(); j++) { + const PowerStateVoter& voter = state.voters[j]; + added = snprintf(offset, remaining, + "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", + j + 1, voter.name.c_str(), + voter.totalTimeInMsecVotedForSinceBoot, + voter.totalNumberOfTimesVotedSinceBoot); + if (added < 0) { + break; + } + if (added > remaining) { + added = remaining; + } + offset += added; + remaining -= added; + total_added += added; + } + + if (remaining <= 0) { + /* rewrite NULL character*/ + offset--; + total_added--; + ALOGE("PowerHal: buffer not enough"); + break; + } } } + ); + + if (!ret.isOk()) { + ALOGE("getPlatformLowPowerStats() failed: power HAL service not available"); + gPowerHal = nullptr; + return -1; } - ); + } *offset = 0; total_added += 1; return total_added; diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp index fab309bfb148..1bdcd7aa9bd6 100644 --- a/services/core/jni/com_android_server_power_PowerManagerService.cpp +++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp @@ -43,7 +43,7 @@ using android::hardware::Void; using android::hardware::power::V1_0::IPower; using android::hardware::power::V1_0::PowerHint; using android::hardware::power::V1_0::Feature; -using android::hardware::hidl_vec; +using android::String8; namespace android { @@ -56,7 +56,8 @@ static struct { // ---------------------------------------------------------------------------- static jobject gPowerManagerServiceObj; -sp<IPower> gPowerHal; +sp<IPower> gPowerHal = nullptr; +std::mutex gPowerHalMutex; static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1]; // Throttling interval for user activity calls. @@ -74,11 +75,37 @@ static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa return false; } +// Check validity of current handle to the power HAL service, and call getService() if necessary. +// The caller must be holding gPowerHalMutex. +bool getPowerHal() { + if (gPowerHal == nullptr) { + gPowerHal = IPower::getService(); + if (gPowerHal != nullptr) { + ALOGI("Loaded power HAL service"); + } else { + ALOGI("Couldn't load power HAL service"); + } + } + return gPowerHal != nullptr; +} + +// Check if a call to a power HAL function failed; if so, log the failure and invalidate the +// current handle to the power HAL service. The caller must be holding gPowerHalMutex. +static void processReturn(const Return<void> &ret, const char* functionName) { + if (!ret.isOk()) { + ALOGE("%s() failed: power HAL service not available.", functionName); + gPowerHal = nullptr; + } +} + void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { // Tell the power HAL when user activity occurs. - if (gPowerHal != nullptr) { - gPowerHal->powerHint(PowerHint::INTERACTION, 0); + gPowerHalMutex.lock(); + if (getPowerHal()) { + Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0); + processReturn(ret, "powerHint"); } + gPowerHalMutex.unlock(); if (gPowerManagerServiceObj) { // Throttle calls into user activity by event type. @@ -106,14 +133,13 @@ void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t } // ---------------------------------------------------------------------------- -//TODO(b/31632518) + static void nativeInit(JNIEnv* env, jobject obj) { gPowerManagerServiceObj = env->NewGlobalRef(obj); - gPowerHal = IPower::getService(); - if (gPowerHal == nullptr) { - ALOGE("Couldn't load PowerHAL module"); - } + gPowerHalMutex.lock(); + getPowerHal(); + gPowerHalMutex.unlock(); } static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) { @@ -127,14 +153,12 @@ static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring } static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { - if (gPowerHal != nullptr) { - if (enable) { - ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on"); - gPowerHal->setInteractive(true); - } else { - ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off"); - gPowerHal->setInteractive(false); - } + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (getPowerHal()) { + String8 err("Excessive delay in setInteractive(%s) while turning screen %s"); + ALOGD_IF_SLOW(20, String8::format(err, enable ? "true" : "false", enable ? "on" : "off")); + Return<void> ret = gPowerHal->setInteractive(enable); + processReturn(ret, "setInteractive"); } } @@ -149,20 +173,18 @@ static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean } static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) { - if (gPowerHal != nullptr) { - if(data) - gPowerHal->powerHint((PowerHint)hintId, data); - else { - gPowerHal->powerHint((PowerHint)hintId, 0); - } + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (getPowerHal()) { + Return<void> ret = gPowerHal->powerHint((PowerHint)hintId, data); + processReturn(ret, "powerHint"); } } static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) { - int data_param = data; - - if (gPowerHal != nullptr) { - gPowerHal->setFeature((Feature)featureId, data_param ? true : false); + std::lock_guard<std::mutex> lock(gPowerHalMutex); + if (getPowerHal()) { + Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data)); + processReturn(ret, "setFeature"); } } @@ -217,7 +239,6 @@ int register_android_server_PowerManagerService(JNIEnv* env) { gLastEventTime[i] = LLONG_MIN; } gPowerManagerServiceObj = NULL; - gPowerHal = NULL; return 0; } |