1 /*
2 * Copyright (c) 2021-2022 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 #include "base_obj.h"
17
18 #include <cstdio>
19
20 #include "securec.h"
21
22 #include "light_refbase.h"
23
24 namespace OHOS {
25 namespace AAFwk {
26 const InterfaceID g_IID_IObject = {
27 0x8321f710, 0xa0c0, 0x4cbe, 0xbfbc, {0x5, 0xa, 0x7, 0x8, 0xf, 0x1, 0x3, 0x1, 0x2, 0xb, 0x1, 0xb}
28 };
29
30 const InterfaceID g_IID_IWeakReference = {
31 0x26ab1978, 0x1d11, 0x4a4f, 0x826d, {0x6, 0x1, 0x7, 0x8, 0x5, 0xc, 0x0, 0x4, 0x8, 0xc, 0xc, 0xa}
32 };
33
34 const InterfaceID g_IID_IWeakReferenceSource = {
35 0xbc3f5250, 0x34d7, 0x42d2, 0x9b40, {0xf, 0xf, 0xc, 0xe, 0x8, 0x3, 0xf, 0xd, 0x4, 0x0, 0x6, 0x1}
36 };
37
38 class WeakReferenceImpl final : public LightRefCountBase, public IWeakReference {
39 public:
WeakReferenceImpl(IInterface * object,WeakRefCounter * wkRef)40 WeakReferenceImpl(IInterface *object, WeakRefCounter *wkRef) : object_(object), wkRef_(wkRef)
41 {}
42
~WeakReferenceImpl()43 virtual ~WeakReferenceImpl()
44 {}
45
46 void IncStrongRef(const void *id = nullptr) override;
47
48 void DecStrongRef(const void *id = nullptr) override;
49
50 IInterface *Query(const InterfaceID &iid) override;
51
52 InterfaceID GetInterfaceID(IInterface *object) override;
53
54 ErrCode Resolve(const InterfaceID &iid, IInterface **object) override;
55
56 private:
57 IInterface *object_ = nullptr;
58 WeakRefCounter *wkRef_ = nullptr;
59 };
60
IncStrongRef(const void * id)61 void WeakReferenceImpl::IncStrongRef(const void *id)
62 {
63 LightRefCountBase::IncStrongRef(id);
64 }
65
DecStrongRef(const void * id)66 void WeakReferenceImpl::DecStrongRef(const void *id)
67 {
68 LightRefCountBase::DecStrongRef(id);
69 }
70
Query(const InterfaceID & iid)71 IInterface *WeakReferenceImpl::Query(const InterfaceID &iid)
72 {
73 if ((iid == g_IID_IWeakReference) || (iid == g_IID_IInterface)) {
74 return static_cast<IWeakReference *>(this);
75 }
76 return nullptr;
77 }
78
GetInterfaceID(IInterface * object)79 InterfaceID WeakReferenceImpl::GetInterfaceID(IInterface *object)
80 {
81 if (object == static_cast<IWeakReference *>(this)) {
82 return g_IID_IWeakReference;
83 }
84 return InterfaceID::Empty;
85 }
86
Resolve(const InterfaceID & iid,IInterface ** object)87 ErrCode WeakReferenceImpl::Resolve(const InterfaceID &iid, IInterface **object)
88 {
89 VALIDATE_NOT_NULL(object);
90
91 if ((object_ != nullptr) && wkRef_->AttemptIncStrongRef(this)) {
92 *object = object_->Query(iid);
93 if (*object == nullptr) {
94 object_->DecStrongRef(this);
95 }
96 } else {
97 *object = nullptr;
98 }
99 return ERR_OK;
100 }
101
IncStrongRef(const void * id)102 void Object::IncStrongRef(const void *id)
103 {
104 RefBase::IncStrongRef(id);
105 }
106
DecStrongRef(const void * id)107 void Object::DecStrongRef(const void *id)
108 {
109 RefBase::DecStrongRef(id);
110 }
111
Query(const InterfaceID & iid)112 IInterface *Object::Query(const InterfaceID &iid)
113 {
114 if (iid == g_IID_IObject) {
115 return static_cast<IObject *>(this);
116 }
117 if (iid == g_IID_IWeakReferenceSource) {
118 return static_cast<IWeakReferenceSource *>(this);
119 }
120 if (iid == g_IID_IInterface) {
121 return static_cast<IWeakReferenceSource *>(this);
122 }
123 return nullptr;
124 }
125
GetInterfaceID(IInterface * object)126 InterfaceID Object::GetInterfaceID(IInterface *object)
127 {
128 if (object == static_cast<IObject *>(this)) {
129 return g_IID_IObject;
130 }
131 if (object == static_cast<IWeakReferenceSource *>(this)) {
132 return g_IID_IWeakReferenceSource;
133 }
134 return InterfaceID::Empty;
135 }
136
GetClassID()137 ClassID Object::GetClassID()
138 {
139 return ClassID::Empty;
140 }
141
GetHashCode()142 int Object::GetHashCode()
143 {
144 return reinterpret_cast<HANDLE>(this);
145 }
146
Equals(IObject & other)147 bool Object::Equals(IObject &other)
148 {
149 Object *otherObj = nullptr;
150 otherObj = static_cast<Object *>(&other);
151 return this == otherObj;
152 }
153
GetWeakReference(sptr<IWeakReference> & weakRef)154 ErrCode Object::GetWeakReference(sptr<IWeakReference> &weakRef)
155 {
156 void *addr = calloc(sizeof(WeakReferenceImpl), 1);
157 if (addr == nullptr) {
158 return ERR_NO_MEMORY;
159 }
160 weakRef = new (addr) WeakReferenceImpl(static_cast<IObject *>(this), CreateWeakRef(addr));
161 return ERR_OK;
162 }
163
ToString()164 std::string Object::ToString()
165 {
166 static constexpr int BUFFER_MAX = 1024;
167 std::string str("");
168 char *buf = new (std::nothrow) char[BUFFER_MAX];
169 if (buf != nullptr) {
170 int ret = snprintf_s(buf, BUFFER_MAX, BUFFER_MAX - 1, "[Object %p]", this);
171 if (ret >= 0) {
172 str = buf;
173 }
174 delete[] buf;
175 buf = nullptr;
176 }
177 return str;
178 }
179
Equals(IInterface & obj1,IInterface & obj2)180 bool Object::Equals(IInterface &obj1, IInterface &obj2)
181 {
182 if (IInterface::Query(&obj1) == IInterface::Query(&obj2)) {
183 return true;
184 }
185
186 IObject *o1 = IObject::Query(obj1);
187 if (o1 == nullptr) {
188 return false;
189 }
190 return o1->Equals(*(IObject::Query(obj2)));
191 }
192
ToString(IInterface & object)193 std::string Object::ToString(IInterface &object)
194 {
195 IObject *obj = IObject::Query(object);
196 return ((obj != nullptr) ? obj->ToString() : "");
197 }
198 } // namespace AAFwk
199 } // namespace OHOS