• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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