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