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

Commit 8677f1f3 authored by Chong Zhang's avatar Chong Zhang
Browse files

Revert "Revert "transcoding: add thermal status listener""

This reverts commit b253cec6.

Reason for revert: reland with fix

Change-Id: Ieab554dc2dc4187e75fc223997387f4875832e52
parent cbb06bde
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -71,11 +71,12 @@ cc_library {
    ],

    srcs: [
        "TranscoderWrapper.cpp",
        "TranscodingClientManager.cpp",
        "TranscodingSessionController.cpp",
        "TranscodingResourcePolicy.cpp",
        "TranscodingSessionController.cpp",
        "TranscodingThermalPolicy.cpp",
        "TranscodingUidPolicy.cpp",
        "TranscoderWrapper.cpp",
    ],

    shared_libs: [
+8 −10
Original line number Diff line number Diff line
@@ -138,8 +138,7 @@ Status TranscodingClientManager::ClientImpl::submitRequest(
        ALOGE("submitRequest rejected (clientPid %d, clientUid %d) "
              "(don't trust callingUid %d)",
              in_clientPid, in_clientUid, callingUid);
        return STATUS_ERROR_FMT(
                IMediaTranscodingService::ERROR_PERMISSION_DENIED,
        return STATUS_ERROR_FMT(IMediaTranscodingService::ERROR_PERMISSION_DENIED,
                                "submitRequest rejected (clientPid %d, clientUid %d) "
                                "(don't trust callingUid %d)",
                                in_clientPid, in_clientUid, callingUid);
@@ -155,8 +154,7 @@ Status TranscodingClientManager::ClientImpl::submitRequest(
        ALOGE("submitRequest rejected (clientPid %d, clientUid %d) "
              "(don't trust callingUid %d)",
              in_clientPid, in_clientUid, callingUid);
        return STATUS_ERROR_FMT(
                IMediaTranscodingService::ERROR_PERMISSION_DENIED,
        return STATUS_ERROR_FMT(IMediaTranscodingService::ERROR_PERMISSION_DENIED,
                                "submitRequest rejected (clientPid %d, clientUid %d) "
                                "(don't trust callingUid %d)",
                                in_clientPid, in_clientUid, callingUid);
+53 −9
Original line number Diff line number Diff line
@@ -63,10 +63,12 @@ const char* TranscodingSessionController::sessionStateToString(const Session::St
TranscodingSessionController::TranscodingSessionController(
        const std::shared_ptr<TranscoderInterface>& transcoder,
        const std::shared_ptr<UidPolicyInterface>& uidPolicy,
        const std::shared_ptr<ResourcePolicyInterface>& resourcePolicy)
        const std::shared_ptr<ResourcePolicyInterface>& resourcePolicy,
        const std::shared_ptr<ThermalPolicyInterface>& thermalPolicy)
      : mTranscoder(transcoder),
        mUidPolicy(uidPolicy),
        mResourcePolicy(resourcePolicy),
        mThermalPolicy(thermalPolicy),
        mCurrentSession(nullptr),
        mResourceLost(false) {
    // Only push empty offline queue initially. Realtime queues are added when requests come in.
@@ -74,6 +76,7 @@ TranscodingSessionController::TranscodingSessionController(
    mOfflineUidIterator = mUidSortedList.begin();
    mSessionQueues.emplace(OFFLINE_UID, SessionQueueType());
    mUidPackageNames[OFFLINE_UID] = "(offline)";
    mThermalThrottling = thermalPolicy->getThrottlingStatus();
}

TranscodingSessionController::~TranscodingSessionController() {}
@@ -192,18 +195,27 @@ void TranscodingSessionController::updateCurrentSession_l() {
          topSession == nullptr ? "null" : sessionToString(topSession->key).c_str(),
          curSession == nullptr ? "null" : sessionToString(curSession->key).c_str());

    if (topSession == nullptr) {
        mCurrentSession = nullptr;
        return;
    }

    bool shouldBeRunning = !((mResourcePolicy != nullptr && mResourceLost) ||
                             (mThermalPolicy != nullptr && mThermalThrottling));
    // If we found a topSession that should be run, and it's not already running,
    // take some actions to ensure it's running.
    if (topSession != nullptr &&
        (topSession != curSession || topSession->getState() != Session::RUNNING)) {
        // If another session is currently running, pause it first.
    if (topSession != curSession ||
        (shouldBeRunning ^ (topSession->getState() == Session::RUNNING))) {
        // If current session is running, pause it first. Note this is true for either
        // cases: 1) If top session is changing, or 2) if top session is not changing but
        // the topSession's state is changing.
        if (curSession != nullptr && curSession->getState() == Session::RUNNING) {
            mTranscoder->pause(curSession->key.first, curSession->key.second);
            curSession->setState(Session::PAUSED);
        }
        // If we are not experiencing resource loss, we can start or resume
        // the topSession now.
        if (!mResourceLost) {
        // If we are not experiencing resource loss nor thermal throttling, we can start
        // or resume the topSession now.
        if (shouldBeRunning) {
            if (topSession->getState() == Session::NOT_STARTED) {
                mTranscoder->start(topSession->key.first, topSession->key.second,
                                   topSession->request, topSession->callback.lock());
@@ -566,7 +578,9 @@ void TranscodingSessionController::onResourceLost(ClientIdType clientId, Session
        if (clientCallback != nullptr) {
            clientCallback->onTranscodingPaused(sessionKey.second);
        }
        if (mResourcePolicy != nullptr) {
            mResourcePolicy->setPidResourceLost(resourceLostSession->request.clientPid);
        }
        mResourceLost = true;

        validateState_l();
@@ -613,6 +627,36 @@ void TranscodingSessionController::onResourceAvailable() {
    validateState_l();
}

void TranscodingSessionController::onThrottlingStarted() {
    std::scoped_lock lock{mLock};

    if (mThermalThrottling) {
        return;
    }

    ALOGI("%s", __FUNCTION__);

    mThermalThrottling = true;
    updateCurrentSession_l();

    validateState_l();
}

void TranscodingSessionController::onThrottlingStopped() {
    std::scoped_lock lock{mLock};

    if (!mThermalThrottling) {
        return;
    }

    ALOGI("%s", __FUNCTION__);

    mThermalThrottling = false;
    updateCurrentSession_l();

    validateState_l();
}

void TranscodingSessionController::validateState_l() {
#ifdef VALIDATE_STATE
    LOG_ALWAYS_FATAL_IF(mSessionQueues.count(OFFLINE_UID) != 1,
+133 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "TranscodingThermalPolicy"

#include <media/TranscodingThermalPolicy.h>
#include <media/TranscodingUidPolicy.h>
#include <utils/Log.h>

namespace android {

static bool needThrottling(AThermalStatus status) {
    return (status >= ATHERMAL_STATUS_SEVERE);
}

//static
void TranscodingThermalPolicy::onStatusChange(void* data, AThermalStatus status) {
    TranscodingThermalPolicy* policy = static_cast<TranscodingThermalPolicy*>(data);
    policy->onStatusChange(status);
}

TranscodingThermalPolicy::TranscodingThermalPolicy()
      : mRegistered(false), mThermalManager(nullptr), mIsThrottling(false) {
    registerSelf();
}

TranscodingThermalPolicy::~TranscodingThermalPolicy() {
    unregisterSelf();
}

void TranscodingThermalPolicy::registerSelf() {
    ALOGI("TranscodingThermalPolicy: registerSelf");

    std::scoped_lock lock{mRegisteredLock};

    if (mRegistered) {
        return;
    }

    if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
        AThermalManager* thermalManager = AThermal_acquireManager();
        if (thermalManager == nullptr) {
            ALOGE("Failed to acquire thermal manager");
            return;
        }

        int ret = AThermal_registerThermalStatusListener(thermalManager, onStatusChange, this);
        if (ret != 0) {
            ALOGE("Failed to register thermal status listener");
            AThermal_releaseManager(thermalManager);
            return;
        }

        mIsThrottling = needThrottling(AThermal_getCurrentThermalStatus(thermalManager));
        mThermalManager = thermalManager;
    }

    mRegistered = true;
}

void TranscodingThermalPolicy::unregisterSelf() {
    ALOGI("TranscodingThermalPolicy: unregisterSelf");

    std::scoped_lock lock{mRegisteredLock};

    if (!mRegistered) {
        return;
    }

    if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
        if (mThermalManager != nullptr) {
            // Unregister listener
            int ret =
                    AThermal_unregisterThermalStatusListener(mThermalManager, onStatusChange, this);
            if (ret != 0) {
                ALOGW("Failed to unregister thermal status listener");
            }
            AThermal_releaseManager(mThermalManager);
            mThermalManager = nullptr;
        }
    }

    mRegistered = false;
}

void TranscodingThermalPolicy::setCallback(
        const std::shared_ptr<ThermalPolicyCallbackInterface>& cb) {
    std::scoped_lock lock{mCallbackLock};
    mThermalPolicyCallback = cb;
}

bool TranscodingThermalPolicy::getThrottlingStatus() {
    std::scoped_lock lock{mRegisteredLock};
    return mIsThrottling;
}

void TranscodingThermalPolicy::onStatusChange(AThermalStatus status) {
    bool isThrottling = needThrottling(status);

    {
        std::scoped_lock lock{mRegisteredLock};
        if (isThrottling == mIsThrottling) {
            return;
        }
        ALOGI("Transcoding thermal throttling changed: %d", isThrottling);
        mIsThrottling = isThrottling;
    }

    std::scoped_lock lock{mCallbackLock};
    std::shared_ptr<ThermalPolicyCallbackInterface> cb;
    if ((cb = mThermalPolicyCallback.lock()) != nullptr) {
        if (isThrottling) {
            cb->onThrottlingStarted();
        } else {
            cb->onThrottlingStopped();
        }
    }
}
}  // namespace android
+5 −11
Original line number Diff line number Diff line
@@ -32,9 +32,7 @@ constexpr static uid_t OFFLINE_UID = -1;
constexpr static int32_t IMPORTANCE_UNKNOWN = INT32_MAX;

TranscodingUidPolicy::TranscodingUidPolicy()
      : mUidObserver(nullptr),
        mRegistered(false),
        mTopUidState(IMPORTANCE_UNKNOWN) {
      : mUidObserver(nullptr), mRegistered(false), mTopUidState(IMPORTANCE_UNKNOWN) {
    registerSelf();
}

@@ -129,8 +127,7 @@ void TranscodingUidPolicy::unregisterMonitorUid(uid_t uid) {
bool TranscodingUidPolicy::isUidOnTop(uid_t uid) {
    Mutex::Autolock _l(mUidLock);

    return mTopUidState != IMPORTANCE_UNKNOWN &&
           mTopUidState == getProcState_l(uid);
    return mTopUidState != IMPORTANCE_UNKNOWN && mTopUidState == getProcState_l(uid);
}

std::unordered_set<uid_t> TranscodingUidPolicy::getTopUids() const {
@@ -155,12 +152,10 @@ void TranscodingUidPolicy::onUidStateChanged(uid_t uid, int32_t procState) {
            // Top set changed if 1) the uid is in the current top uid set, or 2) the
            // new procState is at least the same priority as the current top uid state.
            bool isUidCurrentTop =
                    mTopUidState != IMPORTANCE_UNKNOWN &&
                    mStateUidMap[mTopUidState].count(uid) > 0;
                    mTopUidState != IMPORTANCE_UNKNOWN && mStateUidMap[mTopUidState].count(uid) > 0;
            bool isNewStateHigherThanTop =
                    procState != IMPORTANCE_UNKNOWN &&
                    (procState <= mTopUidState ||
                     mTopUidState == IMPORTANCE_UNKNOWN);
                    (procState <= mTopUidState || mTopUidState == IMPORTANCE_UNKNOWN);
            topUidSetChanged = (isUidCurrentTop || isNewStateHigherThanTop);

            // Move uid to the new procState.
@@ -192,8 +187,7 @@ void TranscodingUidPolicy::updateTopUid_l() {

    // Find the lowest uid state (ignoring PROCESS_STATE_UNKNOWN) with some monitored uids.
    for (auto stateIt = mStateUidMap.begin(); stateIt != mStateUidMap.end(); stateIt++) {
        if (stateIt->first != IMPORTANCE_UNKNOWN &&
            !stateIt->second.empty()) {
        if (stateIt->first != IMPORTANCE_UNKNOWN && !stateIt->second.empty()) {
            mTopUidState = stateIt->first;
            break;
        }
Loading