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 DataObjectHiTrace trace("DistributedObjectStoreImpl::CreateObject");
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 DataObjectHiTrace trace("DistributedObjectStoreImpl::CreateObject");
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 DataObjectHiTrace trace("DistributedObjectStoreImpl::DeleteObject");
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 std::lock_guard<std::mutex> lock(watchersLock_);
148 if (watchers_.count(object) != 0) {
149 LOG_ERROR("DistributedObjectStoreImpl::Watch already gets object");
150 return ERR_EXIST;
151 }
152 std::shared_ptr<WatcherProxy> watcherProxy = std::make_shared<WatcherProxy>(watcher, object->GetSessionId());
153 uint32_t status = flatObjectStore_->Watch(object->GetSessionId(), watcherProxy);
154 if (status != SUCCESS) {
155 LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status);
156 return status;
157 }
158 watchers_.insert_or_assign(object, watcherProxy);
159 LOG_INFO("DistributedObjectStoreImpl:Watch object success.");
160 return SUCCESS;
161 }
162
UnWatch(DistributedObject * object)163 uint32_t DistributedObjectStoreImpl::UnWatch(DistributedObject *object)
164 {
165 if (object == nullptr) {
166 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
167 return ERR_NULL_OBJECT;
168 }
169 if (flatObjectStore_ == nullptr) {
170 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
171 return ERR_NULL_OBJECTSTORE;
172 }
173 uint32_t status = flatObjectStore_->UnWatch(object->GetSessionId());
174 if (status != SUCCESS) {
175 LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status);
176 return status;
177 }
178 std::lock_guard<std::mutex> lock(watchersLock_);
179 watchers_.erase(object);
180 LOG_INFO("DistributedObjectStoreImpl:UnWatch object success.");
181 return SUCCESS;
182 }
183
SetStatusNotifier(std::shared_ptr<StatusNotifier> notifier)184 uint32_t DistributedObjectStoreImpl::SetStatusNotifier(std::shared_ptr<StatusNotifier> notifier)
185 {
186 if (flatObjectStore_ == nullptr) {
187 LOG_ERROR("DistributedObjectStoreImpl::Sync object err ");
188 return ERR_NULL_OBJECTSTORE;
189 }
190 std::shared_ptr<StatusNotifierProxy> watcherProxy = std::make_shared<StatusNotifierProxy>(notifier);
191 return flatObjectStore_->SetStatusNotifier(watcherProxy);
192 }
193
NotifyCachedStatus(const std::string & sessionId)194 void DistributedObjectStoreImpl::NotifyCachedStatus(const std::string &sessionId)
195 {
196 flatObjectStore_->CheckRetrieveCache(sessionId);
197 }
198
WatcherProxy(const std::shared_ptr<ObjectWatcher> objectWatcher,const std::string & sessionId)199 WatcherProxy::WatcherProxy(const std::shared_ptr<ObjectWatcher> objectWatcher, const std::string &sessionId)
200 : FlatObjectWatcher(sessionId), objectWatcher_(objectWatcher)
201 {
202 }
203
OnChanged(const std::string & sessionid,const std::vector<std::string> & changedData)204 void WatcherProxy::OnChanged(const std::string &sessionid, const std::vector<std::string> &changedData)
205 {
206 objectWatcher_->OnChanged(sessionid, changedData);
207 }
208
GetInstance(const std::string & bundleName)209 DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &bundleName)
210 {
211 static std::mutex instLock_;
212 static DistributedObjectStore *instPtr = nullptr;
213 if (instPtr == nullptr) {
214 std::lock_guard<std::mutex> lock(instLock_);
215 if (instPtr == nullptr && !bundleName.empty()) {
216 LOG_INFO("new objectstore %{public}s", bundleName.c_str());
217 FlatObjectStore *flatObjectStore = new (std::nothrow) FlatObjectStore(bundleName);
218 if (flatObjectStore == nullptr) {
219 LOG_ERROR("no memory for FlatObjectStore malloc!");
220 return nullptr;
221 }
222 // Use instMemory to make sure this singleton not free before other object.
223 // This operation needn't to malloc memory, we needn't to check nullptr.
224 instPtr = new (std::nothrow) DistributedObjectStoreImpl(flatObjectStore);
225 if (instPtr == nullptr) {
226 LOG_ERROR("no memory for DistributedObjectStoreImpl malloc!");
227 return nullptr;
228 }
229 }
230 }
231 return instPtr;
232 }
233
OnChanged(const std::string & sessionId,const std::string & networkId,const std::string & onlineStatus)234 void StatusNotifierProxy::OnChanged(
235 const std::string &sessionId, const std::string &networkId, const std::string &onlineStatus)
236 {
237 if (notifier != nullptr) {
238 notifier->OnChanged(sessionId, networkId, onlineStatus);
239 }
240 }
241
StatusNotifierProxy(const std::shared_ptr<StatusNotifier> & notifier)242 StatusNotifierProxy::StatusNotifierProxy(const std::shared_ptr<StatusNotifier> ¬ifier) : notifier(notifier)
243 {
244 }
245
~StatusNotifierProxy()246 StatusNotifierProxy::~StatusNotifierProxy()
247 {
248 LOG_ERROR("destroy");
249 notifier = nullptr;
250 }
251 } // namespace OHOS::ObjectStore
252