• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2023 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_SERVICES_DBINDER_DBINDER_SERVICE_H
17 #define OHOS_IPC_SERVICES_DBINDER_DBINDER_SERVICE_H
18 
19 #include <string>
20 #include <map>
21 #include <mutex>
22 #include <shared_mutex>
23 #include <memory>
24 #include <list>
25 #include <thread>
26 
27 #include "dbinder_service_stub.h"
28 #include "ipc_object_proxy.h"
29 #include "ipc_object_stub.h"
30 #include "rpc_system_ability_callback.h"
31 #include "Session.h"
32 #include "thread_pool.h"
33 
34 using Communication::SoftBus::Session;
35 
36 namespace OHOS {
37 class DBinderRemoteListener;
38 
39 constexpr int DEVICEID_LENGTH = 64;
40 constexpr int SERVICENAME_LENGTH = 200;
41 
42 /* version change history
43  * a) 1 --> 2, support transfer tokenid to peer device
44  */
45 constexpr int RPC_TOKENID_SUPPORT_VERSION = 2;
46 constexpr int ENCRYPT_HEAD_LEN = 28;
47 constexpr int ENCRYPT_LENGTH = 4;
48 
49 // Description of the device identification information parameter.
50 struct DeviceIdInfo {
51     uint32_t tokenId;
52     char fromDeviceId[DEVICEID_LENGTH + 1];
53     char toDeviceId[DEVICEID_LENGTH + 1];
54 };
55 
56 // Description of the DHandle entry head parameter.
57 struct DHandleEntryHead {
58     uint32_t len;
59     uint32_t version;
60 };
61 
62 // Description of the DHandle entry TxRx parameter.
63 struct DHandleEntryTxRx {
64     struct DHandleEntryHead head;
65     uint32_t transType;
66     uint32_t dBinderCode;
67     uint16_t fromPort;
68     uint16_t toPort;
69     uint64_t stubIndex;
70     uint32_t seqNumber;
71     binder_uintptr_t binderObject;
72     struct DeviceIdInfo deviceIdInfo;
73     binder_uintptr_t stub;
74     uint16_t serviceNameLength;
75     char serviceName[SERVICENAME_LENGTH + 1];
76     uint32_t pid;
77     uint32_t uid;
78 };
79 
80 // SessionInfo parameter description.
81 struct SessionInfo {
82     uint32_t seqNumber;
83     uint32_t type;
84     uint16_t toPort;
85     uint16_t fromPort;
86     uint64_t stubIndex;
87     uint32_t socketFd;
88     std::string serviceName;
89     struct DeviceIdInfo deviceIdInfo;
90 };
91 
92 // Enumerate DBinder message codes.
93 enum DBinderCode {
94     MESSAGE_AS_INVOKER          = 1,
95     MESSAGE_AS_REPLY            = 2,
96     MESSAGE_AS_OBITUARY         = 3,
97     MESSAGE_AS_REMOTE_ERROR     = 4,
98     MESSAGE_AS_REPLY_TOKENID    = 5,
99 };
100 
101 // Enumerate the returned DBinder error codes.
102 enum DBinderErrorCode {
103     DBINDER_OK                  = 100,
104     STUB_INVALID                = 101,
105     SEND_MESSAGE_FAILED         = 102,
106     MAKE_THREADLOCK_FAILED      = 103,
107     WAIT_REPLY_TIMEOUT          = 104,
108     QUERY_REPLY_SESSION_FAILED  = 105,
109     SA_NOT_FOUND                = 106,
110     SA_INVOKE_FAILED            = 107,
111     DEVICEID_INVALID            = 108,
112     SESSION_NAME_NOT_FOUND      = 109,
113     WRITE_PARCEL_FAILED         = 110,
114     INVOKE_STUB_THREAD_FAILED   = 111,
115     SESSION_NAME_INVALID        = 112,
116 };
117 
118 // Description of thread locking information parameters.
119 struct ThreadLockInfo {
120     std::mutex mutex;
121     std::string networkId;
122     std::condition_variable condition;
123     bool ready = false;
124 };
125 
126 class DBinderService : public virtual RefBase {
127 public:
128     DBinderService();
129     virtual ~DBinderService();
130 public:
131 
132     /**
133      * @brief Obtains an instance.
134      * @return Returns a DBinderService type pointer object.
135      * @since 9
136      */
137     static sptr<DBinderService> GetInstance();
138 
139     /**
140      * @brief Convert device ID to security string for printing.
141      * @param deviceID Indicates the device ID to be converted.
142      * @return Returns the converted security device ID.
143      * @since 9
144      */
145     static std::string ConvertToSecureDeviceID(const std::string &deviceID);
146 
147     /**
148      * @brief Start the DBinder service.
149      * @param callbackImpl Indicates a callback of type RpcSystemAbilityCallback.
150      * @return Returns <b>true</b> if the service started successfully; returns <b>false</b> otherwise.
151      * @since 9
152      */
153     bool StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl);
154 
155     /**
156      * @brief Make a remote binding.
157      * @param serviceName Indicates the service name.
158      * @param deviceID Indicates the device ID.
159      * @param binderObject Indicates the object to be binder.
160      * @param pid Indicates the value of pid.
161      * @param uid Indicates the value of uid.
162      * @return Returns the DBinderServiceStuble pointer object.
163      * @since 9
164      */
165     sptr<DBinderServiceStub> MakeRemoteBinder(const std::u16string &serviceName,
166         const std::string &deviceID, int32_t binderObject, uint32_t pid = 0, uint32_t uid = 0);
167 
168     /**
169      * @brief Register the remote agent.
170      * @param serviceName Indicates the service name.
171      * @param binderObject Indicates the IRemoteObject pointer object to be binder.
172      * @return Returns <b>true</b> if the registration successful; returns <b>false</b> otherwise.
173      * @since 9
174      */
175     bool RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject);
176 
177     /**
178      * @brief Register the remote agent.
179      * @param serviceName Indicates the service name.
180      * @param systemAbilityId Indicatesthe system ability ID.
181      * @return Returns <b>true</b> if the registration successful; returns <b>false</b> otherwise.
182      * @since 9
183      */
184     bool RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId);
185 
186     /**
187      * @brief Processing remote messaging tasks.
188      * @param message Indicates the delivered message belongs to the DHandleEntryTxR structure.
189      * @return Returns <b>true</b> if the processing is successful; returns <b>false</b> otherwise.
190      * @since 9
191      */
192     bool OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message);
193 
194     /**
195      * @brief Register an asynchronous message task.
196      * @param message Indicates the delivered message belongs to the DHandleEntryTxR structure.
197      * @return void
198      * @since 9
199      */
200     void AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message);
201 
202     /**
203      * @brief Query the session object.
204      * @param stub Indicates a stub that can be used to query a session object.
205      * @return The returned result belongs to the SessionInfo structure.
206      * @since 9
207      */
208     std::shared_ptr<struct SessionInfo> QuerySessionObject(binder_uintptr_t stub);
209 
210     /**
211      * @brief Detach the remote object death notification.
212      * @param object Indicates the IRemoteObject pointer object.
213      * @return Returns <b>true</b> if the registration successful; returns <b>false</b> otherwise.
214      * @since 9
215      */
216     bool DetachDeathRecipient(sptr<IRemoteObject> object);
217 
218     /**
219      * @brief Attach the remote object death notification.
220      * @param object Indicates the IRemoteObject pointer object.
221      * @param deathRecipient Indicates the the callback to attach.
222      * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise.
223      * @since 9
224      */
225     bool AttachDeathRecipient(sptr<IRemoteObject> object, sptr<IRemoteObject::DeathRecipient> deathRecipient);
226 
227     /**
228      * @brief Query the remote object death notification.
229      * @param object Indicates the IRemoteObject pointer object.
230      * @return Returns the results of the found death notice.
231      * @since 9
232      */
233     sptr<IRemoteObject::DeathRecipient> QueryDeathRecipient(sptr<IRemoteObject> object);
234 
235     /**
236      * @brief Detach the callback proxy object.
237      * @param object Indicates the IRemoteObject pointer object.
238      * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise.
239      * @since 9
240      */
241     bool DetachCallbackProxy(sptr<IRemoteObject> object);
242 
243     /**
244      * @brief Attach the callback proxy object.
245      * @param object Indicates the IRemoteObject pointer object.
246      * @param dbStub Indicates a service communication stub across devices.
247      * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise.
248      * @since 9
249      */
250     bool AttachCallbackProxy(sptr<IRemoteObject> object, DBinderServiceStub *dbStub);
251 
252     /**
253      * @brief Notification service death.
254      * @param serviceName Indicates the service name.
255      * @param deviceID Indicates the device ID.
256      * @return Returns {@code ERR_NONE} if valid notifications; returns an error code if the operation fails.
257      * @since 9
258      */
259     int32_t NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID);
260 
261     /**
262      * @brief Notification device death.
263      * @param deviceID Indicates the device ID.
264      * @return Returns {@code ERR_NONE} if valid notifications; returns an error code if the operation fails.
265      * @since 9
266      */
267     int32_t NoticeDeviceDie(const std::string &deviceID);
268 
269     /**
270      * @brief Create a databus(Dbinder) name.
271      * @param uid Indicates the UID of databus(Dbinder).
272      * @param pid Indicates the PID of databus(Dbinder).
273      * @return Returns the corresponding sessionName.
274      * @since 9
275      */
276     std::string CreateDatabusName(int uid, int pid);
277 
278     /**
279      * @brief Detach the proxy object.
280      * @param binderObject Indicates the object to which it is bound.
281      * @return Returns <b>true</b> if the operation succeeds; returns <b>false</b> otherwise.
282      * @since 9
283      */
284     bool DetachProxyObject(binder_uintptr_t binderObject);
285 
286     /**
287      * @brief A callback when a system ability is loaded completely.
288      * @param srcNetworkId Indicates The network ID of the path.
289      * @param systemAbilityId Indicates system capability ID.
290      * @param remoteObject Indicates a remote object.
291      * @return void
292      * @since 9
293      */
294     void LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId,
295         const sptr<IRemoteObject>& remoteObject);
296 
297     /**
298      * @brief Close the process session.
299      * @param session Indicates the session to close.
300      * @return Returns <b>true</b> if the shutdown is successful; returns <b>false</b> otherwise.
301      * @since 9
302      */
303     bool ProcessOnSessionClosed(std::shared_ptr<Session> session);
304 
305 private:
306     static std::shared_ptr<DBinderRemoteListener> GetRemoteListener();
307     static bool StartRemoteListener();
308     static void StopRemoteListener();
309     std::u16string GetRegisterService(binder_uintptr_t binderObject);
310     int32_t InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid, uint32_t uid);
311     bool OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage);
312     bool OnRemoteErrorMessage(const struct DHandleEntryTxRx *replyMessage);
313     void MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage);
314     bool OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message);
315     void WakeupThreadByStub(uint32_t seqNumber);
316     void DetachThreadLockInfo(uint32_t seqNumber);
317     bool AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId,
318         std::shared_ptr<struct ThreadLockInfo> object);
319     std::shared_ptr<struct ThreadLockInfo> QueryThreadLockInfo(uint32_t seqNumber);
320     bool AttachProxyObject(sptr<IRemoteObject> object, binder_uintptr_t binderObject);
321     sptr<IRemoteObject> QueryProxyObject(binder_uintptr_t binderObject);
322     bool DetachSessionObject(binder_uintptr_t stub);
323     bool AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub);
324     sptr<IRemoteObject> FindOrNewProxy(binder_uintptr_t binderObject, int32_t systemAbilityId);
325     bool SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid, uint32_t uid);
326     uint16_t AllocFreeSocketPort();
327     std::string GetLocalDeviceID();
328     binder_uintptr_t AddStubByTag(binder_uintptr_t stub);
329     binder_uintptr_t QueryStubPtr(binder_uintptr_t stub);
330     bool CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t binderObject);
331     bool HasDBinderStub(binder_uintptr_t binderObject);
332     bool IsSameStubObject(const sptr<DBinderServiceStub> &stub, const std::u16string &service,
333         const std::string &device);
334     sptr<DBinderServiceStub> FindDBinderStub(const std::u16string &service, const std::string &device);
335     bool DeleteDBinderStub(const std::u16string &service, const std::string &device);
336     sptr<DBinderServiceStub> FindOrNewDBinderStub(const std::u16string &service,
337         const std::string &device, binder_uintptr_t binderObject);
338     void ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub);
339     bool NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub);
340     std::list<std::u16string> FindServicesByDeviceID(const std::string &deviceID);
341     int32_t NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID);
342     uint32_t GetRemoteTransType();
343     uint32_t OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage,
344         std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId);
345     bool IsDeviceIdIllegal(const std::string &deviceID);
346     std::string GetDatabusNameByProxy(IPCObjectProxy *proxy);
347     uint32_t GetSeqNumber();
348     bool StartThreadPool();
349     bool StopThreadPool();
350     bool AddAsynTask(const ThreadPool::Task &f);
351     bool IsSameSession(std::shared_ptr<struct SessionInfo> oldSession, std::shared_ptr<struct SessionInfo> newSession);
352     bool RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder);
353     bool CheckSystemAbilityId(int32_t systemAbilityId);
354     bool HandleInvokeListenThread(IPCObjectProxy *proxy, uint64_t stubIndex, std::string serverSessionName,
355         struct DHandleEntryTxRx *replyMessage);
356     bool ReStartRemoteListener();
357     bool IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId,
358         std::shared_ptr<DHandleEntryTxRx> loadSaItem);
359     std::shared_ptr<struct DHandleEntryTxRx> PopLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId);
360     void SendMessageToRemote(uint32_t dBinderCode, uint32_t reason,
361         std::shared_ptr<struct DHandleEntryTxRx> replyMessage);
362 
363 private:
364     DISALLOW_COPY_AND_MOVE(DBinderService);
365     static std::mutex instanceMutex_;
366     static constexpr int WAIT_FOR_REPLY_MAX_SEC = 8;
367     static constexpr int RETRY_TIMES = 2;
368     static std::shared_ptr<DBinderRemoteListener> remoteListener_;
369     static bool mainThreadCreated_;
370     static sptr<DBinderService> instance_;
371 
372     std::shared_mutex remoteBinderMutex_;
373     std::shared_mutex proxyMutex_;
374     std::shared_mutex deathRecipientMutex_;
375     std::shared_mutex sessionMutex_;
376     std::shared_mutex loadSaMutex_;
377 
378     std::mutex handleEntryMutex_;
379     std::mutex threadLockMutex_;
380     std::mutex callbackProxyMutex_;
381     std::mutex deathNotificationMutex_;
382     std::mutex threadPoolMutex_;
383 
384     uint32_t seqNumber_ = 0; /* indicate make remote binder message sequence number, and can be overflow */
385 
386     /* indicate the stub flag used for negotiation with the peer end, and can be overflow */
387     binder_uintptr_t stubTagNum_ = 1;
388     std::map<binder_uintptr_t, binder_uintptr_t> mapDBinderStubRegisters_;
389     std::list<sptr<DBinderServiceStub>> DBinderStubRegisted_;
390     std::map<std::u16string, binder_uintptr_t> mapRemoteBinderObjects_;
391     std::map<uint32_t, std::shared_ptr<struct ThreadLockInfo>> threadLockInfo_;
392     std::map<int, sptr<IRemoteObject>> proxyObject_;
393     std::map<binder_uintptr_t, std::shared_ptr<struct SessionInfo>> sessionObject_;
394     std::map<sptr<IRemoteObject>, DBinderServiceStub *> noticeProxy_;
395     std::map<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>> deathRecipients_;
396     bool threadPoolStarted_ = false;
397     int32_t threadPoolNumber_ = 4;
398     std::unique_ptr<ThreadPool> threadPool_ = nullptr;
399     std::list<std::shared_ptr<struct DHandleEntryTxRx>> loadSaReply_;
400     static constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000001;
401     static constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
402 
403     std::shared_ptr<RpcSystemAbilityCallback> dbinderCallback_;
404 };
405 } // namespace OHOS
406 #endif // OHOS_IPC_SERVICES_DBINDER_DBINDER_SERVICE_H
407