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 ®istration = 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 ®istration = 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 ®istration = 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