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

Commit d0f23c6a authored by Lais Andrade's avatar Lais Andrade Committed by Android (Google) Code Review
Browse files

Merge "Use PowerHalController in PowerManagerService"

parents 5b172215 12375902
Loading
Loading
Loading
Loading
+37 −260
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@
#include "jni.h"

#include <nativehelper/ScopedUtfChars.h>
#include <powermanager/PowerHalController.h>
#include <powermanager/PowerHalLoader.h>

#include <limits.h>

@@ -46,8 +48,6 @@

#include "com_android_server_power_PowerManagerService.h"

using android::hardware::Return;
using android::hardware::Void;
using android::hardware::power::Boost;
using android::hardware::power::Mode;
using android::hardware::power::V1_0::PowerHint;
@@ -72,18 +72,7 @@ static struct {
// ----------------------------------------------------------------------------

static jobject gPowerManagerServiceObj;
static sp<IPowerV1_0> gPowerHalHidlV1_0_ = nullptr;
static sp<IPowerV1_1> gPowerHalHidlV1_1_ = nullptr;
static sp<IPowerAidl> gPowerHalAidl_ = nullptr;
static std::mutex gPowerHalMutex;

enum class HalVersion {
    NONE,
    HIDL_1_0,
    HIDL_1_1,
    AIDL,
};

static PowerHalController gPowerHalController;
static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];

// Throttling interval for user activity calls.
@@ -101,206 +90,36 @@ static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa
    return false;
}

// Check validity of current handle to the power HAL service, and connect to it if necessary.
// The caller must be holding gPowerHalMutex.
static HalVersion connectPowerHalLocked() {
    static bool gPowerHalHidlExists = true;
    static bool gPowerHalAidlExists = true;
    if (!gPowerHalHidlExists && !gPowerHalAidlExists) {
        return HalVersion::NONE;
    }
    if (gPowerHalAidlExists) {
        if (!gPowerHalAidl_) {
            gPowerHalAidl_ = waitForVintfService<IPowerAidl>();
        }
        if (gPowerHalAidl_) {
            ALOGV("Successfully connected to Power HAL AIDL service.");
            return HalVersion::AIDL;
        } else {
            gPowerHalAidlExists = false;
        }
    }
    if (gPowerHalHidlExists && gPowerHalHidlV1_0_ == nullptr) {
        gPowerHalHidlV1_0_ = IPowerV1_0::getService();
        if (gPowerHalHidlV1_0_) {
            ALOGV("Successfully connected to Power HAL HIDL 1.0 service.");
            // Try cast to powerHAL HIDL V1_1
            gPowerHalHidlV1_1_ = IPowerV1_1::castFrom(gPowerHalHidlV1_0_);
            if (gPowerHalHidlV1_1_) {
                ALOGV("Successfully connected to Power HAL HIDL 1.1 service.");
            }
        } else {
            ALOGV("Couldn't load power HAL HIDL service");
            gPowerHalHidlExists = false;
            return HalVersion::NONE;
        }
    }
    if (gPowerHalHidlV1_1_) {
        return HalVersion::HIDL_1_1;
    } else if (gPowerHalHidlV1_0_) {
        return HalVersion::HIDL_1_0;
    }
    return HalVersion::NONE;
}

// 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.
bool processPowerHalReturn(bool isOk, const char* functionName) {
    if (!isOk) {
        ALOGE("%s() failed: power HAL service not available.", functionName);
        gPowerHalMutex.lock();
        gPowerHalHidlV1_0_ = nullptr;
        gPowerHalHidlV1_1_ = nullptr;
        gPowerHalAidl_ = nullptr;
        gPowerHalMutex.unlock();
    }
    return isOk;
}

enum class HalSupport {
    UNKNOWN = 0,
    ON,
    OFF,
};

