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_IPC_OBJECT_PROXY_H
17 #define OHOS_IPC_IPC_OBJECT_PROXY_H
18 
19 #include <dlfcn.h>
20 #include <atomic>
21 #include <mutex>
22 #include <shared_mutex>
23 #include <vector>
24 
25 #include "iremote_object.h"
26 
27 namespace OHOS {
28 #define GET_FIRST_VIRTUAL_FUNC_ADDR(ptr) (*reinterpret_cast<uintptr_t *>(*reinterpret_cast<uintptr_t *>(ptr)))
29 #ifndef CONFIG_IPC_SINGLE
30 struct DBinderNegotiationData {
31     pid_t peerPid;
32     pid_t peerUid;
33     uint32_t peerTokenId;
34     uint64_t stubIndex;
35     std::string peerServiceName;
36     std::string peerDeviceId;
37     std::string localServiceName;
38     std::string localDeviceId;
39 };
40 #endif
41 
42 class IPCObjectProxy : public IRemoteObject {
43 public:
44     explicit IPCObjectProxy(int handle, std::u16string descriptor = std::u16string(),
45         int proto = IRemoteObject::IF_PROT_DEFAULT);
46     ~IPCObjectProxy();
47 
48    /**
49     * @brief Sends message to the peer process in synchronous or asynchronous mode.
50     * @param code Indicates the message code, which is determined by both sides of the communication.
51     * @param data Indicates the object sent to the peer process.
52     * @param reply Indicates the object returned by the peer process.
53     * @param optionoption Indicates the synchronous or asynchronous mode to send messages.
54     * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
55     * defined in {@link ipc_types.h} otherwise.
56     * @since 9
57     */
58     int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &optionoption) override;
59 
60     /**
61      * @brief Determine whether it is a Proxy Object.
62      * @return Returns <b>true</b> if it is Proxy Object; returns <b>false</b> otherwise.
63      * @since 9
64      */
IsProxyObject()65     bool IsProxyObject() const override
66     {
67         return true;
68     };
69 
70     /**
71      * @brief Checks whether an object is dead.
72      * @return Returns <b>true</b> if the object is dead; returns <b>false</b> otherwise.
73      * @since 9
74      */
75     bool IsObjectDead() const override;
76 
77     /**
78      * @brief Obtains the reference count of the object.
79      * @return Returns the reference count.
80      * @since 9
81      */
82     int32_t GetObjectRefCount() override;
83 
84     /**
85      * @brief Dump the contents.
86      * @param fd Indicates the file descriptor.
87      * @param args Indicates a vector containing u16string.
88      * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
89      * defined in {@link ipc_types.h} otherwise.
90      * @since 9
91      */
92     int Dump(int fd, const std::vector<std::u16string> &args) override;
93 
94     /**
95      * @brief The first strong reference provided.
96      * @param objectId Indicates the object Id.
97      * @return void
98      * @since 9
99      */
100     void OnFirstStrongRef(const void *objectId) override;
101 
102     /**
103      * @brief The last strong reference provided.
104      * @param objectId Indicates the object Id.
105      * @return void
106      * @since 9
107      */
108     void OnLastStrongRef(const void *objectId) override;
109 
110     /**
111      * @brief Registered a death recipient.
112      * @param recipient Indicates the recipient of the DeathRecipient pointer.
113      * @return Returns <b>true</b> if the callback is registered successfully; returns <b>false</b> otherwise.
114      * @since 9
115      */
116     bool AddDeathRecipient(const sptr<DeathRecipient> &recipient) override;
117 
118     /**
119      * @brief Unregistered a death recipient.
120      * @param recipient Indicates the recipient of the DeathRecipient pointer.
121      * @return Returns <b>true</b> if the callback is registered successfully; returns <b>false</b> otherwise.
122      * @since 9
123      */
124     bool RemoveDeathRecipient(const sptr<DeathRecipient> &recipient) override;
125 
126     /**
127      * @brief Send Obituary to agents who have registered for death notices.
128      * @return void
129      * @since 9
130      */
131     void SendObituary();
132 
133     /**
134      * @brief Check Subscribe to death notifications.
135      * @return Returns <b>true</b> if the recipients exists; returns <b>false</b> otherwise.
136      * @since 9
137      */
IsSubscribeDeathNotice()138     bool IsSubscribeDeathNotice() const
139     {
140         if (recipients_.empty()) {
141             return false;
142         }
143         return true;
144     };
145 
146     /**
147      * @brief Obtains the handle.
148      * @return Returns handle.
149      * @since 9
150      */
GetHandle()151     uint32_t GetHandle() const
152     {
153         return handle_;
154     };
155 
156     /**
157      * @brief Call the listening thread.
158      * @param data Indicates the object sent to the peer process.
159      * @param reply Indicates the object returned by the peer process.
160      * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
161      * defined in {@link ipc_types.h} otherwise.
162      * @since 9
163      */
164     int InvokeListenThread(MessageParcel &data, MessageParcel &reply);
165 
166     /**
167      * @brief Notification service death.
168      * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
169      * defined in {@link ipc_types.h} otherwise.
170      * @since 9
171      */
172     int32_t NoticeServiceDie();
173 
174     /**
175      * @brief Obtains the corresponding PID and UID.
176      * @param reply Indicates the object returned by the peer process.
177      * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
178      * defined in {@link ipc_types.h} otherwise.
179      * @since 9
180      */
181     int GetPidUid(MessageParcel &reply);
182 
183     /**
184      * @brief Obtains the session name.
185      * @return Returns the session name of type string.
186      * @since 9
187      */
188     std::string GetSessionName();
189 
190     /**
191      * @brief Obtains the session name for PID and UID.
192      * @param uid Indicates the UID value entered.
193      * @param pid Indicates the PID value entered.
194      * @return Returns the PID and UID session name of type string.
195      * @since 9
196      */
197     std::string GetSessionNameForPidUid(uint32_t uid, uint32_t pid);
198 
199     /**
200      * @brief Obtains the grant session name.
201      * @return Returns the grant session name of type string.
202      * @since 9
203      */
204     std::string GetGrantedSessionName();
205 
206     /**
207      * @brief Remove the granted session name.
208      * @param sessionName Indicates the session name that needs to remove.
209      * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
210      * @since 12
211      */
212     int RemoveSessionName(const std::string &sessionName);
213 
214     /**
215      * @brief Obtains the proxy protocol.
216      * @return Returns the obtained proxy protocol.
217      * @since 9
218      */
219     int GetProto() const;
220 
221     /**
222      * @brief Wait for initialization.
223      * @param dbinderData dbinder object data.
224      * @return void
225      * @since 9
226      */
227     void WaitForInit(const void *dbinderData = nullptr);
228 
229     /**
230      * @brief Obtains the interface descriptor.
231      * @return Returns the corresponding interface descriptor.
232      * @since 9
233      */
234     std::u16string GetInterfaceDescriptor() override;
235 
236     /**
237      * @brief get the stub strong ref count.
238      * @return 0 get failed; others the strong ref count of the stub.
239      * @since 11
240      */
241     uint32_t GetStrongRefCountForStub();
242 
243 #ifndef EMULATOR_PLATFORM
244     bool CanPromote() override;
245 #endif
246 
247 private:
248     void SetObjectDied(bool isDied);
249     int SendLocalRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &optionoption);
250     int SendRequestInner(bool isLocal, uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option);
251     void ClearDeathRecipients();
252 
253 #ifndef CONFIG_IPC_SINGLE
254     /**
255      * @brief Set the proxy protocol.
256      * @param proto Indicates a proxy proto.
257      * @return void
258      * @since 9
259      */
260     void SetProto(int proto);
261 
262     /**
263      * @brief Update the proxy protocol.
264      * @return Returns the updated proxy protocol.
265      * @since 9
266      */
267     int UpdateProto();
268 
269     /**
270      * @brief Update the proxy protocol.
271      * @param dbinderData Indicates a dbinder object data.
272      * @return Returns <b>true</b> if the operation is successful; return <b>false</b> otherwise.
273      * @since 12
274      */
275     bool UpdateProto(const void *dbinderData);
276 
277     /**
278      * @brief Release the proxy protocol.
279      * @return void
280      * @since 9
281      */
282     void ReleaseProto();
283 
284     /**
285      * @brief Increase a reference to remote.
286      * @return Returns {@link ERR_NONE} if the operation is successful; returns an error code
287      * defined in {@link ipc_types.h} otherwise.
288      * @since 9
289      */
290     int32_t IncRefToRemote();
291 
292     /**
293      * @brief Obtain proxy protocol information.
294      * @return Returns the status code of the protocol.
295      * @since 9
296      */
297     int GetProtoInfo();
298 
299     /**
300      * @brief Register the Dbinder death recipient.
301      * @return Returns <b>true</b> if the current recipient is not empty; return <b>false</b> otherwise.
302      * @since 9
303      */
304     bool AddDbinderDeathRecipient();
305 
306     /**
307      * @brief Unregister the Dbinder death recipient.
308      * @return Returns <b>true</b> if the current recipient or callback result is not empty;
309      * return <b>false</b> otherwise.
310      * @since 9
311      */
312     bool RemoveDbinderDeathRecipient();
313 
314     /**
315      * @brief Release the databus(Dbinder) protocol.
316      * @return void
317      * @since 9
318      */
319     void ReleaseDatabusProto();
320 
321     /**
322      * @brief Release the binder protocol.
323      * @return void
324      * @since 9
325      */
326     void ReleaseBinderProto();
327 
328     /**
329      * @brief Update the databus(Dbinder) client session name.
330      * @param handle Indicates a handle that needs to update session information.
331      * @param reply Indicates the object returned by the peer process.
332      * @return Returns <b>true</b> if the update is successful; returns <b>false</b> Otherwise.
333      * @since 9
334      */
335     bool UpdateDatabusClientSession(int handle, MessageParcel &reply);
336 
337     /**
338      * @brief Update the databus(Dbinder) client session name.
339      * @return Returns <b>true</b> if the update is successful; returns <b>false</b> Otherwise.
340      * @since 12
341      */
342     bool UpdateDatabusClientSession();
343 
344     /**
345      * @brief Check if there is a session.
346      * @return Returns <b>true</b> if there is currently a session; returns <b>false</b> otherwise.
347      * @since 9
348      */
349     bool CheckHaveSession();
350 
351     int GetDBinderNegotiationData(int handle, MessageParcel &reply, DBinderNegotiationData &dbinderData);
352 
353     int GetDBinderNegotiationData(DBinderNegotiationData &dbinderData);
354 
355     bool MakeDBinderTransSession(const DBinderNegotiationData &data);
356 #endif
357 
358     bool RegisterBinderDeathRecipient();
359     bool UnRegisterBinderDeathRecipient();
360 
361     struct DeathRecipientAddrInfo : public virtual RefBase {
362     public:
363         explicit DeathRecipientAddrInfo(const sptr<DeathRecipient> &recipient);
364 
365         std::string GetNewSoPath();
366         bool IsDlclosed();
367     public:
368         sptr<DeathRecipient> recipient_;
369         void *soFuncAddr_;
370         std::string soPath_;
371     };
372 
373 private:
374     std::mutex initMutex_;
375     std::recursive_mutex mutex_;
376     std::shared_mutex descMutex_;
377 
378     std::vector<sptr<DeathRecipientAddrInfo>> recipients_;
379     const uint32_t handle_;
380     int proto_;
381     bool isFinishInit_;
382     std::atomic<bool> isRemoteDead_;
383     std::u16string remoteDescriptor_;
384     std::u16string interfaceDesc_;
385     std::atomic<int> lastErr_ = 0;
386     std::atomic<int> lastErrCnt_ = 0;
387     std::unique_ptr<uint8_t[]> dbinderData_{nullptr};
388 };
389 } // namespace OHOS
390 #endif // OHOS_IPC_IPC_OBJECT_PROXY_H
391