1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_MEDIA_TRANSCODING_SESSION_CONTROLLER_H 18 #define ANDROID_MEDIA_TRANSCODING_SESSION_CONTROLLER_H 19 20 #include <aidl/android/media/TranscodingSessionPriority.h> 21 #include <media/ControllerClientInterface.h> 22 #include <media/ResourcePolicyInterface.h> 23 #include <media/ThermalPolicyInterface.h> 24 #include <media/TranscoderInterface.h> 25 #include <media/TranscodingRequest.h> 26 #include <media/UidPolicyInterface.h> 27 #include <utils/String8.h> 28 #include <utils/Vector.h> 29 30 #include <chrono> 31 #include <functional> 32 #include <list> 33 #include <map> 34 #include <mutex> 35 36 namespace android { 37 using ::aidl::android::media::TranscodingResultParcel; 38 using ::aidl::android::media::TranscodingSessionPriority; 39 40 class TranscodingSessionController 41 : public UidPolicyCallbackInterface, 42 public ControllerClientInterface, 43 public TranscoderCallbackInterface, 44 public ResourcePolicyCallbackInterface, 45 public ThermalPolicyCallbackInterface, 46 public std::enable_shared_from_this<TranscodingSessionController> { 47 public: 48 virtual ~TranscodingSessionController(); 49 50 // ControllerClientInterface 51 bool submit(ClientIdType clientId, SessionIdType sessionId, uid_t callingUid, uid_t clientUid, 52 const TranscodingRequestParcel& request, 53 const std::weak_ptr<ITranscodingClientCallback>& clientCallback) override; 54 bool cancel(ClientIdType clientId, SessionIdType sessionId) override; 55 bool getSession(ClientIdType clientId, SessionIdType sessionId, 56 TranscodingRequestParcel* request) override; 57 bool addClientUid(ClientIdType clientId, SessionIdType sessionId, uid_t clientUid) override; 58 bool getClientUids(ClientIdType clientId, SessionIdType sessionId, 59 std::vector<int32_t>* out_clientUids) override; 60 // ~ControllerClientInterface 61 62 // TranscoderCallbackInterface 63 void onStarted(ClientIdType clientId, SessionIdType sessionId) override; 64 void onPaused(ClientIdType clientId, SessionIdType sessionId) override; 65 void onResumed(ClientIdType clientId, SessionIdType sessionId) override; 66 void onFinish(ClientIdType clientId, SessionIdType sessionId) override; 67 void onError(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) override; 68 void onProgressUpdate(ClientIdType clientId, SessionIdType sessionId, 69 int32_t progress) override; 70 void onHeartBeat(ClientIdType clientId, SessionIdType sessionId) override; 71 void onResourceLost(ClientIdType clientId, SessionIdType sessionId) override; 72 // ~TranscoderCallbackInterface 73 74 // UidPolicyCallbackInterface 75 void onTopUidsChanged(const std::unordered_set<uid_t>& uids) override; 76 void onUidGone(uid_t goneUid) override; 77 // ~UidPolicyCallbackInterface 78 79 // ResourcePolicyCallbackInterface 80 void onResourceAvailable() override; 81 // ~ResourcePolicyCallbackInterface 82 83 // ThermalPolicyCallbackInterface 84 void onThrottlingStarted() override; 85 void onThrottlingStopped() override; 86 // ~ResourcePolicyCallbackInterface 87 88 /** 89 * Dump all the session information to the fd. 90 */ 91 void dumpAllSessions(int fd, const Vector<String16>& args); 92 93 private: 94 friend class MediaTranscodingService; 95 friend class TranscodingSessionControllerTest; 96 97 using SessionKeyType = std::pair<ClientIdType, SessionIdType>; 98 using SessionQueueType = std::list<SessionKeyType>; 99 using TranscoderFactoryType = std::function<std::shared_ptr<TranscoderInterface>( 100 const std::shared_ptr<TranscoderCallbackInterface>&)>; 101 102 struct ControllerConfig { 103 // Watchdog timeout. 104 int64_t watchdogTimeoutUs = 3000000LL; 105 // Threshold of time between finish/start below which a back-to-back start is counted. 106 int32_t pacerBurstThresholdMs = 1000; 107 // Maximum allowed back-to-back start count. 108 int32_t pacerBurstCountQuota = 10; 109 // Maximum allowed back-to-back running time. 110 int32_t pacerBurstTimeQuotaSeconds = 120; // 2-min 111 }; 112 113 struct Session { 114 enum State { 115 INVALID = -1, 116 NOT_STARTED = 0, 117 RUNNING, 118 PAUSED, 119 // The following states would not appear in live sessions map, but could 120 // appear in past sessions map for logging purpose. 121 FINISHED, 122 CANCELED, 123 ERROR, 124 DROPPED_BY_PACER, 125 }; 126 SessionKeyType key; 127 uid_t callingUid; 128 std::unordered_set<uid_t> allClientUids; 129 int32_t lastProgress = 0; 130 int32_t pauseCount = 0; 131 std::chrono::time_point<std::chrono::steady_clock> stateEnterTime; 132 std::chrono::microseconds waitingTime{0}; 133 std::chrono::microseconds runningTime{0}; 134 std::chrono::microseconds pausedTime{0}; 135 136 TranscodingRequest request; 137 std::weak_ptr<ITranscodingClientCallback> callback; 138 139 // Must use setState to change state. 140 void setState(Session::State state); getStateSession141 State getState() const { return state; } isRunningSession142 bool isRunning() { return state == RUNNING; } 143 144 private: 145 State state = INVALID; 146 }; 147 148 struct Watchdog; 149 struct Pacer; 150 151 ControllerConfig mConfig; 152 153 // TODO(chz): call transcoder without global lock. 154 // Use mLock for all entrypoints for now. 155 mutable std::mutex mLock; 156 157 std::map<SessionKeyType, Session> mSessionMap; 158 159 // uid->SessionQueue map (uid == -1: offline queue) 160 std::map<uid_t, SessionQueueType> mSessionQueues; 161 162 // uids, with the head being the most-recently-top app, 2nd item is the 163 // previous top app, etc. 164 std::list<uid_t> mUidSortedList; 165 std::list<uid_t>::iterator mOfflineUidIterator; 166 std::map<uid_t, std::string> mUidPackageNames; 167 168 TranscoderFactoryType mTranscoderFactory; 169 std::shared_ptr<TranscoderInterface> mTranscoder; 170 std::shared_ptr<UidPolicyInterface> mUidPolicy; 171 std::shared_ptr<ResourcePolicyInterface> mResourcePolicy; 172 std::shared_ptr<ThermalPolicyInterface> mThermalPolicy; 173 174 Session* mCurrentSession; 175 bool mResourceLost; 176 bool mThermalThrottling; 177 std::list<Session> mSessionHistory; 178 std::shared_ptr<Watchdog> mWatchdog; 179 std::shared_ptr<Pacer> mPacer; 180 181 // Only allow MediaTranscodingService and unit tests to instantiate. 182 TranscodingSessionController(const TranscoderFactoryType& transcoderFactory, 183 const std::shared_ptr<UidPolicyInterface>& uidPolicy, 184 const std::shared_ptr<ResourcePolicyInterface>& resourcePolicy, 185 const std::shared_ptr<ThermalPolicyInterface>& thermalPolicy, 186 const ControllerConfig* config = nullptr); 187 188 void dumpSession_l(const Session& session, String8& result, bool closedSession = false); 189 Session* getTopSession_l(); 190 void updateCurrentSession_l(); 191 void addUidToSession_l(uid_t uid, const SessionKeyType& sessionKey); 192 void removeSession_l(const SessionKeyType& sessionKey, Session::State finalState, 193 const std::shared_ptr<std::function<bool(uid_t uid)>>& keepUid = nullptr); 194 void moveUidsToTop_l(const std::unordered_set<uid_t>& uids, bool preserveTopUid); 195 void setSessionState_l(Session* session, Session::State state); 196 void notifyClient(ClientIdType clientId, SessionIdType sessionId, const char* reason, 197 std::function<void(const SessionKeyType&)> func); 198 // Internal state verifier (debug only) 199 void validateState_l(); 200 201 static String8 sessionToString(const SessionKeyType& sessionKey); 202 static const char* sessionStateToString(const Session::State sessionState); 203 }; 204 205 } // namespace android 206 #endif // ANDROID_MEDIA_TRANSCODING_SESSION_CONTROLLER_H 207