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_IREMOTE_BROKER_H
17 #define OHOS_IPC_IREMOTE_BROKER_H
18 
19 #include <unordered_map>
20 #include <functional>
21 #include <vector>
22 #include "iremote_object.h"
23 #include "refbase.h"
24 
25 namespace OHOS {
26 template <typename T> class BrokerCreator {
27 public:
28     BrokerCreator() = default;
29     ~BrokerCreator() = default;
operator()30     sptr<IRemoteBroker> operator () (const sptr<IRemoteObject> &object)
31     {
32         T *proxy = new (std::nothrow) T(object);
33         if (proxy != nullptr) {
34             return static_cast<IRemoteBroker *>(proxy);
35         }
36         return nullptr;
37     };
38 };
39 
40 class IRemoteBroker : public virtual RefBase {
41 public:
42     IRemoteBroker() = default;
43     virtual ~IRemoteBroker() override = default;
44 
45     /**
46      * @brief Obtains a proxy or remote object.
47      * @return Returns the RemoteObject if the caller is a RemoteObject;
48      * returns the IRemoteObject if the caller is a RemoteProxy object.
49      * @since 9
50      */
51     virtual sptr<IRemoteObject> AsObject() = 0;
52 };
53 
54 class BrokerDelegatorBase {
55 public:
56     BrokerDelegatorBase() = default;
57     virtual ~BrokerDelegatorBase() = default;
58 
59 public:
60     bool isSoUnloaded = false;
61     std::u16string descriptor_;
62 };
63 
64 #define DECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR)                         \
65     static constexpr const char16_t *metaDescriptor_ = DESCRIPTOR;       \
66     static inline const std::u16string GetDescriptor()                  \
67     {                                                                    \
68         return metaDescriptor_;                                          \
69     }
70 
71 class BrokerRegistration {
72     using Constructor = std::function<sptr<IRemoteBroker>(const sptr<IRemoteObject> &object)>;
73 
74 public:
75     /**
76      * @brief Get broker registered.
77      * @return Returns the BrokerRegistration instance.
78      * @since 9
79      */
80     static BrokerRegistration &Get();
81 
82     /**
83      * @brief Register the broker.
84      * @param descriptor Indicates a descriptor the type of string.
85      * @param creator Indicates the constructor.
86      * @param object Indicates an object of type BrokerDelegatorBase.
87      * @return Returns <b>true</b> if registration is successful; returns <b>false</b> otherwise.
88      * @since 9
89      */
90     bool Register(const std::u16string &descriptor, const Constructor &creator, const BrokerDelegatorBase *object);
91 
92     /**
93      * @brief Deregister the broker.
94      * @param descriptor Indicates a descriptor the type of string.
95      * @return void
96      * @since 9
97      */
98     void Unregister(const std::u16string &descriptor);
99 
100     /**
101      * @brief Obtains the new instance object.
102      * @param descriptor Indicates a descriptor the type of string.
103      * @param object Indicates an IRemoteObject pointer object.
104      * @return Returns an IRemoteBroker pointer object.
105      * @since 9
106      */
107     sptr<IRemoteBroker> NewInstance(const std::u16string &descriptor, const sptr<IRemoteObject> &object);
108 
109 protected:
110     BrokerRegistration() = default;
111     ~BrokerRegistration();
112 
113 private:
114     BrokerRegistration(const BrokerRegistration &) = delete;
115     BrokerRegistration(BrokerRegistration &&) = delete;
116     BrokerRegistration &operator = (const BrokerRegistration &) = delete;
117     BrokerRegistration &operator = (BrokerRegistration &&) = delete;
118     std::mutex creatorMutex_;
119     std::unordered_map<std::u16string, Constructor> creators_;
120     std::vector<uintptr_t> objects_;
121     std::atomic<bool> isUnloading = false;
122 };
123 
124 template <typename T> class BrokerDelegator : public BrokerDelegatorBase {
125 public:
126     BrokerDelegator();
127     ~BrokerDelegator() override;
128 
129 private:
130     BrokerDelegator(const BrokerDelegator &) = delete;
131     BrokerDelegator(BrokerDelegator &&) = delete;
132     BrokerDelegator &operator = (const BrokerDelegator &) = delete;
133     BrokerDelegator &operator = (BrokerDelegator &&) = delete;
134     std::mutex regMutex_;
135 };
136 
BrokerDelegator()137 template <typename T> BrokerDelegator<T>::BrokerDelegator()
138 {
139     std::lock_guard<std::mutex> lockGuard(regMutex_);
140     const std::u16string descriptor = T::GetDescriptor();
141     BrokerRegistration &registration = BrokerRegistration::Get();
142     if (registration.Register(descriptor, BrokerCreator<T>(), this)) {
143         descriptor_ = T::GetDescriptor();
144     }
145 }
146 
~BrokerDelegator()147 template <typename T> BrokerDelegator<T>::~BrokerDelegator()
148 {
149     std::lock_guard<std::mutex> lockGuard(regMutex_);
150     if (!isSoUnloaded && !descriptor_.empty()) {
151         BrokerRegistration &registration = BrokerRegistration::Get();
152         registration.Unregister(descriptor_);
153     }
154 }
155 
iface_cast(const sptr<IRemoteObject> & object)156 template <typename INTERFACE> inline sptr<INTERFACE> iface_cast(const sptr<IRemoteObject> &object)
157 {
158     const std::u16string descriptor = INTERFACE::GetDescriptor();
159     BrokerRegistration &registration = BrokerRegistration::Get();
160     sptr<IRemoteBroker> broker = registration.NewInstance(descriptor, object);
161     return static_cast<INTERFACE *>(broker.GetRefPtr());
162 }
163 } // namespace OHOS
164 #endif // OHOS_IPC_IREMOTE_BROKER_H
165