static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t durationMs) {
    // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT.
    // Need to increase the array size if more boost supported.
    static std::array<std::atomic<HalSupport>,
                      static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1>
            boostSupportedArray = {HalSupport::UNKNOWN};

    // Quick return if boost is not supported by HAL
    if (boost > Boost::DISPLAY_UPDATE_IMMINENT ||
        boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) {
        ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str());
        return;
    }

    if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) {
        bool isSupported = false;
        handle->isBoostSupported(boost, &isSupported);
        boostSupportedArray[static_cast<int32_t>(boost)] =
            isSupported ? HalSupport::ON : HalSupport::OFF;
        if (!isSupported) {
            ALOGV("Skipped setPowerBoost %s because HAL doesn't support it",
                  toString(boost).c_str());
            return;
        }
    }

    auto ret = handle->setBoost(boost, durationMs);
    processPowerHalReturn(ret.isOk(), "setPowerBoost");
    SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(boost));
}

static void setPowerBoost(Boost boost, int32_t durationMs) {
    std::unique_lock<std::mutex> lock(gPowerHalMutex);
    if (connectPowerHalLocked() != HalVersion::AIDL) {
        ALOGV("Power HAL AIDL not available");
        return;
    }
    sp<IPowerAidl> handle = gPowerHalAidl_;
    lock.unlock();
    setPowerBoostWithHandle(handle, boost, durationMs);
}

static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enabled) {
    // Android framework only sends mode upto DISPLAY_INACTIVE.
    // Need to increase the array if more mode supported.
    static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1>
            modeSupportedArray = {HalSupport::UNKNOWN};

    // Quick return if mode is not supported by HAL
    if (mode > Mode::DISPLAY_INACTIVE ||
        modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) {
        ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
        return false;
    }

    if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) {
        bool isSupported = false;
        handle->isModeSupported(mode, &isSupported);
        modeSupportedArray[static_cast<int32_t>(mode)] =
            isSupported ? HalSupport::ON : HalSupport::OFF;
        if (!isSupported) {
            ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
            return false;
        }
    }

    auto ret = handle->setMode(mode, enabled);
    processPowerHalReturn(ret.isOk(), "setPowerMode");
    return ret.isOk();
    gPowerHalController.setBoost(boost, durationMs);
    SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(boost));
}

static bool setPowerMode(Mode mode, bool enabled) {
    std::unique_lock<std::mutex> lock(gPowerHalMutex);
    if (connectPowerHalLocked() != HalVersion::AIDL) {
        ALOGV("Power HAL AIDL not available");
        return false;
    }
    sp<IPowerAidl> handle = gPowerHalAidl_;
    lock.unlock();
    return setPowerModeWithHandle(handle, mode, enabled);
    auto result = gPowerHalController.setMode(mode, enabled);
    return result == PowerHalResult::SUCCESSFUL;
}

static void sendPowerHint(PowerHint hintId, uint32_t data) {
    std::unique_lock<std::mutex> lock(gPowerHalMutex);
    switch (connectPowerHalLocked()) {
        case HalVersion::NONE:
            return;
        case HalVersion::HIDL_1_0: {
            sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
            lock.unlock();
            auto ret = handle->powerHint(hintId, data);
            processPowerHalReturn(ret.isOk(), "powerHint");
            break;
        }
        case HalVersion::HIDL_1_1: {
            sp<IPowerV1_1> handle = gPowerHalHidlV1_1_;
            lock.unlock();
            auto ret = handle->powerHintAsync(hintId, data);
            processPowerHalReturn(ret.isOk(), "powerHintAsync");
            break;
        }
        case HalVersion::AIDL: {
            if (hintId == PowerHint::INTERACTION) {
                sp<IPowerAidl> handle = gPowerHalAidl_;
                lock.unlock();
                setPowerBoostWithHandle(handle, Boost::INTERACTION, data);
    switch (hintId) {
        case PowerHint::INTERACTION:
            gPowerHalController.setBoost(Boost::INTERACTION, data);
            SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(Boost::INTERACTION));
            break;
            } else if (hintId == PowerHint::LAUNCH) {
                sp<IPowerAidl> handle = gPowerHalAidl_;
                lock.unlock();
                setPowerModeWithHandle(handle, Mode::LAUNCH, static_cast<bool>(data));
        case PowerHint::LAUNCH:
            gPowerHalController.setMode(Mode::LAUNCH, static_cast<bool>(data));
            break;
            } else if (hintId == PowerHint::LOW_POWER) {
                sp<IPowerAidl> handle = gPowerHalAidl_;
                lock.unlock();
                setPowerModeWithHandle(handle, Mode::LOW_POWER, static_cast<bool>(data));
        case PowerHint::LOW_POWER:
            gPowerHalController.setMode(Mode::LOW_POWER, static_cast<bool>(data));
            break;
            } else if (hintId == PowerHint::SUSTAINED_PERFORMANCE) {
                sp<IPowerAidl> handle = gPowerHalAidl_;
                lock.unlock();
                setPowerModeWithHandle(handle, Mode::SUSTAINED_PERFORMANCE,
                                       static_cast<bool>(data));
        case PowerHint::SUSTAINED_PERFORMANCE:
            gPowerHalController.setMode(Mode::SUSTAINED_PERFORMANCE, static_cast<bool>(data));
            break;
            } else if (hintId == PowerHint::VR_MODE) {
                sp<IPowerAidl> handle = gPowerHalAidl_;
                lock.unlock();
                setPowerModeWithHandle(handle, Mode::VR, static_cast<bool>(data));
        case PowerHint::VR_MODE:
            gPowerHalController.setMode(Mode::VR, static_cast<bool>(data));
            break;
            } else {
        default:
            ALOGE("Unsupported power hint: %s.", toString(hintId).c_str());
                return;
            }
        }
        default: {
            ALOGE("Unknown power HAL state");
            return;
        }
    }
}

