Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 861a0f91 authored by Connor O'Brien's avatar Connor O'Brien Committed by Android (Google) Code Review
Browse files

Merge "Recover cleanly from power HAL service crashes"

parents 231cf099 578eb7fe
Loading
Loading
Loading
Loading
+51 −40
Original line number Diff line number Diff line
@@ -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,12 +193,14 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o
        return -1;
    }

    if (gPowerHal == nullptr) {
        ALOGE("gPowerHal not loaded");
    {
        std::lock_guard<std::mutex> lock(gPowerHalMutex);
        if (!getPowerHal()) {
            ALOGE("Power Hal not loaded");
            return -1;
        }

    gPowerHal->getPlatformLowPowerStats(
        Return<void> ret = gPowerHal->getPlatformLowPowerStats(
            [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
                    Status status) {
                if (status != Status::SUCCESS)
@@ -247,6 +251,13 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o
                }
            }
        );

        if (!ret.isOk()) {
            ALOGE("getPlatformLowPowerStats() failed: power HAL service not available");
            gPowerHal = nullptr;
            return -1;
        }
    }
    *offset = 0;
    total_added += 1;
    return total_added;
+49 −28
Original line number Diff line number Diff line
@@ -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;
}