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

Commit ebc0b269 authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "transcoding: drop transcoding request when uid is gone" into sc-dev

parents c8b2e4a2 2a3c9672
Loading
Loading
Loading
Loading
+87 −11
Original line number Original line Diff line number Diff line
@@ -195,6 +195,7 @@ struct TranscodingSessionController::Pacer {


    bool onSessionStarted(uid_t uid);
    bool onSessionStarted(uid_t uid);
    void onSessionCompleted(uid_t uid, std::chrono::microseconds runningTime);
    void onSessionCompleted(uid_t uid, std::chrono::microseconds runningTime);
    void onSessionCancelled(uid_t uid);


private:
private:
    // Threshold of time between finish/start below which a back-to-back start is counted.
    // Threshold of time between finish/start below which a back-to-back start is counted.
@@ -267,6 +268,18 @@ void TranscodingSessionController::Pacer::onSessionCompleted(
    mUidHistoryMap[uid].lastCompletedTime = std::chrono::steady_clock::now();
    mUidHistoryMap[uid].lastCompletedTime = std::chrono::steady_clock::now();
}
}


void TranscodingSessionController::Pacer::onSessionCancelled(uid_t uid) {
    if (mUidHistoryMap.find(uid) == mUidHistoryMap.end()) {
        ALOGV("Pacer::onSessionCancelled: uid %d: not present", uid);
        return;
    }
    // This is only called if a uid is removed from a session (due to it being killed
    // or the original submitting client was gone but session was kept for offline use).
    // Since the uid is going to miss the onSessionCompleted(), we can't track this
    // session, and have to check back at next onSessionStarted().
    mUidHistoryMap[uid].sessionActive = false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


TranscodingSessionController::TranscodingSessionController(
TranscodingSessionController::TranscodingSessionController(
@@ -539,8 +552,9 @@ void TranscodingSessionController::addUidToSession_l(uid_t clientUid,
    mSessionQueues[clientUid].push_back(sessionKey);
    mSessionQueues[clientUid].push_back(sessionKey);
}
}


void TranscodingSessionController::removeSession_l(const SessionKeyType& sessionKey,
void TranscodingSessionController::removeSession_l(
                                                   Session::State finalState, bool keepForOffline) {
        const SessionKeyType& sessionKey, Session::State finalState,
        const std::shared_ptr<std::function<bool(uid_t uid)>>& keepUid) {
    ALOGV("%s: session %s", __FUNCTION__, sessionToString(sessionKey).c_str());
    ALOGV("%s: session %s", __FUNCTION__, sessionToString(sessionKey).c_str());


    if (mSessionMap.count(sessionKey) == 0) {
    if (mSessionMap.count(sessionKey) == 0) {
@@ -550,10 +564,18 @@ void TranscodingSessionController::removeSession_l(const SessionKeyType& session


    // Remove session from uid's queue.
    // Remove session from uid's queue.
    bool uidQueueRemoved = false;
    bool uidQueueRemoved = false;
    std::unordered_set<uid_t> remainingUids;
    for (uid_t uid : mSessionMap[sessionKey].allClientUids) {
    for (uid_t uid : mSessionMap[sessionKey].allClientUids) {
        if (keepForOffline && uid == OFFLINE_UID) {
        if (keepUid != nullptr) {
            if ((*keepUid)(uid)) {
                remainingUids.insert(uid);
                continue;
                continue;
            }
            }
            // If we have uids to keep, the session is not going to any final
            // state we can't use onSessionCompleted as the running time will
            // not be valid. Only notify pacer to stop tracking this session.
            mPacer->onSessionCancelled(uid);
        }
        SessionQueueType& sessionQueue = mSessionQueues[uid];
        SessionQueueType& sessionQueue = mSessionQueues[uid];
        auto it = std::find(sessionQueue.begin(), sessionQueue.end(), sessionKey);
        auto it = std::find(sessionQueue.begin(), sessionQueue.end(), sessionKey);
        if (it == sessionQueue.end()) {
        if (it == sessionQueue.end()) {
@@ -578,8 +600,8 @@ void TranscodingSessionController::removeSession_l(const SessionKeyType& session
        moveUidsToTop_l(topUids, false /*preserveTopUid*/);
        moveUidsToTop_l(topUids, false /*preserveTopUid*/);
    }
    }


    if (keepForOffline) {
    if (keepUid != nullptr) {
        mSessionMap[sessionKey].allClientUids = {OFFLINE_UID};
        mSessionMap[sessionKey].allClientUids = remainingUids;
        return;
        return;
    }
    }


@@ -590,11 +612,11 @@ void TranscodingSessionController::removeSession_l(const SessionKeyType& session


    setSessionState_l(&mSessionMap[sessionKey], finalState);
    setSessionState_l(&mSessionMap[sessionKey], finalState);


    if (finalState == Session::FINISHED || finalState == Session::ERROR) {
    // We can use onSessionCompleted() even for CANCELLED, because runningTime is
    // now updated by setSessionState_l().
    for (uid_t uid : mSessionMap[sessionKey].allClientUids) {
    for (uid_t uid : mSessionMap[sessionKey].allClientUids) {
        mPacer->onSessionCompleted(uid, mSessionMap[sessionKey].runningTime);
        mPacer->onSessionCompleted(uid, mSessionMap[sessionKey].runningTime);
    }
    }
    }


    mSessionHistory.push_back(mSessionMap[sessionKey]);
    mSessionHistory.push_back(mSessionMap[sessionKey]);
    if (mSessionHistory.size() > kSessionHistoryMax) {
    if (mSessionHistory.size() > kSessionHistoryMax) {
@@ -743,8 +765,10 @@ bool TranscodingSessionController::cancel(ClientIdType clientId, SessionIdType s
        removeSession_l(*it, Session::CANCELED);
        removeSession_l(*it, Session::CANCELED);
    }
    }


    auto keepUid = std::make_shared<std::function<bool(uid_t)>>(
            [](uid_t uid) { return uid == OFFLINE_UID; });
    for (auto it = sessionsForOffline.begin(); it != sessionsForOffline.end(); ++it) {
    for (auto it = sessionsForOffline.begin(); it != sessionsForOffline.end(); ++it) {
        removeSession_l(*it, Session::CANCELED, true /*keepForOffline*/);
        removeSession_l(*it, Session::CANCELED, keepUid);
    }
    }


    // Start next session.
    // Start next session.
@@ -990,6 +1014,58 @@ void TranscodingSessionController::onTopUidsChanged(const std::unordered_set<uid
    validateState_l();
    validateState_l();
}
}


void TranscodingSessionController::onUidGone(uid_t goneUid) {
    ALOGD("%s: gone uid %u", __FUNCTION__, goneUid);

    std::list<SessionKeyType> sessionsToRemove, sessionsForOtherUids;

    std::scoped_lock lock{mLock};

    for (auto it = mSessionMap.begin(); it != mSessionMap.end(); ++it) {
        if (it->second.allClientUids.count(goneUid) > 0) {
            // If goneUid is the only uid, remove the session; otherwise, only
            // remove the uid from the session.
            if (it->second.allClientUids.size() > 1) {
                sessionsForOtherUids.push_back(it->first);
            } else {
                sessionsToRemove.push_back(it->first);
            }
        }
    }

    for (auto it = sessionsToRemove.begin(); it != sessionsToRemove.end(); ++it) {
        // If the session has ever been started, stop it now.
        // Note that stop() is needed even if the session is currently paused. This instructs
        // the transcoder to discard any states for the session, otherwise the states may
        // never be discarded.
        if (mSessionMap[*it].getState() != Session::NOT_STARTED) {
            mTranscoder->stop(it->first, it->second);
        }

        {
            auto clientCallback = mSessionMap[*it].callback.lock();
            if (clientCallback != nullptr) {
                clientCallback->onTranscodingFailed(it->second,
                                                    TranscodingErrorCode::kUidGoneCancelled);
            }
        }

        // Remove the session.
        removeSession_l(*it, Session::CANCELED);
    }

    auto keepUid = std::make_shared<std::function<bool(uid_t)>>(
            [goneUid](uid_t uid) { return uid != goneUid; });
    for (auto it = sessionsForOtherUids.begin(); it != sessionsForOtherUids.end(); ++it) {
        removeSession_l(*it, Session::CANCELED, keepUid);
    }

    // Start next session.
    updateCurrentSession_l();

    validateState_l();
}

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


+15 −13
Original line number Original line Diff line number Diff line
@@ -141,38 +141,34 @@ std::unordered_set<uid_t> TranscodingUidPolicy::getTopUids() const {
}
}


void TranscodingUidPolicy::onUidStateChanged(uid_t uid, int32_t procState) {
void TranscodingUidPolicy::onUidStateChanged(uid_t uid, int32_t procState) {
    ALOGV("onUidStateChanged: %u, procState %d", uid, procState);
    ALOGV("onUidStateChanged: uid %u, procState %d", uid, procState);


    bool topUidSetChanged = false;
    bool topUidSetChanged = false;
    bool isUidGone = false;
    std::unordered_set<uid_t> topUids;
    std::unordered_set<uid_t> topUids;
    {
    {
        Mutex::Autolock _l(mUidLock);
        Mutex::Autolock _l(mUidLock);
        auto it = mUidStateMap.find(uid);
        auto it = mUidStateMap.find(uid);
        if (it != mUidStateMap.end() && it->second != procState) {
        if (it != mUidStateMap.end() && it->second != procState) {
            // Top set changed if 1) the uid is in the current top uid set, or 2) the
            isUidGone = (procState == AACTIVITYMANAGER_IMPORTANCE_GONE);
            // new procState is at least the same priority as the current top uid state.

            bool isUidCurrentTop =
            topUids = mStateUidMap[mTopUidState];
                    mTopUidState != IMPORTANCE_UNKNOWN && mStateUidMap[mTopUidState].count(uid) > 0;
            bool isNewStateHigherThanTop =
                    procState != IMPORTANCE_UNKNOWN &&
                    (procState <= mTopUidState || mTopUidState == IMPORTANCE_UNKNOWN);
            topUidSetChanged = (isUidCurrentTop || isNewStateHigherThanTop);


            // Move uid to the new procState.
            // Move uid to the new procState.
            mStateUidMap[it->second].erase(uid);
            mStateUidMap[it->second].erase(uid);
            mStateUidMap[procState].insert(uid);
            mStateUidMap[procState].insert(uid);
            it->second = procState;
            it->second = procState;


            if (topUidSetChanged) {
            updateTopUid_l();
            updateTopUid_l();

            if (topUids != mStateUidMap[mTopUidState]) {
                // Make a copy of the uid set for callback.
                // Make a copy of the uid set for callback.
                topUids = mStateUidMap[mTopUidState];
                topUids = mStateUidMap[mTopUidState];
                topUidSetChanged = true;
            }
            }
        }
        }
    }
    }


    ALOGV("topUidSetChanged: %d", topUidSetChanged);
    ALOGV("topUidSetChanged: %d, isUidGone %d", topUidSetChanged, isUidGone);


    if (topUidSetChanged) {
    if (topUidSetChanged) {
        auto callback = mUidPolicyCallback.lock();
        auto callback = mUidPolicyCallback.lock();
@@ -180,6 +176,12 @@ void TranscodingUidPolicy::onUidStateChanged(uid_t uid, int32_t procState) {
            callback->onTopUidsChanged(topUids);
            callback->onTopUidsChanged(topUids);
        }
        }
    }
    }
    if (isUidGone) {
        auto callback = mUidPolicyCallback.lock();
        if (callback != nullptr) {
            callback->onUidGone(uid);
        }
    }
}
}


void TranscodingUidPolicy::updateTopUid_l() {
void TranscodingUidPolicy::updateTopUid_l() {
+1 −0
Original line number Original line Diff line number Diff line
@@ -38,4 +38,5 @@ enum TranscodingErrorCode {
    kErrorIO               = kPrivateErrorFirst + 5,
    kErrorIO               = kPrivateErrorFirst + 5,
    kInsufficientResources = kPrivateErrorFirst + 6,
    kInsufficientResources = kPrivateErrorFirst + 6,
    kWatchdogTimeout       = kPrivateErrorFirst + 7,
    kWatchdogTimeout       = kPrivateErrorFirst + 7,
    kUidGoneCancelled      = kPrivateErrorFirst + 8,
}
}
 No newline at end of file
+2 −1
Original line number Original line Diff line number Diff line
@@ -73,6 +73,7 @@ public:


    // UidPolicyCallbackInterface
    // UidPolicyCallbackInterface
    void onTopUidsChanged(const std::unordered_set<uid_t>& uids) override;
    void onTopUidsChanged(const std::unordered_set<uid_t>& uids) override;
    void onUidGone(uid_t goneUid) override;
    // ~UidPolicyCallbackInterface
    // ~UidPolicyCallbackInterface


    // ResourcePolicyCallbackInterface
    // ResourcePolicyCallbackInterface
@@ -189,7 +190,7 @@ private:
    void updateCurrentSession_l();
    void updateCurrentSession_l();
    void addUidToSession_l(uid_t uid, const SessionKeyType& sessionKey);
    void addUidToSession_l(uid_t uid, const SessionKeyType& sessionKey);
    void removeSession_l(const SessionKeyType& sessionKey, Session::State finalState,
    void removeSession_l(const SessionKeyType& sessionKey, Session::State finalState,
                         bool keepForOffline = false);
                         const std::shared_ptr<std::function<bool(uid_t uid)>>& keepUid = nullptr);
    void moveUidsToTop_l(const std::unordered_set<uid_t>& uids, bool preserveTopUid);
    void moveUidsToTop_l(const std::unordered_set<uid_t>& uids, bool preserveTopUid);
    void setSessionState_l(Session* session, Session::State state);
    void setSessionState_l(Session* session, Session::State state);
    void notifyClient(ClientIdType clientId, SessionIdType sessionId, const char* reason,
    void notifyClient(ClientIdType clientId, SessionIdType sessionId, const char* reason,
+3 −0
Original line number Original line Diff line number Diff line
@@ -48,6 +48,9 @@ public:
    // has changed. The receiver of this callback should adjust accordingly.
    // has changed. The receiver of this callback should adjust accordingly.
    virtual void onTopUidsChanged(const std::unordered_set<uid_t>& uids) = 0;
    virtual void onTopUidsChanged(const std::unordered_set<uid_t>& uids) = 0;


    // Called when a uid is gone.
    virtual void onUidGone(uid_t goneUid) = 0;

protected:
protected:
    virtual ~UidPolicyCallbackInterface() = default;
    virtual ~UidPolicyCallbackInterface() = default;
};
};
Loading