• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_IPC_IPC_PROCESS_SKELETON_H
17 #define OHOS_IPC_IPC_PROCESS_SKELETON_H
18 
19 #include <atomic>
20 #include <list>
21 #include <map>
22 #include <shared_mutex>
23 
24 #include "invoker_rawdata.h"
25 #include "ipc_object_proxy.h"
26 #include "ipc_object_stub.h"
27 #include "ipc_thread_pool.h"
28 #include "iremote_object.h"
29 #include "nocopyable.h"
30 #include "sys_binder.h"
31 
32 #ifndef CONFIG_IPC_SINGLE
33 #include "comm_auth_info.h"
34 #include "dbinder_callback_stub.h"
35 #include "dbinder_session_object.h"
36 #include "dbinder_softbus_client.h"
37 #include "stub_refcount_object.h"
38 #endif
39 
40 namespace OHOS {
41 #ifdef CONFIG_IPC_SINGLE
42 namespace IPC_SINGLE {
43 #endif
44 #ifndef CONFIG_IPC_SINGLE
45 struct SocketThreadLockInfo {
46     std::mutex mutex;
47     std::condition_variable condition;
48     bool ready = false;
49 };
50 
51 struct ThreadMessageInfo {
52     uint32_t flags;
53     binder_size_t bufferSize;
54     binder_size_t offsetsSize;
55     binder_uintptr_t offsets;
56     uint32_t socketId;
57     void *buffer;
58     std::mutex mutex;
59     std::condition_variable condition;
60     bool ready;
61 };
62 
63 struct ThreadProcessInfo {
64     int32_t listenFd;
65     uint32_t packageSize;
66     std::shared_ptr<char> buffer;
67 };
68 
69 struct AppAuthInfo {
70     uint32_t pid;
71     uint32_t uid;
72     uint32_t tokenId;
73     int32_t socketId;
74     uint64_t stubIndex;
75     IRemoteObject *stub;
76     std::string deviceId;
77 };
78 #endif
79 
80 class IPCProcessSkeleton {
81 public:
82     enum {
83         LISTEN_THREAD_CREATE_OK, // Invoker family.
84         LISTEN_THREAD_CREATE_FAILED,
85         LISTEN_THREAD_CREATED_ALREADY,
86         LISTEN_THREAD_CREATED_TIMEOUT
87     };
88     ~IPCProcessSkeleton();
89 
90     static IPCProcessSkeleton *GetCurrent();
91     static std::string ConvertToSecureString(const std::string &str);
GetIPCRuntimeInfo()92     static inline const char *GetIPCRuntimeInfo()
93     {
94 #ifndef CONFIG_IPC_SINGLE
95         return "ipc_core";
96 #else
97         return "ipc_single";
98 #endif
99     };
100 
101 #ifndef CONFIG_IPC_SINGLE
102     static uint32_t ConvertChannelID2Int(int64_t databusChannelId);
103     static bool IsHandleMadeByUser(uint32_t handle);
104 #endif
105     bool SetIPCProxyLimit(uint64_t num, std::function<void(uint64_t num)> callback);
106     bool SetMaxWorkThread(int maxThreadNum);
107     std::u16string MakeHandleDescriptor(int handle);
108 
109     bool OnThreadTerminated(const std::string &threadName);
110     bool SpawnThread(int policy = IPCWorkThread::SPAWN_PASSIVE, int proto = IRemoteObject::IF_PROT_DEFAULT);
111 
112     sptr<IRemoteObject> FindOrNewObject(int handle, const dbinder_negotiation_data *dbinderData = nullptr);
113     bool IsContainsObject(IRemoteObject *object);
114     sptr<IRemoteObject> QueryObject(const std::u16string &descriptor, bool lockFlag = true);
115     bool AttachObject(IRemoteObject *object, bool lockFlag = true);
116     bool DetachObject(IRemoteObject *object);
117     sptr<IRemoteObject> GetProxyObject(int handle, bool &newFlag);
118 
119     sptr<IRemoteObject> GetRegistryObject();
120     bool SetRegistryObject(sptr<IRemoteObject> &object);
121     void BlockUntilThreadAvailable();
122     void LockForNumExecuting();
123     void UnlockForNumExecuting();
124 
125 #ifndef CONFIG_IPC_SINGLE
126     bool AttachRawData(int32_t socketId, uint64_t seqNumber, std::shared_ptr<InvokerRawData> rawData);
127     bool DetachRawData(int32_t socketId, uint64_t seqNumber);
128     std::shared_ptr<InvokerRawData> QueryRawData(int32_t socketId, uint64_t seqNumber);
129 
130     sptr<IRemoteObject> GetSAMgrObject();
131     std::shared_ptr<DBinderSessionObject> ProxyDetachDBinderSession(uint32_t handle, IPCObjectProxy *proxy);
132     bool ProxyAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object);
133     std::shared_ptr<DBinderSessionObject> ProxyQueryDBinderSession(uint32_t handle);
134     bool ProxyMoveDBinderSession(uint32_t handle, IPCObjectProxy *proxy);
135     bool QueryProxyBySocketId(int32_t socketId, std::vector<uint32_t> &proxyHandle);
136     std::shared_ptr<DBinderSessionObject> QuerySessionByInfo(const std::string &name, const std::string &deviceId);
137 
138     bool DetachThreadLockInfo(const std::thread::id &threadId);
139     bool AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object, const std::thread::id &threadId);
140     std::shared_ptr<SocketThreadLockInfo> QueryThreadLockInfo(const std::thread::id &threadId);
141     void EraseThreadBySeqNumber(uint64_t seqNumber);
142     bool AddThreadBySeqNumber(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo);
143     std::shared_ptr<ThreadMessageInfo> QueryThreadBySeqNumber(uint64_t seqNumber);
144     bool AddSendThreadInWait(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo, int userWaitTime);
145 
146     int GetSocketIdleThreadNum() const;
147     int GetSocketTotalThreadNum() const;
148     int PopSocketIdFromThread(const std::thread::id &threadId);
149     void WakeUpSocketIOThread(const std::thread::id &threadID);
150     void WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle);
151     IRemoteObject *QueryStubByIndex(uint64_t stubIndex);
152     uint64_t QueryStubIndex(IRemoteObject *stubObject);
153     uint64_t AddStubByIndex(IRemoteObject *stubObject);
154     uint64_t EraseStubIndex(IRemoteObject *stubObject);
155     uint64_t GetSeqNumber();
156     uint32_t GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session);
157     std::string GetLocalDeviceID();
158 
159     bool AttachCallbackStub(IPCObjectProxy *ipcProxy, sptr<IPCObjectStub> callbackStub);
160     sptr<IPCObjectStub> QueryCallbackStub(IPCObjectProxy *ipcProxy);
161     sptr<IPCObjectProxy> QueryCallbackProxy(IPCObjectStub *callbackStub);
162     sptr<IPCObjectStub> DetachCallbackStub(IPCObjectProxy *ipcProxy);
163     uint32_t QueryHandleByDatabusSession(const std::string &name, const std::string &deviceId, uint64_t stubIndex);
164     bool StubDetachDBinderSession(uint32_t handle, uint32_t &tokenId);
165     std::shared_ptr<DBinderSessionObject> StubQueryDBinderSession(uint32_t handle);
166     bool StubAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object);
167     std::string GetDatabusName();
168     bool CreateSoftbusServer(const std::string &name);
169     bool RemoveSoftbusServer();
170 
171     bool AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId);
172     bool DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId);
173     void DetachCommAuthInfoByStub(IRemoteObject *stub);
174     void DetachCommAuthInfoBySocketId(int32_t socketId);
175     bool QueryCommAuthInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId);
176     void UpdateCommAuthSocketInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId,
177         const int32_t socketId);
178     bool AttachOrUpdateAppAuthInfo(const AppAuthInfo &appAuthInfo);
179     bool DetachAppAuthInfo(const AppAuthInfo &appAuthInfo);
180     void DetachAppAuthInfoByStub(IRemoteObject *stub, uint64_t stubIndex);
181     std::list<uint64_t> DetachAppAuthInfoBySocketId(int32_t socketId);
182     bool QueryCommAuthInfo(AppAuthInfo &appAuthInfo);
183     bool QueryAppInfoToStubIndex(const AppAuthInfo &appAuthInfo);
184     bool AddDataThreadToIdle(const std::thread::id &threadId);
185     bool DeleteDataThreadFromIdle(const std::thread::id &threadId);
186     std::thread::id GetIdleDataThread();
187     void AddDataInfoToThread(const std::thread::id &threadId, std::shared_ptr<ThreadProcessInfo> processInfo);
188     std::shared_ptr<ThreadProcessInfo> PopDataInfoFromThread(const std::thread::id &threadId);
189     void WakeUpDataThread(const std::thread::id &threadID);
190     void AddDataThreadInWait(const std::thread::id &threadId);
191     bool IsSameRemoteObject(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, const std::string &deviceId,
192         const std::shared_ptr<CommAuthInfo> &auth);
193     bool IsSameRemoteObject(int pid, int uid, const std::string &deviceId, const std::shared_ptr<CommAuthInfo> &auth);
194     bool DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId,
195         uint64_t stubIndex, int32_t listenFd);
196     std::list<uint64_t> DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId,
197         const std::string &deviceId, int32_t listenFd);
198     void DetachAppInfoToStubIndex(uint64_t stubIndex);
199     std::list<uint64_t> DetachAppInfoToStubIndex(int32_t listenFd);
200     bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId,
201         uint64_t stubIndex, int32_t listenFd);
202     bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId,
203         int32_t listenFd);
204     bool QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, const std::string &deviceId,
205         uint64_t stubIndex, int32_t listenFd);
206     std::string UIntToString(uint32_t input);
207     bool AttachDBinderCallbackStub(sptr<IRemoteObject> rpcProxy, sptr<DBinderCallbackStub> stub);
208     bool DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> rpcProxy);
209     void DetachDBinderCallbackStub(DBinderCallbackStub *stub);
210     sptr<DBinderCallbackStub> QueryDBinderCallbackStub(sptr<IRemoteObject> rpcProxy);
211     sptr<IRemoteObject> QueryDBinderCallbackProxy(sptr<IRemoteObject> stub);
212 #endif
213 
214 public:
215     static constexpr int DEFAULT_WORK_THREAD_NUM = 16;
216     static constexpr uint32_t DBINDER_HANDLE_MAGIC = 6872; // 'D'(Binder) 'H'(andle)
217     static constexpr uint32_t DBINDER_HANDLE_BASE = 100000 * DBINDER_HANDLE_MAGIC;
218     static constexpr uint32_t DBINDER_HANDLE_COUNT = 100000;
219     static constexpr uint32_t DBINDER_HANDLE_RANG = 100;
220     static constexpr int ENCRYPT_LENGTH = 4;
221     static constexpr uint32_t INVALID_HANDLE_VALUE = 0xFFFFFFFF;
222     static constexpr uint32_t THREADS_FULL_TIME_THRESHOLD = 500;    // 500ms
223 
224 private:
225     DISALLOW_COPY_AND_MOVE(IPCProcessSkeleton);
226     IPCProcessSkeleton();
227 #ifndef CONFIG_IPC_SINGLE
228     void ClearDataResource();
229 #endif
230 
231     class DestroyInstance {
232     public:
233         ~DestroyInstance();
234     };
235 
236     static IPCProcessSkeleton *instance_;
237     static std::mutex procMutex_;
238     static DestroyInstance destroyInstance_;
239     static std::atomic<bool> exitFlag_;
240     std::atomic<int> lastErrHandle_ = -1;
241     std::atomic<int> lastErrCnt_ = 0;
242 
243     // for DFX
244     std::mutex mutex_;
245     std::condition_variable cv_;
246     int numExecuting_ = 0;
247     int numWaitingForThreads_ = 0;
248     uint64_t numExecutingFullLastTime_ = 0;
249 
250     IPCWorkThreadPool *threadPool_ = nullptr;
251 
252 #ifndef CONFIG_IPC_SINGLE
253     std::mutex databusProcMutex_;
254 
255     std::mutex idleDataMutex_;
256     std::list<std::thread::id> idleDataThreads_;
257 
258     std::mutex dataQueueMutex_;
259     std::map<std::thread::id, std::vector<std::shared_ptr<ThreadProcessInfo>>> dataInfoQueue_; // key is threadId
260 
261     std::mutex findThreadMutex_;
262     std::map<uint64_t, std::shared_ptr<ThreadMessageInfo>> seqNumberToThread_;
263 
264     std::shared_mutex proxyToSessionMutex_;
265     std::map<uint32_t, std::shared_ptr<DBinderSessionObject>> proxyToSession_;
266 
267     std::shared_mutex rawDataMutex_;
268     std::map<std::string, std::shared_ptr<InvokerRawData>> rawData_;
269 
270     std::shared_mutex databusSessionMutex_;
271     std::map<uint32_t, std::shared_ptr<DBinderSessionObject>> dbinderSessionObjects_;
272 
273     std::shared_mutex threadLockMutex_;
274     std::map<std::thread::id, std::shared_ptr<SocketThreadLockInfo>> threadLockInfo_;
275 
276     std::shared_mutex callbackStubMutex_;
277     std::map<IPCObjectProxy *, sptr<IPCObjectStub>> noticeStub_;
278 
279     std::shared_mutex stubObjectsMutex_;
280     std::unordered_map<uint64_t, IRemoteObject *> stubObjects_;
281 
282     std::shared_mutex appAuthMutex_;
283     std::shared_mutex appInfoToIndexMutex_;
284     std::map<std::string, std::map<uint64_t, int32_t>> appInfoToStubIndex_;
285 
286     std::shared_mutex commAuthMutex_;
287     std::list<std::shared_ptr<CommAuthInfo>> commAuth_;
288 
289     std::shared_mutex dbinderSentMutex_;
290     std::map<sptr<IRemoteObject>, wptr<DBinderCallbackStub>> dbinderSentCallback_;
291 
292     std::mutex seqNumberMutex_;
293     uint64_t seqNumber_ = 0;
294 
295     std::shared_mutex sessionNameMutex_;
296     std::string sessionName_;
297     std::atomic<int32_t> listenSocketId_ = 0;
298 
299     uint32_t dBinderHandle_ = DBINDER_HANDLE_BASE; /* dbinder handle start at 687200000 */
300     uint64_t randNum_;
301 #endif
302 };
303 #ifdef CONFIG_IPC_SINGLE
304 } // namespace IPC_SINGLE
305 #endif
306 } // namespace OHOS
307 #endif // OHOS_IPC_IPC_PROCESS_SKELETON_H
308