1 /*
2 * Copyright (c) 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 <thread>
17
18 #include "hitrace.h"
19 #include "distributed_object_impl.h"
20 #include "distributed_objectstore_impl.h"
21 #include "objectstore_errors.h"
22 #include "softbus_adapter.h"
23 #include "string_utils.h"
24
25 namespace OHOS::ObjectStore {
DistributedObjectStoreImpl(FlatObjectStore * flatObjectStore)26 DistributedObjectStoreImpl::DistributedObjectStoreImpl(FlatObjectStore *flatObjectStore)
27 : flatObjectStore_(flatObjectStore)
28 {
29 }
30
~DistributedObjectStoreImpl()31 DistributedObjectStoreImpl::~DistributedObjectStoreImpl()
32 {
33 delete flatObjectStore_;
34 }
35
CacheObject(const std::string & sessionId,FlatObjectStore * flatObjectStore)36 DistributedObject *DistributedObjectStoreImpl::CacheObject(
37 const std::string &sessionId, FlatObjectStore *flatObjectStore)
38 {
39 DistributedObjectImpl *object = new (std::nothrow) DistributedObjectImpl(sessionId, flatObjectStore);
40 if (object == nullptr) {
41 return nullptr;
42 }
43 std::unique_lock<std::shared_mutex> cacheLock(dataMutex_);
44 objects_.push_back(object);
45 return object;
46 }
47
RemoveCacheObject(const std::string & sessionId)48 void DistributedObjectStoreImpl::RemoveCacheObject(const std::string &sessionId)
49 {
50 std::unique_lock<std::shared_mutex> cacheLock(dataMutex_);
51 auto iter = objects_.begin();
52 while (iter != objects_.end()) {
53 if ((*iter)->GetSessionId() == sessionId) {
54 delete *iter;
55 iter = objects_.erase(iter);
56 } else {
57 iter++;
58 }
59 }
60 return;
61 }
62
CreateObject(const std::string & sessionId)63 DistributedObject *DistributedObjectStoreImpl::CreateObject(const std::string &sessionId)
64 {
65 HiTrace trace(std::string(__FUNCTION__));
66 if (flatObjectStore_ == nullptr) {
67 LOG_ERROR("DistributedObjectStoreImpl::CreateObject store not opened!");
68 return nullptr;
69 }
70
71 if (sessionId.empty()) {
72 LOG_ERROR("DistributedObjectStoreImpl::CreateObject Invalid sessionId");
73 return nullptr;
74 }
75
76 uint32_t status = flatObjectStore_->CreateObject(sessionId);
77 if (status != SUCCESS) {
78 LOG_ERROR("DistributedObjectStoreImpl::CreateObject CreateTable err %{public}d", status);
79 return nullptr;
80 }
81 return CacheObject(sessionId, flatObjectStore_);
82 }
83
CreateObject(const std::string & sessionId,uint32_t & status)84 DistributedObject *DistributedObjectStoreImpl::CreateObject(const std::string &sessionId, uint32_t &status)
85 {
86 HiTrace trace(std::string(__FUNCTION__));
87 if (flatObjectStore_ == nullptr) {
88 LOG_ERROR("DistributedObjectStoreImpl::CreateObject store not opened!");
89 status = ERR_NULL_OBJECTSTORE;
90 return nullptr;
91 }
92
93 if (sessionId.empty()) {
94 LOG_ERROR("DistributedObjectStoreImpl::CreateObject Invalid sessionId");
95 status = ERR_INVALID_ARGS;
96 return nullptr;
97 }
98
99 status = flatObjectStore_->CreateObject(sessionId);
100 if (status != SUCCESS) {
101 LOG_ERROR("DistributedObjectStoreImpl::CreateObject CreateTable err %{public}d", status);
102 return nullptr;
103 }
104 return CacheObject(sessionId, flatObjectStore_);
105 }
106
DeleteObject(const std::string & sessionId)107 uint32_t DistributedObjectStoreImpl::DeleteObject(const std::string &sessionId)
108 {
109 HiTrace trace(std::string(__FUNCTION__));
110 if (flatObjectStore_ == nullptr) {
111 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
112 return ERR_NULL_OBJECTSTORE;
113 }
114 uint32_t status = flatObjectStore_->Delete(sessionId);
115 if (status != SUCCESS) {
116 LOG_ERROR("DistributedObjectStoreImpl::DeleteObject store delete err %{public}d", status);
117 return status;
118 }
119 RemoveCacheObject(sessionId);
120 return SUCCESS;
121 }
122
Get(const std::string & sessionId,DistributedObject ** object)123 uint32_t DistributedObjectStoreImpl::Get(const std::string &sessionId, DistributedObject **object)
124 {
125 auto iter = objects_.begin();
126 while (iter != objects_.end()) {
127 if ((*iter)->GetSessionId() == sessionId) {
128 *object = *iter;
129 return SUCCESS;
130 }
131 iter++;
132 }
133 LOG_ERROR("DistributedObjectStoreImpl::Get object err, no object");
134 return ERR_GET_OBJECT;
135 }
136
Watch(DistributedObject * object,std::shared_ptr<ObjectWatcher> watcher)137 uint32_t DistributedObjectStoreImpl::Watch(DistributedObject *object, std::shared_ptr<ObjectWatcher> watcher)
138 {
139 if (object == nullptr) {
140 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
141 return ERR_NULL_OBJECT;
142 }
143 if (flatObjectStore_ == nullptr) {
144 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
145 return ERR_NULL_OBJECTSTORE;
146 }
147 if (watchers_.count(object) != 0) {
148 LOG_ERROR("DistributedObjectStoreImpl::Watch already gets object");
149 return ERR_EXIST;
150 }
151 std::shared_ptr<WatcherProxy> watcherProxy = std::make_shared<WatcherProxy>(watcher, object->GetSessionId());
152 uint32_t status = flatObjectStore_->Watch(object->GetSessionId(), watcherProxy);
153 if (status != SUCCESS) {
154 LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status);
155 return status;
156 }
157 watchers_.insert_or_assign(object, watcherProxy);
158 LOG_INFO("DistributedObjectStoreImpl:Watch object success.");
159 return SUCCESS;
160 }
161
UnWatch(DistributedObject * object)162 uint32_t DistributedObjectStoreImpl::UnWatch(DistributedObject *object)
163 {
164 if (object == nullptr) {
165 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
166 return ERR_NULL_OBJECT;
167 }
168 if (flatObjectStore_ == nullptr) {
169 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
170 return ERR_NULL_OBJECTSTORE;
171 }
172 uint32_t status = flatObjectStore_->UnWatch(object->GetSessionId());
173 if (status != SUCCESS) {
174 LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status);
175 return status;
176 }
177 watchers_.erase(object);
178 LOG_INFO("DistributedObjectStoreImpl:UnWatch object success.");
179 return SUCCESS;
180 }
181
SetStatusNotifier(std::shared_ptr<StatusNotifier> notifier)182 uint32_t DistributedObjectStoreImpl::SetStatusNotifier(std::shared_ptr<StatusNotifier> notifier)
183 {
184 if (flatObjectStore_ == nullptr) {
185 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
186 return ERR_NULL_OBJECTSTORE;
187 }
188 std::shared_ptr<StatusNotifierProxy> watcherProxy = std::make_shared<StatusNotifierProxy>(notifier);
189 uint32_t status = flatObjectStore_->SetStatusNotifier(watcherProxy);
190 if (status != SUCCESS) {
191 LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status);
192 }
193 return status;
194 }
195
NotifyCachedStatus(const std::string & sessionId)196 void DistributedObjectStoreImpl::NotifyCachedStatus(const std::string &sessionId)
197 {
198 flatObjectStore_->CheckRetrieveCache(sessionId);
199 }
200
WatcherProxy(const std::shared_ptr<ObjectWatcher> objectWatcher,const std::string & sessionId)201 WatcherProxy::WatcherProxy(const std::shared_ptr<ObjectWatcher> objectWatcher, const std::string &sessionId)
202 : FlatObjectWatcher(sessionId), objectWatcher_(objectWatcher)
203 {
204 }
205
OnChanged(const std::string & sessionid,const std::vector<std::string> & changedData)206 void WatcherProxy::OnChanged(const std::string &sessionid, const std::vector<std::string> &changedData)
207 {
208 objectWatcher_->OnChanged(sessionid, changedData);
209 }
210
GetInstance(const std::string & bundleName)211 DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &bundleName)
212 {
213 static std::mutex instLock_;
214 static DistributedObjectStore *instPtr = nullptr;
215 if (instPtr == nullptr) {
216 std::lock_guard<std::mutex> lock(instLock_);
217 if (instPtr == nullptr && !bundleName.empty()) {
218 LOG_INFO("new objectstore %{public}s", bundleName.c_str());
219 FlatObjectStore *flatObjectStore = new (std::nothrow) FlatObjectStore(bundleName);
220 if (flatObjectStore == nullptr) {
221 LOG_ERROR("no memory for FlatObjectStore malloc!");
222 return nullptr;
223 }
224 // Use instMemory to make sure this singleton not free before other object.
225 // This operation needn't to malloc memory, we needn't to check nullptr.
226 instPtr = new (std::nothrow) DistributedObjectStoreImpl(flatObjectStore);
227 if (instPtr == nullptr) {
228 LOG_ERROR("no memory for DistributedObjectStoreImpl malloc!");
229 return nullptr;
230 }
231 }
232 }
233 return instPtr;
234 }
235
OnChanged(const std::string & sessionId,const std::string & networkId,const std::string & onlineStatus)236 void StatusNotifierProxy::OnChanged(
237 const std::string &sessionId, const std::string &networkId, const std::string &onlineStatus)
238 {
239 if (notifier != nullptr) {
240 notifier->OnChanged(sessionId, networkId, onlineStatus);
241 }
242 }
243
StatusNotifierProxy(const std::shared_ptr<StatusNotifier> & notifier)244 StatusNotifierProxy::StatusNotifierProxy(const std::shared_ptr<StatusNotifier> ¬ifier) : notifier(notifier)
245 {
246 }
247
~StatusNotifierProxy()248 StatusNotifierProxy::~StatusNotifierProxy()
249 {
250 LOG_ERROR("destroy");
251 notifier = nullptr;
252 }
253 } // namespace OHOS::ObjectStore
254