@@ -388,10 +207,7 @@ void disableAutoSuspend() {

static void nativeInit(JNIEnv* env, jobject obj) {
    gPowerManagerServiceObj = env->NewGlobalRef(obj);

    gPowerHalMutex.lock();
    connectPowerHalLocked();
    gPowerHalMutex.unlock();
    gPowerHalController.init();
}

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
@@ -405,35 +221,12 @@ static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring
}

static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
    std::unique_lock<std::mutex> lock(gPowerHalMutex);
    switch (connectPowerHalLocked()) {
        case HalVersion::NONE:
            return;
        case HalVersion::HIDL_1_0:
            FALLTHROUGH_INTENDED;
        case HalVersion::HIDL_1_1: {
    android::base::Timer t;
            sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
            lock.unlock();
            auto ret = handle->setInteractive(enable);
            processPowerHalReturn(ret.isOk(), "setInteractive");
    gPowerHalController.setMode(Mode::INTERACTIVE, enable);
    if (t.duration() > 20ms) {
        ALOGD("Excessive delay in setInteractive(%s) while turning screen %s",
              enable ? "true" : "false", enable ? "on" : "off");
    }
            return;
        }
        case HalVersion::AIDL: {
            sp<IPowerAidl> handle = gPowerHalAidl_;
            lock.unlock();
            setPowerModeWithHandle(handle, Mode::INTERACTIVE, enable);
            return;
        }
        default: {
            ALOGE("Unknown power HAL state");
            return;
        }
    }
}

static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
@@ -467,29 +260,13 @@ static jboolean nativeSetPowerMode(JNIEnv* /* env */, jclass /* clazz */, jint m
}

static void nativeSetFeature(JNIEnv* /* env */, jclass /* clazz */, jint featureId, jint data) {
    std::unique_lock<std::mutex> lock(gPowerHalMutex);
    switch (connectPowerHalLocked()) {
        case HalVersion::NONE:
            return;
        case HalVersion::HIDL_1_0:
            FALLTHROUGH_INTENDED;
        case HalVersion::HIDL_1_1: {
            sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
            lock.unlock();
            auto ret = handle->setFeature(static_cast<Feature>(featureId), static_cast<bool>(data));
            processPowerHalReturn(ret.isOk(), "setFeature");
            return;
        }
        case HalVersion::AIDL: {
            sp<IPowerAidl> handle = gPowerHalAidl_;
            lock.unlock();
            setPowerModeWithHandle(handle, Mode::DOUBLE_TAP_TO_WAKE, static_cast<bool>(data));
            return;
        }
        default: {
            ALOGE("Unknown power HAL state");
            return;
        }
    Feature feature = static_cast<Feature>(featureId);
    switch (feature) {
        case Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE:
            gPowerHalController.setMode(Mode::DOUBLE_TAP_TO_WAKE, static_cast<bool>(data));
            break;
        default:
            ALOGE("Unsupported feature: %s.", toString(feature).c_str());
    }
}