1 /*
2 * Copyright (c) 2021 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 "auto_launch.h"
17
18 #include <map>
19
20 #include "db_common.h"
21 #include "db_dump_helper.h"
22 #include "db_dfx_adapter.h"
23 #include "db_errno.h"
24 #include "kv_store_changed_data_impl.h"
25 #include "kv_store_nb_conflict_data_impl.h"
26 #include "kvdb_manager.h"
27 #include "kvdb_pragma.h"
28 #include "log_print.h"
29 #include "param_check_utils.h"
30 #include "relational_store_instance.h"
31 #include "relational_store_changed_data_impl.h"
32 #include "runtime_context.h"
33 #include "semaphore_utils.h"
34 #include "sync_able_kvdb_connection.h"
35
36 namespace DistributedDB {
37 namespace {
38 constexpr int MAX_AUTO_LAUNCH_ITEM_NUM = 8;
39 const char *AUTO_LAUNCH_ID = "AutoLaunchID";
40 }
41
SetCommunicatorAggregator(ICommunicatorAggregator * aggregator)42 void AutoLaunch::SetCommunicatorAggregator(ICommunicatorAggregator *aggregator)
43 {
44 LOGI("[AutoLaunch] SetCommunicatorAggregator");
45 std::lock_guard<std::mutex> autoLock(communicatorLock_);
46 int errCode;
47 if (communicatorAggregator_ != nullptr) {
48 LOGI("[AutoLaunch] SetCommunicatorAggregator communicatorAggregator_ is not nullptr");
49 errCode = communicatorAggregator_->RegOnConnectCallback(nullptr, nullptr);
50 if (errCode != E_OK) {
51 LOGW("[AutoLaunch] RegOnConnectCallback set nullptr failed, errCode:%d", errCode);
52 }
53 errCode = communicatorAggregator_->RegCommunicatorLackCallback(nullptr, nullptr);
54 if (errCode != E_OK) {
55 LOGW("[AutoLaunch] RegCommunicatorLackCallback set nullptr failed, errCode:%d", errCode);
56 }
57 }
58 communicatorAggregator_ = aggregator;
59 if (aggregator == nullptr) {
60 LOGI("[AutoLaunch] SetCommunicatorAggregator aggregator is nullptr");
61 return;
62 }
63 errCode = aggregator->RegOnConnectCallback(std::bind(&AutoLaunch::OnlineCallBack, this,
64 std::placeholders::_1, std::placeholders::_2), nullptr);
65 if (errCode != E_OK) {
66 LOGW("[AutoLaunch] RegOnConnectCallback errCode:%d", errCode);
67 }
68 errCode = aggregator->RegCommunicatorLackCallback(
69 std::bind(&AutoLaunch::ReceiveUnknownIdentifierCallBack, this, std::placeholders::_1, std::placeholders::_2),
70 nullptr);
71 if (errCode != E_OK) {
72 LOGW("[AutoLaunch] RegCommunicatorLackCallback errCode:%d", errCode);
73 }
74 }
75
~AutoLaunch()76 AutoLaunch::~AutoLaunch()
77 {
78 {
79 std::lock_guard<std::mutex> autoLock(communicatorLock_);
80 LOGI("[AutoLaunch] ~AutoLaunch()");
81 if (communicatorAggregator_ != nullptr) {
82 communicatorAggregator_->RegOnConnectCallback(nullptr, nullptr);
83 communicatorAggregator_->RegCommunicatorLackCallback(nullptr, nullptr);
84 communicatorAggregator_ = nullptr;
85 }
86 }
87 // {identifier, userId}
88 std::set<std::pair<std::string, std::string>> inDisableSet;
89 std::set<std::pair<std::string, std::string>> inWaitIdleSet;
90 std::unique_lock<std::mutex> autoLock(dataLock_);
91 for (auto &items : autoLaunchItemMap_) {
92 for (auto &iter : items.second) {
93 if (iter.second.isDisable) {
94 inDisableSet.insert({ items.first, iter.first });
95 } else if (iter.second.state == AutoLaunchItemState::IDLE && (!iter.second.inObserver)) {
96 TryCloseConnection(iter.second);
97 } else {
98 inWaitIdleSet.insert({ items.first, iter.first });
99 iter.second.isDisable = true;
100 }
101 }
102 }
103 for (const auto &identifierInfo : inDisableSet) {
104 cv_.wait(autoLock, [identifierInfo, this] {
105 return autoLaunchItemMap_.count(identifierInfo.first) == 0 ||
106 autoLaunchItemMap_[identifierInfo.first].count(identifierInfo.second) == 0 ||
107 (!autoLaunchItemMap_[identifierInfo.first][identifierInfo.second].isDisable);
108 });
109 if (autoLaunchItemMap_.count(identifierInfo.first) != 0 &&
110 autoLaunchItemMap_[identifierInfo.first].count(identifierInfo.second)) {
111 TryCloseConnection(autoLaunchItemMap_[identifierInfo.first][identifierInfo.second]);
112 }
113 }
114 for (const auto &info : inWaitIdleSet) {
115 cv_.wait(autoLock, [info, this] {
116 return (autoLaunchItemMap_[info.first][info.second].state == AutoLaunchItemState::IDLE) &&
117 (!autoLaunchItemMap_[info.first][info.second].inObserver);
118 });
119 TryCloseConnection(autoLaunchItemMap_[info.first][info.second]);
120 }
121 }
122
EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem & autoLaunchItem,const std::string & normalIdentifier,const std::string & dualTupleIdentifier,bool isDualTupleMode)123 int AutoLaunch::EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem &autoLaunchItem, const std::string &normalIdentifier,
124 const std::string &dualTupleIdentifier, bool isDualTupleMode)
125 {
126 std::lock_guard<std::mutex> autoLock(dataLock_);
127 std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::USER_ID, "");
128 if (isDualTupleMode && autoLaunchItemMap_.count(normalIdentifier) != 0 &&
129 autoLaunchItemMap_[normalIdentifier].count(userId) != 0) {
130 LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is already enabled in normal tuple mode");
131 return -E_ALREADY_SET;
132 }
133 if (!isDualTupleMode && autoLaunchItemMap_.count(dualTupleIdentifier) != 0 &&
134 autoLaunchItemMap_[dualTupleIdentifier].count(userId) != 0) {
135 LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is already enabled in dual tuple mode");
136 return -E_ALREADY_SET;
137 }
138 std::string identifier = isDualTupleMode ? dualTupleIdentifier : normalIdentifier;
139 if (identifier.empty()) {
140 LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is invalid");
141 return -E_INVALID_ARGS;
142 }
143 if (autoLaunchItemMap_.count(identifier) != 0 && autoLaunchItemMap_[identifier].count(userId) != 0) {
144 LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is already enabled!");
145 return -E_ALREADY_SET;
146 }
147 uint32_t autoLaunchItemSize = 0;
148 for (const auto &item : autoLaunchItemMap_) {
149 autoLaunchItemSize += item.second.size();
150 }
151 if (autoLaunchItemSize == MAX_AUTO_LAUNCH_ITEM_NUM) {
152 LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck size is max(8) now");
153 return -E_MAX_LIMITS;
154 }
155 autoLaunchItem.state = AutoLaunchItemState::IN_ENABLE;
156 autoLaunchItemMap_[identifier][userId] = autoLaunchItem;
157 LOGI("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck ok identifier=%.6s, isDual=%d",
158 STR_TO_HEX(identifier), isDualTupleMode);
159 return E_OK;
160 }
161
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)162 int AutoLaunch::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
163 const AutoLaunchOption &option)
164 {
165 LOGI("[AutoLaunch] EnableKvStoreAutoLaunch");
166 bool isDualTupleMode = properties.GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false);
167 std::string dualTupleIdentifier = properties.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
168 std::string identifier = properties.GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
169 std::string userId = properties.GetStringProp(KvDBProperties::USER_ID, "");
170 std::shared_ptr<DBProperties> ptr = std::make_shared<KvDBProperties>(properties);
171 AutoLaunchItem autoLaunchItem { ptr, notifier, option.observer, option.conflictType, option.notifier };
172 autoLaunchItem.isAutoSync = option.isAutoSync;
173 autoLaunchItem.type = DBType::DB_KV;
174 int errCode = EnableKvStoreAutoLaunchParmCheck(autoLaunchItem, identifier, dualTupleIdentifier, isDualTupleMode);
175 if (errCode != E_OK) {
176 LOGE("[AutoLaunch] EnableKvStoreAutoLaunch failed errCode:%d", errCode);
177 return errCode;
178 }
179 if (isDualTupleMode && !RuntimeContext::GetInstance()->IsSyncerNeedActive(properties)) {
180 std::lock_guard<std::mutex> autoLock(dataLock_);
181 std::string tmpIdentifier = isDualTupleMode ? dualTupleIdentifier : identifier;
182 LOGI("[AutoLaunch] GetDoOpenMap identifier=%.6s no need to open", STR_TO_HEX(tmpIdentifier));
183 autoLaunchItemMap_[tmpIdentifier][userId].state = AutoLaunchItemState::IDLE;
184 return errCode;
185 }
186 errCode = GetKVConnectionInEnable(autoLaunchItem, isDualTupleMode ? dualTupleIdentifier : identifier);
187 if (errCode == E_OK) {
188 LOGI("[AutoLaunch] EnableKvStoreAutoLaunch ok");
189 } else {
190 LOGE("[AutoLaunch] EnableKvStoreAutoLaunch failed errCode:%d", errCode);
191 }
192 return errCode;
193 }
194
GetKVConnectionInEnable(AutoLaunchItem & autoLaunchItem,const std::string & identifier)195 int AutoLaunch::GetKVConnectionInEnable(AutoLaunchItem &autoLaunchItem, const std::string &identifier)
196 {
197 LOGI("[AutoLaunch] GetKVConnectionInEnable");
198 int errCode;
199 std::shared_ptr<KvDBProperties> properties = std::static_pointer_cast<KvDBProperties>(autoLaunchItem.propertiesPtr);
200 std::string userId = properties->GetStringProp(KvDBProperties::USER_ID, "");
201 autoLaunchItem.conn = KvDBManager::GetDatabaseConnection(*properties, errCode, false);
202 if (errCode == -E_ALREADY_OPENED) {
203 LOGI("[AutoLaunch] GetKVConnectionInEnable user already getkvstore by self");
204 std::lock_guard<std::mutex> autoLock(dataLock_);
205 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
206 return E_OK;
207 }
208 if (autoLaunchItem.conn == nullptr) {
209 EraseAutoLauchItem(identifier, userId);
210 return errCode;
211 }
212 bool isEmpty = false;
213 {
214 std::lock_guard<std::mutex> onlineDevicesLock(dataLock_);
215 isEmpty = onlineDevices_.empty();
216 }
217 if (isEmpty) {
218 LOGI("[AutoLaunch] GetKVConnectionInEnable no online device, ReleaseDatabaseConnection");
219 IKvDBConnection *kvConn = static_cast<IKvDBConnection *>(autoLaunchItem.conn);
220 errCode = KvDBManager::ReleaseDatabaseConnection(kvConn);
221 if (errCode != E_OK) {
222 LOGE("[AutoLaunch] GetKVConnectionInEnable ReleaseDatabaseConnection failed errCode:%d", errCode);
223 EraseAutoLauchItem(identifier, userId);
224 return errCode;
225 }
226 std::lock_guard<std::mutex> autoLock(dataLock_);
227 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
228 return E_OK;
229 }
230 errCode = RegisterObserverAndLifeCycleCallback(autoLaunchItem, identifier, false);
231 if (errCode == E_OK) {
232 std::lock_guard<std::mutex> autoLock(dataLock_);
233 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
234 autoLaunchItemMap_[identifier][userId].conn = autoLaunchItem.conn;
235 autoLaunchItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle;
236 } else {
237 LOGE("[AutoLaunch] GetKVConnectionInEnable RegisterObserverAndLifeCycleCallback err, do CloseConnection");
238 TryCloseConnection(autoLaunchItem); // do nothing if failed
239 EraseAutoLauchItem(identifier, userId);
240 }
241 return errCode;
242 }
243
244 // we will return errCode, if errCode != E_OK
CloseConnectionStrict(AutoLaunchItem & autoLaunchItem)245 int AutoLaunch::CloseConnectionStrict(AutoLaunchItem &autoLaunchItem)
246 {
247 LOGI("[AutoLaunch] CloseConnectionStrict");
248 if (autoLaunchItem.conn == nullptr) {
249 LOGI("[AutoLaunch] CloseConnectionStrict conn is nullptr, do nothing");
250 return E_OK;
251 }
252 IKvDBConnection *kvConn = static_cast<IKvDBConnection *>(autoLaunchItem.conn);
253 int errCode = kvConn->RegisterLifeCycleCallback(nullptr);
254 if (errCode != E_OK) {
255 LOGE("[AutoLaunch] CloseConnectionStrict RegisterLifeCycleCallback failed errCode:%d", errCode);
256 return errCode;
257 }
258 if (autoLaunchItem.observerHandle != nullptr) {
259 errCode = kvConn->UnRegisterObserver(autoLaunchItem.observerHandle);
260 if (errCode != E_OK) {
261 LOGE("[AutoLaunch] CloseConnectionStrict UnRegisterObserver failed errCode:%d", errCode);
262 return errCode;
263 }
264 autoLaunchItem.observerHandle = nullptr;
265 }
266 errCode = KvDBManager::ReleaseDatabaseConnection(kvConn);
267 if (errCode != E_OK) {
268 LOGE("[AutoLaunch] CloseConnectionStrict ReleaseDatabaseConnection failed errCode:%d", errCode);
269 }
270 return errCode;
271 }
272
273 // before ReleaseDatabaseConnection, if errCode != E_OK, we not return, we try close more
TryCloseConnection(AutoLaunchItem & autoLaunchItem)274 void AutoLaunch::TryCloseConnection(AutoLaunchItem &autoLaunchItem)
275 {
276 LOGI("[AutoLaunch] TryCloseConnection");
277 switch (autoLaunchItem.type) {
278 case DBType::DB_KV:
279 TryCloseKvConnection(autoLaunchItem);
280 break;
281 case DBType::DB_RELATION:
282 TryCloseRelationConnection(autoLaunchItem);
283 break;
284 default:
285 LOGD("[AutoLaunch] Unknown type[%d] when try to close connection", static_cast<int>(autoLaunchItem.type));
286 break;
287 }
288 }
289
RegisterObserverAndLifeCycleCallback(AutoLaunchItem & autoLaunchItem,const std::string & identifier,bool isExt)290 int AutoLaunch::RegisterObserverAndLifeCycleCallback(AutoLaunchItem &autoLaunchItem, const std::string &identifier,
291 bool isExt)
292 {
293 int errCode = RegisterObserver(autoLaunchItem, identifier, isExt);
294 if (errCode != E_OK) {
295 return errCode;
296 }
297 LOGI("[AutoLaunch] RegisterObserver ok");
298
299 errCode = RegisterLifeCycleCallback(autoLaunchItem, identifier, isExt);
300 if (errCode != E_OK) {
301 LOGE("[AutoLaunch] RegisterLifeCycleCallback failed, errCode:%d", errCode);
302 return errCode;
303 }
304 LOGI("[AutoLaunch] RegisterLifeCycleCallback ok");
305
306 errCode = SetConflictNotifier(autoLaunchItem);
307 if (errCode != E_OK) {
308 LOGE("[AutoLaunch] SetConflictNotifier failed, errCode:%d", errCode);
309 return errCode;
310 }
311
312 return PragmaAutoSync(autoLaunchItem);
313 }
314
RegisterObserver(AutoLaunchItem & autoLaunchItem,const std::string & identifier,bool isExt)315 int AutoLaunch::RegisterObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt)
316 {
317 if (autoLaunchItem.conn == nullptr) {
318 LOGE("[AutoLaunch] autoLaunchItem.conn is nullptr");
319 return -E_INTERNAL_ERROR;
320 }
321 LOGI("[AutoLaunch] RegisterObserver type=%d", static_cast<int>(autoLaunchItem.type));
322 switch (autoLaunchItem.type) {
323 case DBType::DB_RELATION:
324 return RegisterRelationalObserver(autoLaunchItem, identifier, isExt);
325 case DBType::DB_KV:
326 return RegisterKvObserver(autoLaunchItem, identifier, isExt);
327 default:
328 return -E_INVALID_ARGS;
329 }
330 }
331
ObserverFunc(const KvDBCommitNotifyData & notifyData,const std::string & identifier,const std::string & userId)332 void AutoLaunch::ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier,
333 const std::string &userId)
334 {
335 LOGD("[AutoLaunch] ObserverFunc identifier=%.6s", STR_TO_HEX(identifier));
336 AutoLaunchItem autoLaunchItem;
337 std::string appId;
338 std::string storeId;
339 {
340 std::lock_guard<std::mutex> autoLock(dataLock_);
341 if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) {
342 LOGE("[AutoLaunch] ObserverFunc err no this identifier in map");
343 return;
344 }
345 if (autoLaunchItemMap_[identifier][userId].isDisable) {
346 LOGI("[AutoLaunch] ObserverFunc isDisable, do nothing");
347 return;
348 }
349 autoLaunchItemMap_[identifier][userId].inObserver = true;
350 autoLaunchItem.observer = autoLaunchItemMap_[identifier][userId].observer;
351 autoLaunchItem.isWriteOpenNotified = autoLaunchItemMap_[identifier][userId].isWriteOpenNotified;
352 autoLaunchItem.notifier = autoLaunchItemMap_[identifier][userId].notifier;
353
354 std::shared_ptr<KvDBProperties> properties =
355 std::static_pointer_cast<KvDBProperties>(autoLaunchItemMap_[identifier][userId].propertiesPtr);
356 appId = properties->GetStringProp(KvDBProperties::APP_ID, "");
357 storeId = properties->GetStringProp(KvDBProperties::STORE_ID, "");
358 }
359 if (autoLaunchItem.observer != nullptr) {
360 LOGI("[AutoLaunch] do user observer");
361 KvStoreChangedDataImpl data(¬ifyData);
362 (autoLaunchItem.observer)->OnChange(data);
363 }
364 LOGI("[AutoLaunch] in observer autoLaunchItem.isWriteOpenNotified:%d", autoLaunchItem.isWriteOpenNotified);
365
366 if (!autoLaunchItem.isWriteOpenNotified && autoLaunchItem.notifier != nullptr) {
367 {
368 std::lock_guard<std::mutex> autoLock(dataLock_);
369 autoLaunchItemMap_[identifier][userId].isWriteOpenNotified = true;
370 }
371 AutoLaunchNotifier notifier = autoLaunchItem.notifier;
372 int retCode = RuntimeContext::GetInstance()->ScheduleTask([notifier, userId, appId, storeId] {
373 LOGI("[AutoLaunch] notify the user auto opened event");
374 notifier(userId, appId, storeId, AutoLaunchStatus::WRITE_OPENED);
375 });
376 if (retCode != E_OK) {
377 LOGE("[AutoLaunch] ObserverFunc notifier ScheduleTask retCode:%d", retCode);
378 }
379 }
380 std::lock_guard<std::mutex> autoLock(dataLock_);
381 autoLaunchItemMap_[identifier][userId].inObserver = false;
382 cv_.notify_all();
383 }
384
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)385 int AutoLaunch::DisableKvStoreAutoLaunch(const std::string &normalIdentifier, const std::string &dualTupleIdentifier,
386 const std::string &userId)
387 {
388 std::string identifier = (autoLaunchItemMap_.count(normalIdentifier) == 0) ? dualTupleIdentifier : normalIdentifier;
389 LOGI("[AutoLaunch] DisableKvStoreAutoLaunch identifier=%.6s", STR_TO_HEX(identifier));
390 AutoLaunchItem autoLaunchItem;
391 {
392 std::unique_lock<std::mutex> autoLock(dataLock_);
393 if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) {
394 LOGE("[AutoLaunch] DisableKvStoreAutoLaunch identifier is not exist!");
395 return -E_NOT_FOUND;
396 }
397 if (autoLaunchItemMap_[identifier][userId].isDisable) {
398 LOGI("[AutoLaunch] DisableKvStoreAutoLaunch already disabling in another thread, do nothing here");
399 return -E_BUSY;
400 }
401 if (autoLaunchItemMap_[identifier][userId].state == AutoLaunchItemState::IN_ENABLE) {
402 LOGE("[AutoLaunch] DisableKvStoreAutoLaunch enable not return, do not disable!");
403 return -E_BUSY;
404 }
405 autoLaunchItemMap_[identifier][userId].isDisable = true;
406 if (autoLaunchItemMap_[identifier][userId].state != AutoLaunchItemState::IDLE) {
407 LOGI("[AutoLaunch] DisableKvStoreAutoLaunch wait idle");
408 cv_.wait(autoLock, [identifier, userId, this] {
409 return (autoLaunchItemMap_[identifier][userId].state == AutoLaunchItemState::IDLE) &&
410 (!autoLaunchItemMap_[identifier][userId].inObserver);
411 });
412 LOGI("[AutoLaunch] DisableKvStoreAutoLaunch wait idle ok");
413 }
414 autoLaunchItem = autoLaunchItemMap_[identifier][userId];
415 }
416
417 int errCode = CloseConnectionStrict(autoLaunchItem);
418 if (errCode != E_OK) {
419 LOGE("[AutoLaunch] DisableKvStoreAutoLaunch CloseConnection failed errCode:%d", errCode);
420 std::lock_guard<std::mutex> autoLock(dataLock_);
421 autoLaunchItemMap_[identifier][userId].isDisable = false;
422 autoLaunchItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle;
423 cv_.notify_all();
424 return errCode;
425 }
426
427 EraseAutoLauchItem(identifier, userId);
428 cv_.notify_all();
429 if (autoLaunchItem.isWriteOpenNotified && autoLaunchItem.notifier) {
430 RuntimeContext::GetInstance()->ScheduleTask([autoLaunchItem] { CloseNotifier(autoLaunchItem); });
431 }
432 LOGI("[AutoLaunch] DisableKvStoreAutoLaunch ok");
433 return E_OK;
434 }
435
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const436 void AutoLaunch::GetAutoLaunchSyncDevices(const std::string &identifier, std::vector<std::string> &devices) const
437 {
438 devices.clear();
439 devices.shrink_to_fit();
440 std::lock_guard<std::mutex> autoLock(dataLock_);
441 if (autoLaunchItemMap_.count(identifier) == 0) {
442 LOGD("[AutoLaunch] GetSyncDevices identifier is not exist!");
443 return;
444 }
445 for (const auto &device : onlineDevices_) {
446 devices.push_back(device);
447 }
448 }
449
CloseNotifier(const AutoLaunchItem & autoLaunchItem)450 void AutoLaunch::CloseNotifier(const AutoLaunchItem &autoLaunchItem)
451 {
452 if (autoLaunchItem.notifier) {
453 std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::USER_ID, "");
454 std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, "");
455 std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, "");
456 LOGI("[AutoLaunch] CloseNotifier do autoLaunchItem.notifier");
457 autoLaunchItem.notifier(userId, appId, storeId, AutoLaunchStatus::WRITE_CLOSED);
458 LOGI("[AutoLaunch] CloseNotifier do autoLaunchItem.notifier finished");
459 } else {
460 LOGI("[AutoLaunch] CloseNotifier autoLaunchItem.notifier is nullptr");
461 }
462 }
463
ConnectionLifeCycleCallbackTask(const std::string & identifier,const std::string & userId)464 void AutoLaunch::ConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId)
465 {
466 LOGI("[AutoLaunch] ConnectionLifeCycleCallbackTask identifier=%.6s", STR_TO_HEX(identifier));
467 AutoLaunchItem autoLaunchItem;
468 {
469 std::lock_guard<std::mutex> autoLock(dataLock_);
470 if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) {
471 LOGE("[AutoLaunch] ConnectionLifeCycleCallback identifier is not exist!");
472 return;
473 }
474 if (autoLaunchItemMap_[identifier][userId].isDisable) {
475 LOGI("[AutoLaunch] ConnectionLifeCycleCallback isDisable, do nothing");
476 return;
477 }
478 if (autoLaunchItemMap_[identifier][userId].state != AutoLaunchItemState::IDLE) {
479 LOGI("[AutoLaunch] ConnectionLifeCycleCallback state:%d is not idle, do nothing",
480 static_cast<int>(autoLaunchItemMap_[identifier][userId].state));
481 return;
482 }
483 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IN_LIFE_CYCLE_CALL_BACK;
484 autoLaunchItem = autoLaunchItemMap_[identifier][userId];
485 }
486 LOGI("[AutoLaunch] ConnectionLifeCycleCallbackTask do CloseConnection");
487 TryCloseConnection(autoLaunchItem); // do nothing if failed
488 LOGI("[AutoLaunch] ConnectionLifeCycleCallback do CloseConnection finished");
489 {
490 std::lock_guard<std::mutex> lock(dataLock_);
491 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
492 autoLaunchItemMap_[identifier][userId].conn = nullptr;
493 autoLaunchItemMap_[identifier][userId].isWriteOpenNotified = false;
494 cv_.notify_all();
495 LOGI("[AutoLaunch] ConnectionLifeCycleCallback notify_all");
496 }
497 if (autoLaunchItem.isWriteOpenNotified) {
498 CloseNotifier(autoLaunchItem);
499 }
500 }
501
ConnectionLifeCycleCallback(const std::string & identifier,const std::string & userId)502 void AutoLaunch::ConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId)
503 {
504 LOGI("[AutoLaunch] ConnectionLifeCycleCallback identifier=%.6s", STR_TO_HEX(identifier));
505 int errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(&AutoLaunch::ConnectionLifeCycleCallbackTask,
506 this, identifier, userId));
507 if (errCode != E_OK) {
508 LOGE("[AutoLaunch] ConnectionLifeCycleCallback ScheduleTask failed");
509 }
510 }
511
OpenOneConnection(AutoLaunchItem & autoLaunchItem)512 int AutoLaunch::OpenOneConnection(AutoLaunchItem &autoLaunchItem)
513 {
514 LOGI("[AutoLaunch] GetOneConnection");
515 int errCode;
516 switch (autoLaunchItem.type) {
517 case DBType::DB_KV:
518 errCode = OpenKvConnection(autoLaunchItem);
519 break;
520 case DBType::DB_RELATION:
521 errCode = OpenRelationalConnection(autoLaunchItem);
522 break;
523 default:
524 errCode = -E_INVALID_ARGS;
525 }
526 if (errCode == -E_INVALID_PASSWD_OR_CORRUPTED_DB) {
527 std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::USER_ID, "");
528 std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, "");
529 std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, "");
530 DBDfxAdapter::ReportFault( { DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED, userId, appId, storeId, errCode } );
531 }
532 return errCode;
533 }
534
OnlineCallBack(const std::string & device,bool isConnect)535 void AutoLaunch::OnlineCallBack(const std::string &device, bool isConnect)
536 {
537 LOGI("[AutoLaunch] OnlineCallBack device:%s{private}, isConnect:%d", device.c_str(), isConnect);
538 if (!isConnect) {
539 std::lock_guard<std::mutex> autoLock(dataLock_);
540 onlineDevices_.erase(device);
541 return;
542 }
543 {
544 std::lock_guard<std::mutex> autoLock(dataLock_);
545 onlineDevices_.insert(device);
546 }
547
548 int errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(&AutoLaunch::OnlineCallBackTask, this));
549 if (errCode != E_OK) {
550 LOGE("[AutoLaunch] OnlineCallBack ScheduleTask failed");
551 }
552 }
553
OnlineCallBackTask()554 void AutoLaunch::OnlineCallBackTask()
555 {
556 LOGI("[AutoLaunch] OnlineCallBackTask");
557 // <identifier, <userId, AutoLaunchItem>>
558 std::map<std::string, std::map<std::string, AutoLaunchItem>> doOpenMap;
559 GetDoOpenMap(doOpenMap);
560 GetConnInDoOpenMap(doOpenMap);
561 UpdateGlobalMap(doOpenMap);
562 }
563
GetDoOpenMap(std::map<std::string,std::map<std::string,AutoLaunchItem>> & doOpenMap)564 void AutoLaunch::GetDoOpenMap(std::map<std::string, std::map<std::string, AutoLaunchItem>> &doOpenMap)
565 {
566 std::lock_guard<std::mutex> autoLock(dataLock_);
567 LOGI("[AutoLaunch] GetDoOpenMap");
568 for (auto &items : autoLaunchItemMap_) {
569 for (auto &iter : items.second) {
570 bool isDualTupleMode = iter.second.propertiesPtr->GetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, false);
571 if (iter.second.isDisable) {
572 LOGI("[AutoLaunch] GetDoOpenMap this item isDisable do nothing");
573 continue;
574 } else if (iter.second.state != AutoLaunchItemState::IDLE) {
575 LOGI("[AutoLaunch] GetDoOpenMap this item state:%d is not idle do nothing",
576 static_cast<int>(iter.second.state));
577 continue;
578 } else if (iter.second.conn != nullptr) {
579 LOGI("[AutoLaunch] GetDoOpenMap this item is opened");
580 continue;
581 } else if (isDualTupleMode &&
582 !RuntimeContext::GetInstance()->IsSyncerNeedActive(*iter.second.propertiesPtr)) {
583 LOGI("[AutoLaunch] GetDoOpenMap this item no need to open");
584 continue;
585 } else {
586 doOpenMap[items.first][iter.first] = iter.second;
587 iter.second.state = AutoLaunchItemState::IN_COMMUNICATOR_CALL_BACK;
588 LOGI("[AutoLaunch] GetDoOpenMap this item in IN_COMMUNICATOR_CALL_BACK");
589 }
590 }
591 }
592 }
593
GetConnInDoOpenMap(std::map<std::string,std::map<std::string,AutoLaunchItem>> & doOpenMap)594 void AutoLaunch::GetConnInDoOpenMap(std::map<std::string, std::map<std::string, AutoLaunchItem>> &doOpenMap)
595 {
596 LOGI("[AutoLaunch] GetConnInDoOpenMap doOpenMap.size():%zu", doOpenMap.size());
597 if (doOpenMap.empty()) {
598 return;
599 }
600 uint32_t totalSize = 0;
601 for (auto &items : doOpenMap) {
602 totalSize += items.second.size();
603 }
604 SemaphoreUtils sema(1 - totalSize);
605 for (auto &items : doOpenMap) {
606 for (auto &iter : items.second) {
607 int errCode = RuntimeContext::GetInstance()->ScheduleTask([&sema, &iter, &items, this] {
608 int ret = OpenOneConnection(iter.second);
609 LOGI("[AutoLaunch] GetConnInDoOpenMap GetOneConnection errCode:%d", ret);
610 if (iter.second.conn == nullptr) {
611 sema.SendSemaphore();
612 LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore");
613 return;
614 }
615 ret = RegisterObserverAndLifeCycleCallback(iter.second, items.first, false);
616 if (ret != E_OK) {
617 LOGE("[AutoLaunch] GetConnInDoOpenMap failed, we do CloseConnection");
618 TryCloseConnection(iter.second); // if here failed, do nothing
619 iter.second.conn = nullptr;
620 }
621 sema.SendSemaphore();
622 LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore");
623 });
624 if (errCode != E_OK) {
625 LOGE("[AutoLaunch] GetConnInDoOpenMap ScheduleTask failed, SendSemaphore");
626 sema.SendSemaphore();
627 }
628 }
629 }
630 LOGI("[AutoLaunch] GetConnInDoOpenMap WaitSemaphore");
631 sema.WaitSemaphore();
632 LOGI("[AutoLaunch] GetConnInDoOpenMap WaitSemaphore ok");
633 }
634
UpdateGlobalMap(std::map<std::string,std::map<std::string,AutoLaunchItem>> & doOpenMap)635 void AutoLaunch::UpdateGlobalMap(std::map<std::string, std::map<std::string, AutoLaunchItem>> &doOpenMap)
636 {
637 std::lock_guard<std::mutex> autoLock(dataLock_);
638 LOGI("[AutoLaunch] UpdateGlobalMap");
639 for (const auto &items : doOpenMap) {
640 for (const auto &iter : items.second) {
641 if (iter.second.conn != nullptr) {
642 autoLaunchItemMap_[items.first][iter.first].conn = iter.second.conn;
643 autoLaunchItemMap_[items.first][iter.first].observerHandle = iter.second.observerHandle;
644 autoLaunchItemMap_[items.first][iter.first].isWriteOpenNotified = false;
645 LOGI("[AutoLaunch] UpdateGlobalMap opened conn update map");
646 }
647 autoLaunchItemMap_[items.first][iter.first].state = AutoLaunchItemState::IDLE;
648 LOGI("[AutoLaunch] UpdateGlobalMap opened conn set state IDLE");
649 }
650 }
651 cv_.notify_all();
652 LOGI("[AutoLaunch] UpdateGlobalMap finish notify_all");
653 }
654
ReceiveUnknownIdentifierCallBackTask(const std::string & identifier,const std::string & userId)655 void AutoLaunch::ReceiveUnknownIdentifierCallBackTask(const std::string &identifier, const std::string &userId)
656 {
657 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask identifier=%.6s", STR_TO_HEX(identifier));
658 AutoLaunchItem autoLaunchItem;
659 {
660 std::lock_guard<std::mutex> autoLock(dataLock_);
661 autoLaunchItem = autoLaunchItemMap_[identifier][userId];
662 }
663 int errCode = OpenOneConnection(autoLaunchItem);
664 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack GetOneConnection errCode:%d", errCode);
665 if (autoLaunchItem.conn == nullptr) {
666 std::lock_guard<std::mutex> autoLock(dataLock_);
667 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
668 cv_.notify_all();
669 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask set state IDLE");
670 return;
671 }
672 errCode = RegisterObserverAndLifeCycleCallback(autoLaunchItem, identifier, false);
673 if (errCode != E_OK) {
674 LOGE("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask RegisterObserverAndLifeCycleCallback failed");
675 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask do CloseConnection");
676 TryCloseConnection(autoLaunchItem); // if here failed, do nothing
677 std::lock_guard<std::mutex> autoLock(dataLock_);
678 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
679 cv_.notify_all();
680 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask set state IDLE");
681 return;
682 }
683 std::lock_guard<std::mutex> autoLock(dataLock_);
684 autoLaunchItemMap_[identifier][userId].conn = autoLaunchItem.conn;
685 autoLaunchItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle;
686 autoLaunchItemMap_[identifier][userId].isWriteOpenNotified = false;
687 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
688 cv_.notify_all();
689 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask conn opened set state IDLE");
690 }
691
ReceiveUnknownIdentifierCallBack(const LabelType & label,const std::string & originalUserId)692 int AutoLaunch::ReceiveUnknownIdentifierCallBack(const LabelType &label, const std::string &originalUserId)
693 {
694 const std::string identifier(label.begin(), label.end());
695 // originalUserId size maybe 0
696 std::string userId = originalUserId;
697 if (originalUserId.size() == 0 && autoLaunchItemMap_.count(identifier) != 0 &&
698 autoLaunchItemMap_[identifier].size() > 1) {
699 LOGE("[AutoLaunch] normal tuple mode userId larger than one userId");
700 goto EXT;
701 }
702 if (originalUserId.size() == 0 && autoLaunchItemMap_.count(identifier) != 0 &&
703 autoLaunchItemMap_[identifier].size() == 1) {
704 // normal tuple mode
705 userId = autoLaunchItemMap_[identifier].begin()->first;
706 }
707 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack identifier=%.6s", STR_TO_HEX(identifier));
708 int errCode;
709 {
710 std::lock_guard<std::mutex> autoLock(dataLock_);
711 if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) {
712 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack not find identifier");
713 goto EXT;
714 } else if (autoLaunchItemMap_[identifier][userId].isDisable) {
715 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack isDisable ,do nothing");
716 return -E_NOT_FOUND; // not E_OK is ok for communicator
717 } else if (autoLaunchItemMap_[identifier][userId].conn != nullptr) {
718 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack conn is not nullptr");
719 return E_OK;
720 } else if (autoLaunchItemMap_[identifier][userId].state != AutoLaunchItemState::IDLE) {
721 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack state:%d is not idle, do nothing",
722 static_cast<int>(autoLaunchItemMap_[identifier][userId].state));
723 return E_OK;
724 }
725 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IN_COMMUNICATOR_CALL_BACK;
726 LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack set state IN_COMMUNICATOR_CALL_BACK");
727 }
728
729 errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(
730 &AutoLaunch::ReceiveUnknownIdentifierCallBackTask, this, identifier, userId));
731 if (errCode != E_OK) {
732 LOGE("[AutoLaunch] ReceiveUnknownIdentifierCallBack ScheduleTask failed");
733 std::lock_guard<std::mutex> autoLock(dataLock_);
734 autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE;
735 }
736 return errCode;
737
738 EXT:
739 return AutoLaunchExt(identifier, userId);
740 }
741
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBType type)742 void AutoLaunch::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBType type)
743 {
744 LOGI("[AutoLaunch] SetAutoLaunchRequestCallback type[%d]", static_cast<int>(type));
745 std::lock_guard<std::mutex> lock(extLock_);
746 if (callback) {
747 autoLaunchRequestCallbackMap_[type] = callback;
748 } else if (autoLaunchRequestCallbackMap_.find(type) != autoLaunchRequestCallbackMap_.end()) {
749 autoLaunchRequestCallbackMap_.erase(type);
750 }
751 }
752
AutoLaunchExt(const std::string & identifier,const std::string & userId)753 int AutoLaunch::AutoLaunchExt(const std::string &identifier, const std::string &userId)
754 {
755 AutoLaunchParam param;
756 // for non dual tuple mode, userId is ""
757 param.userId = userId;
758 DBType openType = DBType::DB_INVALID;
759 int errCode = ExtAutoLaunchRequestCallBack(identifier, param, openType);
760 if (errCode != E_OK) {
761 return errCode; // not E_OK is ok for communicator
762 }
763
764 std::shared_ptr<DBProperties> ptr;
765 errCode = AutoLaunch::GetAutoLaunchProperties(param, openType, false, ptr);
766 if (errCode != E_OK) {
767 LOGE("[AutoLaunch] AutoLaunchExt param check fail errCode:%d", errCode);
768 if (!param.notifier) {
769 return errCode;
770 }
771 int retCode = RuntimeContext::GetInstance()->ScheduleTask([param] {
772 param.notifier(param.userId, param.appId, param.storeId, INVALID_PARAM);
773 });
774 if (retCode != E_OK) {
775 LOGE("[AutoLaunch] AutoLaunchExt notifier ScheduleTask retCode:%d", retCode);
776 }
777 return errCode;
778 }
779 AutoLaunchItem autoLaunchItem{ptr, param.notifier, param.option.observer, param.option.conflictType,
780 param.option.notifier};
781 autoLaunchItem.isAutoSync = param.option.isAutoSync;
782 autoLaunchItem.type = openType;
783 autoLaunchItem.storeObserver = param.option.storeObserver;
784 errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(&AutoLaunch::AutoLaunchExtTask, this,
785 identifier, param.userId, autoLaunchItem));
786 if (errCode != E_OK) {
787 LOGE("[AutoLaunch] AutoLaunchExt ScheduleTask errCode:%d", errCode);
788 }
789 return errCode;
790 }
791
AutoLaunchExtTask(const std::string & identifier,const std::string & userId,AutoLaunchItem & autoLaunchItem)792 void AutoLaunch::AutoLaunchExtTask(const std::string &identifier, const std::string &userId,
793 AutoLaunchItem &autoLaunchItem)
794 {
795 {
796 std::lock_guard<std::mutex> autoLock(extLock_);
797 if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0) {
798 LOGE("[AutoLaunch] extItemMap has this identifier");
799 return;
800 }
801 extItemMap_[identifier][userId] = autoLaunchItem;
802 }
803 bool abort = false;
804 do {
805 int errCode = CheckAutoLaunchRealPath(autoLaunchItem);
806 if (errCode != E_OK) {
807 abort = true;
808 break;
809 }
810 errCode = OpenOneConnection(autoLaunchItem);
811 LOGI("[AutoLaunch] AutoLaunchExtTask GetOneConnection errCode:%d", errCode);
812 if (autoLaunchItem.conn == nullptr) {
813 abort = true;
814 break;
815 }
816 errCode = RegisterObserverAndLifeCycleCallback(autoLaunchItem, identifier, true);
817 if (errCode != E_OK) {
818 LOGE("[AutoLaunch] AutoLaunchExtTask RegisterObserverAndLifeCycleCallback failed");
819 TryCloseConnection(autoLaunchItem); // if here failed, do nothing
820 abort = true;
821 }
822 } while (false);
823 if (abort) {
824 std::lock_guard<std::mutex> autoLock(extLock_);
825 extItemMap_[identifier].erase(userId);
826 if (extItemMap_[identifier].size() == 0) {
827 extItemMap_.erase(identifier);
828 }
829 return;
830 }
831 std::lock_guard<std::mutex> autoLock(extLock_);
832 extItemMap_[identifier][userId].conn = autoLaunchItem.conn;
833 extItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle;
834 extItemMap_[identifier][userId].isWriteOpenNotified = false;
835 LOGI("[AutoLaunch] AutoLaunchExtTask ok");
836 }
837
ExtObserverFunc(const KvDBCommitNotifyData & notifyData,const std::string & identifier,const std::string & userId)838 void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier,
839 const std::string &userId)
840 {
841 LOGD("[AutoLaunch] ExtObserverFunc identifier=%.6s", STR_TO_HEX(identifier));
842 AutoLaunchItem autoLaunchItem;
843 AutoLaunchNotifier notifier;
844 {
845 std::lock_guard<std::mutex> autoLock(extLock_);
846 if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) {
847 LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map");
848 return;
849 }
850 autoLaunchItem = extItemMap_[identifier][userId];
851 }
852 if (autoLaunchItem.observer != nullptr) {
853 LOGD("[AutoLaunch] do user observer");
854 KvStoreChangedDataImpl data(¬ifyData);
855 autoLaunchItem.observer->OnChange(data);
856 }
857
858 {
859 std::lock_guard<std::mutex> autoLock(extLock_);
860 if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0 &&
861 !extItemMap_[identifier][userId].isWriteOpenNotified &&
862 autoLaunchItem.notifier != nullptr) {
863 extItemMap_[identifier][userId].isWriteOpenNotified = true;
864 notifier = autoLaunchItem.notifier;
865 } else {
866 return;
867 }
868 }
869
870 std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::APP_ID, "");
871 std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::STORE_ID, "");
872 int retCode = RuntimeContext::GetInstance()->ScheduleTask([notifier, userId, appId, storeId] {
873 LOGI("[AutoLaunch] ExtObserverFunc do user notifier WRITE_OPENED");
874 notifier(userId, appId, storeId, AutoLaunchStatus::WRITE_OPENED);
875 });
876 if (retCode != E_OK) {
877 LOGE("[AutoLaunch] ExtObserverFunc notifier ScheduleTask retCode:%d", retCode);
878 }
879 }
880
ExtConnectionLifeCycleCallback(const std::string & identifier,const std::string & userId)881 void AutoLaunch::ExtConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId)
882 {
883 LOGI("[AutoLaunch] ExtConnectionLifeCycleCallback identifier=%.6s", STR_TO_HEX(identifier));
884 int errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(
885 &AutoLaunch::ExtConnectionLifeCycleCallbackTask, this, identifier, userId));
886 if (errCode != E_OK) {
887 LOGE("[AutoLaunch] ExtConnectionLifeCycleCallback ScheduleTask failed");
888 }
889 }
890
ExtConnectionLifeCycleCallbackTask(const std::string & identifier,const std::string & userId)891 void AutoLaunch::ExtConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId)
892 {
893 LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier=%.6s", STR_TO_HEX(identifier));
894 AutoLaunchItem autoLaunchItem;
895 {
896 std::lock_guard<std::mutex> autoLock(extLock_);
897 if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) {
898 LOGE("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier is not exist!");
899 return;
900 }
901 autoLaunchItem = extItemMap_[identifier][userId];
902 extItemMap_[identifier].erase(userId);
903 if (extItemMap_[identifier].size() == 0) {
904 extItemMap_.erase(identifier);
905 }
906 }
907 LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask do CloseConnection");
908 TryCloseConnection(autoLaunchItem); // do nothing if failed
909 if (autoLaunchItem.isWriteOpenNotified) {
910 CloseNotifier(autoLaunchItem);
911 }
912 }
913
SetConflictNotifier(AutoLaunchItem & autoLaunchItem)914 int AutoLaunch::SetConflictNotifier(AutoLaunchItem &autoLaunchItem)
915 {
916 if (autoLaunchItem.type != DBType::DB_KV) {
917 LOGD("[AutoLaunch] Current Type[%d] Not Support ConflictNotifier Now", static_cast<int>(autoLaunchItem.type));
918 return E_OK;
919 }
920
921 IKvDBConnection *kvConn = static_cast<IKvDBConnection *>(autoLaunchItem.conn);
922 int conflictType = autoLaunchItem.conflictType;
923 const KvStoreNbConflictNotifier ¬ifier = autoLaunchItem.conflictNotifier;
924 if (conflictType == 0) {
925 return E_OK;
926 }
927 int errCode;
928 if (!notifier) {
929 errCode = kvConn->SetConflictNotifier(conflictType, nullptr);
930 goto END;
931 }
932
933 errCode = kvConn->SetConflictNotifier(conflictType,
934 [conflictType, notifier](const KvDBCommitNotifyData &data) {
935 int resultCode;
936 const std::list<KvDBConflictEntry> entries = data.GetCommitConflicts(resultCode);
937 if (resultCode != E_OK) {
938 LOGE("Get commit conflicted entries failed:%d!", resultCode);
939 return;
940 }
941
942 for (const auto &entry : entries) {
943 // Prohibit signed numbers to perform bit operations
944 uint32_t entryType = static_cast<uint32_t>(entry.type);
945 uint32_t type = static_cast<uint32_t>(conflictType);
946 if ((entryType & type) != 0) {
947 KvStoreNbConflictDataImpl dataImpl;
948 dataImpl.SetConflictData(entry);
949 notifier(dataImpl);
950 }
951 }
952 });
953
954 END:
955 if (errCode != E_OK) {
956 LOGE("[KvStoreNbDelegate] Register conflict failed:%d!", errCode);
957 }
958 return errCode;
959 }
960
GetAutoLaunchProperties(const AutoLaunchParam & param,const DBType & openType,bool checkDir,std::shared_ptr<DBProperties> & propertiesPtr)961 int AutoLaunch::GetAutoLaunchProperties(const AutoLaunchParam ¶m, const DBType &openType, bool checkDir,
962 std::shared_ptr<DBProperties> &propertiesPtr)
963 {
964 switch (openType) {
965 case DBType::DB_KV: {
966 propertiesPtr = std::make_shared<KvDBProperties>();
967 std::shared_ptr<KvDBProperties> kvPtr = std::static_pointer_cast<KvDBProperties>(propertiesPtr);
968 return GetAutoLaunchKVProperties(param, kvPtr, checkDir);
969 }
970 case DBType::DB_RELATION: {
971 propertiesPtr = std::make_shared<RelationalDBProperties>();
972 std::shared_ptr<RelationalDBProperties> rdbPtr =
973 std::static_pointer_cast<RelationalDBProperties>(propertiesPtr);
974 return GetAutoLaunchRelationProperties(param, rdbPtr);
975 }
976 default:
977 return -E_INVALID_ARGS;
978 }
979 }
980
GetAutoLaunchKVProperties(const AutoLaunchParam & param,const std::shared_ptr<KvDBProperties> & propertiesPtr,bool checkDir)981 int AutoLaunch::GetAutoLaunchKVProperties(const AutoLaunchParam ¶m,
982 const std::shared_ptr<KvDBProperties> &propertiesPtr, bool checkDir)
983 {
984 SchemaObject schemaObject;
985 std::string canonicalDir;
986 int errCode = ParamCheckUtils::CheckAndTransferAutoLaunchParam(param, checkDir, schemaObject, canonicalDir);
987 if (errCode != E_OK) {
988 return errCode;
989 }
990
991 if (param.option.isEncryptedDb) {
992 propertiesPtr->SetPassword(param.option.cipher, param.option.passwd);
993 }
994 propertiesPtr->SetStringProp(KvDBProperties::DATA_DIR, canonicalDir);
995 propertiesPtr->SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, param.option.createIfNecessary);
996 propertiesPtr->SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, param.option.createDirByStoreIdOnly);
997 propertiesPtr->SetBoolProp(KvDBProperties::MEMORY_MODE, false);
998 propertiesPtr->SetBoolProp(KvDBProperties::ENCRYPTED_MODE, param.option.isEncryptedDb);
999 propertiesPtr->SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE);
1000 propertiesPtr->SetSchema(schemaObject);
1001 if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) {
1002 propertiesPtr->SetIntProp(KvDBProperties::SECURITY_LABEL, param.option.secOption.securityLabel);
1003 propertiesPtr->SetIntProp(KvDBProperties::SECURITY_FLAG, param.option.secOption.securityFlag);
1004 }
1005 propertiesPtr->SetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, param.option.isNeedCompressOnSync);
1006 if (param.option.isNeedCompressOnSync) {
1007 propertiesPtr->SetIntProp(KvDBProperties::COMPRESSION_RATE,
1008 ParamCheckUtils::GetValidCompressionRate(param.option.compressionRate));
1009 }
1010 propertiesPtr->SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, param.option.syncDualTupleMode);
1011 DBCommon::SetDatabaseIds(*propertiesPtr, param.appId, param.userId, param.storeId);
1012 return E_OK;
1013 }
1014
GetAutoLaunchRelationProperties(const AutoLaunchParam & param,const std::shared_ptr<RelationalDBProperties> & propertiesPtr)1015 int AutoLaunch::GetAutoLaunchRelationProperties(const AutoLaunchParam ¶m,
1016 const std::shared_ptr<RelationalDBProperties> &propertiesPtr)
1017 {
1018 if (!ParamCheckUtils::CheckStoreParameter(param.storeId, param.appId, param.userId)) {
1019 LOGE("[AutoLaunch] CheckStoreParameter is invalid.");
1020 return -E_INVALID_ARGS;
1021 }
1022 propertiesPtr->SetStringProp(RelationalDBProperties::DATA_DIR, param.path);
1023 propertiesPtr->SetIdentifier(param.userId, param.appId, param.storeId);
1024 propertiesPtr->SetBoolProp(RelationalDBProperties::SYNC_DUAL_TUPLE_MODE, param.option.syncDualTupleMode);
1025 if (param.option.isEncryptedDb) {
1026 if (!ParamCheckUtils::CheckEncryptedParameter(param.option.cipher, param.option.passwd) ||
1027 param.option.iterateTimes == 0) {
1028 return -E_INVALID_ARGS;
1029 }
1030 propertiesPtr->SetCipherArgs(param.option.cipher, param.option.passwd, param.option.iterateTimes);
1031 }
1032 propertiesPtr->SetIntProp(AUTO_LAUNCH_ID, static_cast<int>(RuntimeContext::GetInstance()->GenerateSessionId()));
1033 return E_OK;
1034 }
1035
ExtAutoLaunchRequestCallBack(const std::string & identifier,AutoLaunchParam & param,DBType & openType)1036 int AutoLaunch::ExtAutoLaunchRequestCallBack(const std::string &identifier, AutoLaunchParam ¶m, DBType &openType)
1037 {
1038 std::lock_guard<std::mutex> lock(extLock_);
1039 if (autoLaunchRequestCallbackMap_.empty()) {
1040 LOGI("[AutoLaunch] autoLaunchRequestCallbackMap_ is empty");
1041 return -E_NOT_FOUND; // not E_OK is ok for communicator
1042 }
1043
1044 bool needOpen = false;
1045 for (const auto &[type, callBack] : autoLaunchRequestCallbackMap_) {
1046 needOpen = callBack(identifier, param);
1047 if (needOpen) {
1048 openType = type;
1049 break;
1050 }
1051 }
1052
1053 if (!needOpen) {
1054 LOGI("[AutoLaunch] autoLaunchRequestCallback is not need open");
1055 return -E_NOT_FOUND; // not E_OK is ok for communicator
1056 }
1057 // inner error happened
1058 if (openType >= DBType::DB_INVALID) {
1059 LOGW("[AutoLaunch] Unknown DB Type, Ignore the open request");
1060 return -E_NOT_FOUND; // not E_OK is ok for communicator
1061 }
1062 return E_OK;
1063 }
1064
OpenKvConnection(AutoLaunchItem & autoLaunchItem)1065 int AutoLaunch::OpenKvConnection(AutoLaunchItem &autoLaunchItem)
1066 {
1067 std::shared_ptr<KvDBProperties> properties =
1068 std::static_pointer_cast<KvDBProperties>(autoLaunchItem.propertiesPtr);
1069 int errCode = E_OK;
1070 IKvDBConnection *conn = KvDBManager::GetDatabaseConnection(*properties, errCode, false);
1071 if (errCode == -E_ALREADY_OPENED) {
1072 LOGI("[AutoLaunch] GetOneConnection user already getkvstore by self");
1073 } else if (conn == nullptr) {
1074 LOGE("[AutoLaunch] GetOneConnection GetDatabaseConnection failed errCode:%d", errCode);
1075 }
1076 autoLaunchItem.conn = conn;
1077 return errCode;
1078 }
1079
OpenRelationalConnection(AutoLaunchItem & autoLaunchItem)1080 int AutoLaunch::OpenRelationalConnection(AutoLaunchItem &autoLaunchItem)
1081 {
1082 std::shared_ptr<RelationalDBProperties> properties =
1083 std::static_pointer_cast<RelationalDBProperties>(autoLaunchItem.propertiesPtr);
1084 int errCode = E_OK;
1085 auto conn = RelationalStoreInstance::GetDatabaseConnection(*properties, errCode);
1086 if (errCode == -E_ALREADY_OPENED) {
1087 LOGI("[AutoLaunch] GetOneConnection user already openstore by self");
1088 } else if (conn == nullptr) {
1089 LOGE("[AutoLaunch] GetOneConnection GetDatabaseConnection failed errCode:%d", errCode);
1090 }
1091 autoLaunchItem.conn = conn;
1092 return errCode;
1093 }
1094
RegisterLifeCycleCallback(AutoLaunchItem & autoLaunchItem,const std::string & identifier,bool isExt)1095 int AutoLaunch::RegisterLifeCycleCallback(AutoLaunchItem &autoLaunchItem, const std::string &identifier,
1096 bool isExt)
1097 {
1098 int errCode = E_OK;
1099 DatabaseLifeCycleNotifier notifier;
1100 if (isExt) {
1101 notifier = std::bind(
1102 &AutoLaunch::ExtConnectionLifeCycleCallback, this, std::placeholders::_1, std::placeholders::_2);
1103 } else {
1104 notifier = std::bind(&AutoLaunch::ConnectionLifeCycleCallback,
1105 this, std::placeholders::_1, std::placeholders::_2);
1106 }
1107 switch (autoLaunchItem.type) {
1108 case DBType::DB_KV:
1109 errCode = static_cast<IKvDBConnection *>(autoLaunchItem.conn)->RegisterLifeCycleCallback(notifier);
1110 break;
1111 case DBType::DB_RELATION:
1112 errCode =
1113 static_cast<RelationalStoreConnection *>(autoLaunchItem.conn)->RegisterLifeCycleCallback(notifier);
1114 break;
1115 default:
1116 LOGD("[AutoLaunch] Unknown Type[%d]", static_cast<int>(autoLaunchItem.type));
1117 break;
1118 }
1119 return errCode;
1120 }
1121
PragmaAutoSync(AutoLaunchItem & autoLaunchItem)1122 int AutoLaunch::PragmaAutoSync(AutoLaunchItem &autoLaunchItem)
1123 {
1124 int errCode = E_OK;
1125 if (autoLaunchItem.type != DBType::DB_KV) {
1126 LOGD("[AutoLaunch] Current Type[%d] Not Support AutoSync Now", static_cast<int>(autoLaunchItem.type));
1127 return errCode;
1128 }
1129
1130 bool enAutoSync = autoLaunchItem.isAutoSync;
1131 errCode = static_cast<SyncAbleKvDBConnection *>(autoLaunchItem.conn)->Pragma(PRAGMA_AUTO_SYNC,
1132 static_cast<void *>(&enAutoSync));
1133 if (errCode != E_OK) {
1134 LOGE("[AutoLaunch] PRAGMA_AUTO_SYNC failed, errCode:%d", errCode);
1135 return errCode;
1136 }
1137 LOGI("[AutoLaunch] set PRAGMA_AUTO_SYNC ok, enAutoSync=%d", enAutoSync);
1138 return errCode;
1139 }
1140
TryCloseKvConnection(AutoLaunchItem & autoLaunchItem)1141 void AutoLaunch::TryCloseKvConnection(AutoLaunchItem &autoLaunchItem)
1142 {
1143 LOGI("[AutoLaunch] TryCloseKvConnection");
1144 if (autoLaunchItem.conn == nullptr) {
1145 LOGI("[AutoLaunch] TryCloseKvConnection conn is nullptr, do nothing");
1146 return;
1147 }
1148 IKvDBConnection *kvConn = static_cast<IKvDBConnection *>(autoLaunchItem.conn);
1149 int errCode = kvConn->RegisterLifeCycleCallback(nullptr);
1150 if (errCode != E_OK) {
1151 LOGE("[AutoLaunch] TryCloseKvConnection RegisterLifeCycleCallback failed errCode:%d", errCode);
1152 }
1153 if (autoLaunchItem.observerHandle != nullptr) {
1154 errCode = kvConn->UnRegisterObserver(autoLaunchItem.observerHandle);
1155 if (errCode != E_OK) {
1156 LOGE("[AutoLaunch] TryCloseKvConnection UnRegisterObserver failed errCode:%d", errCode);
1157 }
1158 autoLaunchItem.observerHandle = nullptr;
1159 }
1160 errCode = KvDBManager::ReleaseDatabaseConnection(kvConn);
1161 if (errCode != E_OK) {
1162 LOGE("[AutoLaunch] TryCloseKvConnection ReleaseDatabaseConnection failed errCode:%d", errCode);
1163 }
1164 }
1165
TryCloseRelationConnection(AutoLaunchItem & autoLaunchItem)1166 void AutoLaunch::TryCloseRelationConnection(AutoLaunchItem &autoLaunchItem)
1167 {
1168 LOGI("[AutoLaunch] TryCloseRelationConnection");
1169 if (autoLaunchItem.conn == nullptr) {
1170 LOGI("[AutoLaunch] TryCloseRelationConnection conn is nullptr, do nothing");
1171 return;
1172 }
1173 RelationalStoreConnection *rdbConn = static_cast<RelationalStoreConnection *>(autoLaunchItem.conn);
1174 int errCode = rdbConn->RegisterLifeCycleCallback(nullptr);
1175 if (errCode != E_OK) {
1176 LOGE("[AutoLaunch] TryCloseRelationConnection RegisterLifeCycleCallback failed errCode:%d", errCode);
1177 }
1178 errCode = rdbConn->Close();
1179 if (errCode != E_OK) {
1180 LOGE("[AutoLaunch] TryCloseRelationConnection close connection failed errCode:%d", errCode);
1181 }
1182 }
1183
EraseAutoLauchItem(const std::string & identifier,const std::string & userId)1184 void AutoLaunch::EraseAutoLauchItem(const std::string &identifier, const std::string &userId)
1185 {
1186 std::lock_guard<std::mutex> autoLock(dataLock_);
1187 autoLaunchItemMap_[identifier].erase(userId);
1188 if (autoLaunchItemMap_[identifier].empty()) {
1189 autoLaunchItemMap_.erase(identifier);
1190 }
1191 }
1192
NotifyInvalidParam(const AutoLaunchItem & autoLaunchItem)1193 void AutoLaunch::NotifyInvalidParam(const AutoLaunchItem &autoLaunchItem)
1194 {
1195 if (!autoLaunchItem.notifier) {
1196 return;
1197 }
1198 int retCode = RuntimeContext::GetInstance()->ScheduleTask([autoLaunchItem] {
1199 std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::USER_ID, "");
1200 std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, "");
1201 std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, "");
1202 autoLaunchItem.notifier(userId, appId, storeId, INVALID_PARAM);
1203 });
1204 if (retCode != E_OK) {
1205 LOGE("[AutoLaunch] AutoLaunchExt notifier ScheduleTask retCode:%d", retCode);
1206 }
1207 }
1208
CheckAutoLaunchRealPath(const AutoLaunchItem & autoLaunchItem)1209 int AutoLaunch::CheckAutoLaunchRealPath(const AutoLaunchItem &autoLaunchItem)
1210 {
1211 std::string canonicalDir;
1212 std::string dataDir = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::DATA_DIR, "");
1213 if (!ParamCheckUtils::CheckDataDir(dataDir, canonicalDir)) {
1214 LOGE("[AutoLaunch] CheckDataDir is invalid Auto Launch failed.");
1215 NotifyInvalidParam(autoLaunchItem);
1216 return -E_INVALID_ARGS;
1217 }
1218 autoLaunchItem.propertiesPtr->SetStringProp(DBProperties::DATA_DIR, canonicalDir);
1219 return E_OK;
1220 }
1221
Dump(int fd)1222 void AutoLaunch::Dump(int fd)
1223 {
1224 std::lock_guard<std::mutex> lock(dataLock_);
1225 DBDumpHelper::Dump(fd, "\tenableAutoLaunch info [\n");
1226 for (const auto &[label, userItem] : autoLaunchItemMap_) {
1227 DBDumpHelper::Dump(fd, "\t\tlabel = %s, userId = [\n", DBCommon::TransferStringToHex(label).c_str());
1228 for (const auto &entry : userItem) {
1229 DBDumpHelper::Dump(fd, "\t\t\t%s\n", entry.first.c_str());
1230 }
1231 DBDumpHelper::Dump(fd, "\t\t]\n");
1232 }
1233 DBDumpHelper::Dump(fd, "\t]\n");
1234 }
1235
RegisterKvObserver(AutoLaunchItem & autoLaunchItem,const std::string & identifier,bool isExt)1236 int AutoLaunch::RegisterKvObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt)
1237 {
1238 std::shared_ptr<KvDBProperties> properties =
1239 std::static_pointer_cast<KvDBProperties>(autoLaunchItem.propertiesPtr);
1240 std::string userId = properties->GetStringProp(KvDBProperties::USER_ID, "");
1241 int errCode;
1242 Key key;
1243 KvDBObserverHandle *observerHandle = nullptr;
1244 IKvDBConnection *kvConn = static_cast<IKvDBConnection *>(autoLaunchItem.conn);
1245 observerHandle = kvConn->RegisterObserver(OBSERVER_CHANGES_FOREIGN, key,
1246 std::bind((isExt ? &AutoLaunch::ExtObserverFunc : &AutoLaunch::ObserverFunc), this, std::placeholders::_1,
1247 identifier, userId), errCode);
1248 if (errCode != E_OK) {
1249 LOGE("[AutoLaunch] RegisterObserver failed:%d!", errCode);
1250 return errCode;
1251 }
1252 autoLaunchItem.observerHandle = observerHandle;
1253 return errCode;
1254 }
1255
RegisterRelationalObserver(AutoLaunchItem & autoLaunchItem,const std::string & identifier,bool isExt)1256 int AutoLaunch::RegisterRelationalObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt)
1257 {
1258 RelationalStoreConnection *conn = static_cast<RelationalStoreConnection *>(autoLaunchItem.conn);
1259 conn->RegisterObserverAction([this, autoLaunchItem, identifier](const std::string &changedDevice) {
1260 RelationalStoreChangedDataImpl data(changedDevice);
1261 std::string userId;
1262 std::string appId;
1263 std::string storeId;
1264 if (autoLaunchItem.propertiesPtr != nullptr) {
1265 userId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::USER_ID, "");
1266 appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, "");
1267 storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, "");
1268 data.SetStoreProperty({ userId, appId, storeId });
1269 }
1270 if (autoLaunchItem.storeObserver) {
1271 LOGD("begin to observer onchange, changedDevice=%s", STR_MASK(changedDevice));
1272 autoLaunchItem.storeObserver->OnChange(data);
1273 }
1274 bool isWriteOpenNotified = false;
1275 AutoLaunchNotifier notifier = nullptr;
1276 {
1277 std::lock_guard<std::mutex> autoLock(extLock_);
1278 if (extItemMap_.find(identifier) == extItemMap_.end() ||
1279 extItemMap_[identifier].find(userId) == extItemMap_[identifier].end()) {
1280 LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map");
1281 return;
1282 }
1283 notifier = extItemMap_[identifier][userId].notifier;
1284 isWriteOpenNotified = extItemMap_[identifier][userId].isWriteOpenNotified;
1285 extItemMap_[identifier][userId].isWriteOpenNotified = true;
1286 }
1287 if (!isWriteOpenNotified && notifier != nullptr) {
1288 notifier(userId, appId, storeId, WRITE_OPENED);
1289 }
1290 });
1291 return E_OK;
1292 }
1293
CloseConnection(DBType type,const DBProperties & properties)1294 void AutoLaunch::CloseConnection(DBType type, const DBProperties &properties)
1295 {
1296 if (type != DBType::DB_RELATION) {
1297 return;
1298 }
1299 std::string identifier = properties.GetStringProp(DBProperties::IDENTIFIER_DATA, "");
1300 int closeId = properties.GetIntProp(AUTO_LAUNCH_ID, 0);
1301 std::lock_guard<std::mutex> lock(extLock_);
1302 auto itemMapIter = extItemMap_.find(identifier);
1303 if (itemMapIter == extItemMap_.end()) {
1304 LOGD("[AutoLaunch] Abort close because not found id");
1305 return;
1306 }
1307 std::string userId = properties.GetStringProp(DBProperties::USER_ID, "");
1308 auto itemIter = itemMapIter->second.find(userId);
1309 if (itemIter == itemMapIter->second.end()) {
1310 LOGD("[AutoLaunch] Abort close because not found user id");
1311 return;
1312 }
1313 if (itemIter->second.propertiesPtr == nullptr) {
1314 LOGD("[AutoLaunch] Abort close because properties is invalid");
1315 return;
1316 }
1317 int targetId = itemIter->second.propertiesPtr->GetIntProp(AUTO_LAUNCH_ID, 0);
1318 if (closeId != targetId) {
1319 LOGD("[AutoLaunch] Abort close because connection has been closed");
1320 return;
1321 }
1322 TryCloseConnection(itemIter->second);
1323 extItemMap_[identifier].erase(userId);
1324 if (extItemMap_[identifier].size() == 0) {
1325 extItemMap_.erase(identifier);
1326 }
1327 }
1328 } // namespace DistributedDB
1329