Loading media/libmediatranscoding/Android.bp +3 −2 Original line number Diff line number Diff line Loading @@ -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: [ Loading media/libmediatranscoding/TranscodingClientManager.cpp +8 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading media/libmediatranscoding/TranscodingSessionController.cpp +53 −9 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -74,6 +76,7 @@ TranscodingSessionController::TranscodingSessionController( mOfflineUidIterator = mUidSortedList.begin(); mSessionQueues.emplace(OFFLINE_UID, SessionQueueType()); mUidPackageNames[OFFLINE_UID] = "(offline)"; mThermalThrottling = thermalPolicy->getThrottlingStatus(); } TranscodingSessionController::~TranscodingSessionController() {} Loading Loading @@ -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()); Loading Loading @@ -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(); Loading Loading @@ -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, Loading media/libmediatranscoding/TranscodingThermalPolicy.cpp 0 → 100644 +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 media/libmediatranscoding/TranscodingUidPolicy.cpp +5 −11 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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 { Loading @@ -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. Loading Loading @@ -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 Loading
media/libmediatranscoding/Android.bp +3 −2 Original line number Diff line number Diff line Loading @@ -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: [ Loading
media/libmediatranscoding/TranscodingClientManager.cpp +8 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading
media/libmediatranscoding/TranscodingSessionController.cpp +53 −9 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -74,6 +76,7 @@ TranscodingSessionController::TranscodingSessionController( mOfflineUidIterator = mUidSortedList.begin(); mSessionQueues.emplace(OFFLINE_UID, SessionQueueType()); mUidPackageNames[OFFLINE_UID] = "(offline)"; mThermalThrottling = thermalPolicy->getThrottlingStatus(); } TranscodingSessionController::~TranscodingSessionController() {} Loading Loading @@ -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()); Loading Loading @@ -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(); Loading Loading @@ -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, Loading
media/libmediatranscoding/TranscodingThermalPolicy.cpp 0 → 100644 +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
media/libmediatranscoding/TranscodingUidPolicy.cpp +5 −11 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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 { Loading @@ -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. Loading Loading @@ -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