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_CLIENT_MANAGER_H
18 #define ANDROID_MEDIA_TRANSCODING_CLIENT_MANAGER_H
19 
20 #include <aidl/android/media/BnTranscodingServiceClient.h>
21 #include <android/binder_ibinder.h>
22 #include <sys/types.h>
23 #include <utils/Condition.h>
24 #include <utils/RefBase.h>
25 #include <utils/String8.h>
26 #include <utils/Vector.h>
27 
28 #include <mutex>
29 #include <unordered_map>
30 
31 namespace android {
32 
33 using ::aidl::android::media::ITranscodingServiceClient;
34 
35 class MediaTranscodingService;
36 
37 /*
38  * TranscodingClientManager manages all the transcoding clients across different processes.
39  *
40  * TranscodingClientManager is a global singleton that could only acquired by
41  * MediaTranscodingService. It manages all the clients's registration/unregistration and clients'
42  * information. It also bookkeeps all the clients' information. It also monitors to the death of the
43  * clients. Upon client's death, it will remove the client from it.
44  *
45  * TODO(hkuang): Hook up with ResourceManager for resource management.
46  * TODO(hkuang): Hook up with MediaMetrics to log all the transactions.
47  */
48 class TranscodingClientManager {
49    public:
50     virtual ~TranscodingClientManager();
51 
52     /**
53      * ClientInfo contains a single client's information.
54      */
55     struct ClientInfo {
56         /* The remote client that this ClientInfo is associated with. */
57         std::shared_ptr<ITranscodingServiceClient> mClient;
58         /* A unique positive Id assigned to the client by the service. */
59         int32_t mClientId;
60         /* Process id of the client */
61         int32_t mClientPid;
62         /* User id of the client. */
63         int32_t mClientUid;
64         /* Package name of the client. */
65         std::string mClientOpPackageName;
66 
ClientInfoClientInfo67         ClientInfo(const std::shared_ptr<ITranscodingServiceClient>& client, int64_t clientId,
68                    int32_t pid, int32_t uid, const std::string& opPackageName)
69             : mClient(client),
70               mClientId(clientId),
71               mClientPid(pid),
72               mClientUid(uid),
73               mClientOpPackageName(opPackageName) {}
74     };
75 
76     /**
77      * Adds a new client to the manager.
78      *
79      * The client must have valid clientId, pid, uid and opPackageName, otherwise, this will return
80      * a non-zero errorcode. If the client has already been added, it will also return non-zero
81      * errorcode.
82      *
83      * @param client to be added to the manager.
84      * @return 0 if client is added successfully, non-zero errorcode otherwise.
85      */
86     status_t addClient(std::unique_ptr<ClientInfo> client);
87 
88     /**
89      * Removes an existing client from the manager.
90      *
91      * If the client does not exist, this will return non-zero errorcode.
92      *
93      * @param clientId id of the client to be removed..
94      * @return 0 if client is removed successfully, non-zero errorcode otherwise.
95      */
96     status_t removeClient(int32_t clientId);
97 
98     /**
99      * Gets the number of clients.
100      */
101     size_t getNumOfClients() const;
102 
103     /**
104      * Checks if a client with clientId is already registered.
105      */
106     bool isClientIdRegistered(int32_t clientId) const;
107 
108     /**
109      * Dump all the client information to the fd.
110      */
111     void dumpAllClients(int fd, const Vector<String16>& args);
112 
113    private:
114     friend class MediaTranscodingService;
115     friend class TranscodingClientManagerTest;
116 
117     /** Get the singleton instance of the TranscodingClientManager. */
118     static TranscodingClientManager& getInstance();
119 
120     TranscodingClientManager();
121 
122     static void BinderDiedCallback(void* cookie);
123 
124     mutable std::mutex mLock;
125     std::unordered_map<int32_t, std::unique_ptr<ClientInfo>> mClientIdToClientInfoMap
126             GUARDED_BY(mLock);
127 
128     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
129 };
130 
131 }  // namespace android
132 #endif  // ANDROID_MEDIA_TRANSCODING_SERVICE_H
133