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 "runtime_context_impl.h"
17
18 #include "communicator_aggregator.h"
19 #include "db_common.h"
20 #include "db_dfx_adapter.h"
21 #include "db_errno.h"
22 #include "kv_store_errno.h"
23 #include "log_print.h"
24 #include "network_adapter.h"
25
26 namespace DistributedDB {
27 #ifdef RUNNING_ON_TESTCASE
28 static std::atomic_uint taskID = 0;
29 #endif
30
RuntimeContextImpl()31 RuntimeContextImpl::RuntimeContextImpl()
32 : adapter_(nullptr),
33 communicatorAggregator_(nullptr),
34 mainLoop_(nullptr),
35 currentTimerId_(0),
36 taskPool_(nullptr),
37 taskPoolReportsTimerId_(0),
38 timeTickMonitor_(nullptr),
39 systemApiAdapter_(nullptr),
40 lockStatusObserver_(nullptr),
41 currentSessionId_(1),
42 dbStatusAdapter_(nullptr),
43 subscribeRecorder_(nullptr),
44 isBatchDownloadAssets_(true)
45 {
46 }
47
48 // Destruct the object.
~RuntimeContextImpl()49 RuntimeContextImpl::~RuntimeContextImpl()
50 {
51 if (taskPoolReportsTimerId_ > 0) { // LCOV_EXCL_BR_LINE
52 RemoveTimer(taskPoolReportsTimerId_, true);
53 taskPoolReportsTimerId_ = 0;
54 }
55 if (taskPool_ != nullptr) { // LCOV_EXCL_BR_LINE
56 taskPool_->Stop();
57 taskPool_->Release(taskPool_);
58 taskPool_ = nullptr;
59 }
60 if (mainLoop_ != nullptr) { // LCOV_EXCL_BR_LINE
61 mainLoop_->Stop();
62 mainLoop_->KillAndDecObjRef(mainLoop_);
63 mainLoop_ = nullptr;
64 }
65 SetCommunicatorAggregator(nullptr);
66 (void)SetCommunicatorAdapter(nullptr);
67 systemApiAdapter_ = nullptr;
68 delete lockStatusObserver_;
69 lockStatusObserver_ = nullptr;
70 userChangeMonitor_ = nullptr;
71 dbStatusAdapter_ = nullptr;
72 subscribeRecorder_ = nullptr;
73 SetThreadPool(nullptr);
74 }
75
76 // Set the label of this process.
SetProcessLabel(const std::string & label)77 void RuntimeContextImpl::SetProcessLabel(const std::string &label)
78 {
79 std::lock_guard<std::mutex> labelLock(labelMutex_);
80 processLabel_ = label;
81 }
82
GetProcessLabel() const83 std::string RuntimeContextImpl::GetProcessLabel() const
84 {
85 std::lock_guard<std::mutex> labelLock(labelMutex_);
86 return processLabel_;
87 }
88
SetCommunicatorAdapter(IAdapter * adapter)89 int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter)
90 {
91 {
92 std::lock_guard<std::mutex> autoLock(communicatorLock_);
93 if (adapter_ != nullptr) {
94 if (communicatorAggregator_ != nullptr) {
95 return -E_NOT_SUPPORT;
96 }
97 delete adapter_;
98 }
99 adapter_ = adapter;
100 }
101 ICommunicatorAggregator *communicatorAggregator = nullptr;
102 GetCommunicatorAggregator(communicatorAggregator);
103 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator);
104 return E_OK;
105 }
106
GetCommunicatorAggregator(ICommunicatorAggregator * & outAggregator)107 int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator)
108 {
109 outAggregator = nullptr;
110 const std::shared_ptr<DBStatusAdapter> statusAdapter = GetDBStatusAdapter();
111 if (statusAdapter == nullptr) {
112 return -E_OUT_OF_MEMORY;
113 }
114 std::lock_guard<std::mutex> lock(communicatorLock_);
115 if (communicatorAggregator_ != nullptr) {
116 outAggregator = communicatorAggregator_;
117 return E_OK;
118 }
119
120 if (adapter_ == nullptr) {
121 LOGE("Adapter has not set!");
122 return -E_NOT_INIT;
123 }
124
125 communicatorAggregator_ = new (std::nothrow) CommunicatorAggregator;
126 if (communicatorAggregator_ == nullptr) {
127 LOGE("CommunicatorAggregator create failed, may be no available memory!");
128 return -E_OUT_OF_MEMORY;
129 }
130
131 int errCode = communicatorAggregator_->Initialize(adapter_, statusAdapter);
132 if (errCode != E_OK) {
133 LOGE("CommunicatorAggregator init failed, err = %d!", errCode);
134 RefObject::KillAndDecObjRef(communicatorAggregator_);
135 communicatorAggregator_ = nullptr;
136 }
137 outAggregator = communicatorAggregator_;
138 return errCode;
139 }
140
SetCommunicatorAggregator(ICommunicatorAggregator * inAggregator)141 void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator)
142 {
143 std::lock_guard<std::mutex> autoLock(communicatorLock_);
144 if (communicatorAggregator_ != nullptr) {
145 autoLaunch_.SetCommunicatorAggregator(nullptr);
146 communicatorAggregator_->Finalize();
147 RefObject::KillAndDecObjRef(communicatorAggregator_);
148 }
149 communicatorAggregator_ = inAggregator;
150 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_);
151 }
152
GetLocalIdentity(std::string & outTarget)153 int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget)
154 {
155 std::lock_guard<std::mutex> autoLock(communicatorLock_);
156 if (communicatorAggregator_ != nullptr) {
157 return communicatorAggregator_->GetLocalIdentity(outTarget);
158 }
159 LOGW("[RuntimeContextImpl] Get local id without communicatorAggregator");
160 return -E_NOT_INIT;
161 }
162
163 // Add and start a timer.
SetTimer(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,TimerId & timerId)164 int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action,
165 const TimerFinalizer &finalizer, TimerId &timerId)
166 {
167 timerId = 0;
168 if ((milliSeconds < 0) || !action) {
169 return -E_INVALID_ARGS;
170 }
171 int errCode = SetTimerByThreadPool(milliSeconds, action, finalizer, true, timerId);
172 if (errCode != -E_NOT_SUPPORT) {
173 return errCode;
174 }
175 IEventLoop *loop = nullptr;
176 errCode = PrepareLoop(loop);
177 if (errCode != E_OK) {
178 LOGE("SetTimer(), prepare loop failed.");
179 return errCode;
180 }
181
182 IEvent *evTimer = IEvent::CreateEvent(milliSeconds, errCode);
183 if (evTimer == nullptr) {
184 RefObject::DecObjRef(loop);
185 loop = nullptr;
186 return errCode;
187 }
188
189 errCode = AllocTimerId(evTimer, timerId);
190 if (errCode != E_OK) {
191 RefObject::DecObjRef(evTimer);
192 evTimer = nullptr;
193 RefObject::DecObjRef(loop);
194 loop = nullptr;
195 return errCode;
196 }
197
198 evTimer->SetAction([this, timerId, action](EventsMask revents) -> int {
199 int errCodeInner = action(timerId);
200 if (errCodeInner != E_OK) {
201 RemoveTimer(timerId, false);
202 }
203 return errCodeInner;
204 },
205 finalizer);
206
207 errCode = loop->Add(evTimer);
208 if (errCode != E_OK) {
209 evTimer->IgnoreFinalizer();
210 RemoveTimer(timerId, false);
211 timerId = 0;
212 }
213
214 RefObject::DecObjRef(loop);
215 loop = nullptr;
216 return errCode;
217 }
218
219 // Modify the interval of the timer.
ModifyTimer(TimerId timerId,int milliSeconds)220 int RuntimeContextImpl::ModifyTimer(TimerId timerId, int milliSeconds)
221 {
222 if (milliSeconds < 0) {
223 return -E_INVALID_ARGS;
224 }
225 int errCode = ModifyTimerByThreadPool(timerId, milliSeconds);
226 if (errCode != -E_NOT_SUPPORT) {
227 return errCode;
228 }
229 std::lock_guard<std::mutex> autoLock(timersLock_);
230 auto iter = timers_.find(timerId);
231 if (iter == timers_.end()) {
232 return -E_NO_SUCH_ENTRY;
233 }
234
235 IEvent *evTimer = iter->second;
236 if (evTimer == nullptr) {
237 return -E_INTERNAL_ERROR;
238 }
239 return evTimer->SetTimeout(milliSeconds);
240 }
241
242 // Remove the timer.
RemoveTimer(TimerId timerId,bool wait)243 void RuntimeContextImpl::RemoveTimer(TimerId timerId, bool wait)
244 {
245 RemoveTimerByThreadPool(timerId, wait);
246 IEvent *evTimer = nullptr;
247 {
248 std::lock_guard<std::mutex> autoLock(timersLock_);
249 auto iter = timers_.find(timerId);
250 if (iter == timers_.end()) {
251 return;
252 }
253 evTimer = iter->second;
254 timers_.erase(iter);
255 }
256
257 if (evTimer != nullptr) {
258 evTimer->Detach(wait);
259 RefObject::DecObjRef(evTimer);
260 evTimer = nullptr;
261 }
262 }
263
264 // Task interfaces.
ScheduleTask(const TaskAction & task)265 int RuntimeContextImpl::ScheduleTask(const TaskAction &task)
266 {
267 if (ScheduleTaskByThreadPool(task) == E_OK) {
268 return E_OK;
269 }
270 std::lock_guard<std::mutex> autoLock(taskLock_);
271 int errCode = PrepareTaskPool();
272 if (errCode != E_OK) {
273 LOGE("Schedule task failed, fail to prepare task pool.");
274 return errCode;
275 }
276 #ifdef RUNNING_ON_TESTCASE
277 auto id = taskID++;
278 LOGI("Schedule task succeed, ID:%u", id);
279 return taskPool_->Schedule([task, id] {
280 LOGI("Execute task, ID:%u", id);
281 task();
282 });
283 #else
284 return taskPool_->Schedule(task);
285 #endif
286 }
287
ScheduleQueuedTask(const std::string & queueTag,const TaskAction & task)288 int RuntimeContextImpl::ScheduleQueuedTask(const std::string &queueTag,
289 const TaskAction &task)
290 {
291 if (ScheduleTaskByThreadPool(task) == E_OK) {
292 return E_OK;
293 }
294 std::lock_guard<std::mutex> autoLock(taskLock_);
295 int errCode = PrepareTaskPool();
296 if (errCode != E_OK) {
297 LOGE("Schedule queued task failed, fail to prepare task pool.");
298 return errCode;
299 }
300 #ifdef RUNNING_ON_TESTCASE
301 auto id = taskID++;
302 LOGI("Schedule queued task succeed, ID:%u", id);
303 return taskPool_->Schedule(queueTag, [task, id] {
304 LOGI("Execute queued task, ID:%u", id);
305 task();
306 });
307 #else
308 return taskPool_->Schedule(queueTag, task);
309 #endif
310 }
311
ShrinkMemory(const std::string & description)312 void RuntimeContextImpl::ShrinkMemory(const std::string &description)
313 {
314 std::lock_guard<std::mutex> autoLock(taskLock_);
315 if (taskPool_ != nullptr) { // LCOV_EXCL_BR_LINE
316 taskPool_->ShrinkMemory(description);
317 }
318 }
319
RegisterTimeChangedLister(const TimeChangedAction & action,const TimeFinalizeAction & finalize,int & errCode)320 NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const TimeChangedAction &action,
321 const TimeFinalizeAction &finalize, int &errCode)
322 {
323 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
324 if (timeTickMonitor_ == nullptr) {
325 timeTickMonitor_ = std::make_shared<TimeTickMonitor>();
326 errCode = timeTickMonitor_->StartTimeTickMonitor();
327 if (errCode != E_OK) {
328 LOGE("TimeTickMonitor start failed!");
329 timeTickMonitor_ = nullptr;
330 return nullptr;
331 }
332 LOGD("[RuntimeContext] TimeTickMonitor start success");
333 }
334 return timeTickMonitor_->RegisterTimeChangedLister(action, finalize, errCode);
335 }
336
PrepareLoop(IEventLoop * & loop)337 int RuntimeContextImpl::PrepareLoop(IEventLoop *&loop)
338 {
339 std::lock_guard<std::mutex> autoLock(loopLock_);
340 if (mainLoop_ != nullptr) {
341 loop = mainLoop_;
342 RefObject::IncObjRef(loop); // ref 1 returned to caller.
343 return E_OK;
344 }
345
346 int errCode = E_OK;
347 loop = IEventLoop::CreateEventLoop(errCode);
348 if (loop == nullptr) {
349 return errCode;
350 }
351
352 RefObject::IncObjRef(loop); // ref 1 owned by thread.
353 std::thread loopThread([loop]() {
354 loop->Run();
355 RefObject::DecObjRef(loop); // ref 1 dropped by thread.
356 });
357 loopThread.detach();
358
359 mainLoop_ = loop;
360 RefObject::IncObjRef(loop); // ref 1 returned to caller.
361 return E_OK;
362 }
363
PrepareTaskPool()364 int RuntimeContextImpl::PrepareTaskPool()
365 {
366 if (taskPool_ != nullptr) {
367 return E_OK;
368 }
369
370 int errCode = E_OK;
371 TaskPool *taskPool = TaskPool::Create(MAX_TP_THREADS, MIN_TP_THREADS, errCode);
372 if (taskPool == nullptr) {
373 return errCode;
374 }
375
376 errCode = taskPool->Start();
377 if (errCode != E_OK) {
378 taskPool->Release(taskPool);
379 return errCode;
380 }
381
382 taskPool_ = taskPool;
383 return E_OK;
384 }
385
AllocTimerId(IEvent * evTimer,TimerId & timerId)386 int RuntimeContextImpl::AllocTimerId(IEvent *evTimer, TimerId &timerId)
387 {
388 std::lock_guard<std::mutex> autoLock(timersLock_);
389 TimerId startId = currentTimerId_;
390 while (++currentTimerId_ != startId) {
391 if (currentTimerId_ == 0) {
392 continue;
393 }
394 if (timers_.find(currentTimerId_) == timers_.end()) {
395 timerId = currentTimerId_;
396 timers_[timerId] = evTimer;
397 return E_OK;
398 }
399 }
400 return -E_OUT_OF_IDS;
401 }
402
SetPermissionCheckCallback(const PermissionCheckCallback & callback)403 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
404 {
405 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
406 permissionCheckCallback_ = callback;
407 LOGI("SetPermissionCheckCallback ok");
408 return E_OK;
409 }
410
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)411 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
412 {
413 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
414 permissionCheckCallbackV2_ = callback;
415 LOGI("SetPermissionCheckCallback V2 ok");
416 return E_OK;
417 }
418
SetPermissionCheckCallback(const PermissionCheckCallbackV3 & callback)419 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV3 &callback)
420 {
421 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
422 permissionCheckCallbackV3_ = callback;
423 LOGI("SetPermissionCheckCallback V3 ok");
424 return E_OK;
425 }
426
SetPermissionCheckCallback(const PermissionCheckCallbackV4 & callback)427 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV4 &callback)
428 {
429 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
430 permissionCheckCallbackV4_ = callback;
431 LOGI("SetPermissionCheckCallback V4 ok");
432 return E_OK;
433 }
434
RunPermissionCheck(const PermissionCheckParam & param,uint8_t flag) const435 int RuntimeContextImpl::RunPermissionCheck(const PermissionCheckParam ¶m, uint8_t flag) const
436 {
437 bool checkResult = false;
438 std::shared_lock<std::shared_mutex> autoLock(permissionCheckCallbackMutex_);
439 if (permissionCheckCallbackV4_) {
440 PermissionCheckParamV4 paramV4;
441 paramV4.appId = param.appId;
442 paramV4.userId = param.userId;
443 paramV4.storeId = param.storeId;
444 paramV4.deviceId = param.deviceId;
445 paramV4.subUserId = param.subUserId;
446 checkResult = permissionCheckCallbackV4_(paramV4, flag);
447 } else if (permissionCheckCallbackV3_) {
448 checkResult = permissionCheckCallbackV3_(param, flag);
449 } else if (permissionCheckCallbackV2_) {
450 checkResult = permissionCheckCallbackV2_(param.userId, param.appId, param.storeId, param.deviceId, flag);
451 } else if (permissionCheckCallback_) {
452 checkResult = permissionCheckCallback_(param.userId, param.appId, param.storeId, flag);
453 } else {
454 return E_OK;
455 }
456 if (checkResult) {
457 return E_OK;
458 }
459 return -E_NOT_PERMIT;
460 }
461
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)462 int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
463 const AutoLaunchOption &option)
464 {
465 return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option);
466 }
467
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)468 int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier,
469 const std::string &dualTupleIdentifier, const std::string &userId)
470 {
471 return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId);
472 }
473
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const474 void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier,
475 std::vector<std::string> &devices) const
476 {
477 return autoLaunch_.GetAutoLaunchSyncDevices(identifier, devices);
478 }
479
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBTypeInner type)480 void RuntimeContextImpl::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBTypeInner type)
481 {
482 autoLaunch_.SetAutoLaunchRequestCallback(callback, type);
483 }
484
RegisterLockStatusLister(const LockStatusNotifier & action,int & errCode)485 NotificationChain::Listener *RuntimeContextImpl::RegisterLockStatusLister(const LockStatusNotifier &action,
486 int &errCode)
487 {
488 std::lock(lockStatusLock_, systemApiAdapterLock_);
489 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
490 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
491 if (lockStatusObserver_ == nullptr) {
492 lockStatusObserver_ = new (std::nothrow) LockStatusObserver();
493 if (lockStatusObserver_ == nullptr) {
494 LOGE("lockStatusObserver_ is nullptr");
495 errCode = -E_OUT_OF_MEMORY;
496 return nullptr;
497 }
498 }
499
500 if (!lockStatusObserver_->IsStarted()) {
501 errCode = lockStatusObserver_->Start();
502 if (errCode != E_OK) {
503 LOGE("lockStatusObserver start failed, err = %d", errCode);
504 delete lockStatusObserver_;
505 lockStatusObserver_ = nullptr;
506 return nullptr;
507 }
508
509 if (systemApiAdapter_ != nullptr) {
510 auto callback = [lockStatusObserver = lockStatusObserver_](bool isLocked) {
511 lockStatusObserver->OnStatusChange(isLocked);
512 };
513 errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
514 if (errCode != OK) {
515 delete lockStatusObserver_;
516 lockStatusObserver_ = nullptr;
517 return nullptr;
518 }
519 }
520 }
521
522 NotificationChain::Listener *listener = lockStatusObserver_->RegisterLockStatusChangedLister(action, errCode);
523 if ((listener == nullptr) || (errCode != E_OK)) {
524 LOGE("Register lock status changed listener failed, err = %d", errCode);
525 delete lockStatusObserver_;
526 lockStatusObserver_ = nullptr;
527 return nullptr;
528 }
529 return listener;
530 }
531
IsAccessControlled() const532 bool RuntimeContextImpl::IsAccessControlled() const
533 {
534 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
535 if (systemApiAdapter_ == nullptr) {
536 return false;
537 }
538 return systemApiAdapter_->IsAccessControlled();
539 }
540
SetSecurityOption(const std::string & filePath,const SecurityOption & option) const541 int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option) const
542 {
543 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
544 if (systemApiAdapter_ == nullptr || !OS::CheckPathExistence(filePath)) {
545 LOGI("Adapter is not set, or path not existed, not support set security option!");
546 return -E_NOT_SUPPORT;
547 }
548
549 std::string fileRealPath;
550 int errCode = OS::GetRealPath(filePath, fileRealPath);
551 if (errCode != E_OK) {
552 LOGE("Get real path failed when set security option!");
553 return errCode;
554 }
555
556 DBStatus dbErrCode = systemApiAdapter_->SetSecurityOption(fileRealPath, option);
557 if (dbErrCode != OK) {
558 LOGE("SetSecurityOption failed, errCode = %d", dbErrCode);
559 return TransferDBStatusToErr(dbErrCode);
560 }
561 return E_OK;
562 }
563
GetSecurityOption(const std::string & filePath,SecurityOption & option) const564 int RuntimeContextImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
565 {
566 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
567 if (systemApiAdapter_ == nullptr) {
568 LOGI("Get Security option, but not set system api adapter!");
569 return -E_NOT_SUPPORT;
570 }
571 int errCode = systemApiAdapter_->GetSecurityOption(filePath, option);
572 if (errCode != OK) {
573 if (errCode == NOT_SUPPORT) {
574 return -E_NOT_SUPPORT;
575 }
576 LOGE("GetSecurityOption failed, errCode = %d", errCode);
577 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
578 }
579
580 LOGD("Get security option from system adapter [%d, %d]", option.securityLabel, option.securityFlag);
581 // This interface may return success but failed to obtain the flag and modified it to -1
582 if (option.securityFlag == INVALID_SEC_FLAG) {
583 // Currently ignoring the failure to obtain flags -1 other than S3, modify the flag to the default value
584 if (option.securityLabel == S3) {
585 LOGE("GetSecurityOption failed, SecurityOption is invalid [3, -1]!");
586 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
587 }
588 option.securityFlag = 0; // 0 is default value
589 }
590 return E_OK;
591 }
592
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const593 bool RuntimeContextImpl::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const
594 {
595 std::shared_ptr<IProcessSystemApiAdapter> tempSystemApiAdapter = nullptr;
596 {
597 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
598 if (systemApiAdapter_ == nullptr) {
599 LOGI("[CheckDeviceSecurityAbility] security not set");
600 return true;
601 }
602 tempSystemApiAdapter = systemApiAdapter_;
603 }
604
605 return tempSystemApiAdapter->CheckDeviceSecurityAbility(devId, option);
606 }
607
SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)608 int RuntimeContextImpl::SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
609 {
610 std::lock(lockStatusLock_, systemApiAdapterLock_);
611 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
612 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
613 systemApiAdapter_ = adapter;
614 if (systemApiAdapter_ != nullptr && lockStatusObserver_ != nullptr && lockStatusObserver_->IsStarted()) {
615 auto callback = [lockStatusObserver = lockStatusObserver_](bool isLocked) {
616 lockStatusObserver->OnStatusChange(isLocked);
617 };
618 int errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
619 if (errCode != OK) {
620 LOGE("Register access controlled event failed while setting adapter, err = %d", errCode);
621 delete lockStatusObserver_;
622 lockStatusObserver_ = nullptr;
623 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
624 }
625 }
626 return E_OK;
627 }
628
IsProcessSystemApiAdapterValid() const629 bool RuntimeContextImpl::IsProcessSystemApiAdapterValid() const
630 {
631 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
632 return (systemApiAdapter_ != nullptr);
633 }
634
NotifyTimestampChanged(TimeOffset offset) const635 void RuntimeContextImpl::NotifyTimestampChanged(TimeOffset offset) const
636 {
637 std::shared_ptr<TimeTickMonitor> timeTickMonitor = nullptr;
638 {
639 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
640 if (timeTickMonitor_ == nullptr) {
641 LOGD("NotifyTimestampChanged fail, timeTickMonitor_ is null.");
642 return;
643 }
644 timeTickMonitor = timeTickMonitor_;
645 }
646 timeTickMonitor->NotifyTimeChange(offset);
647 }
648
IsCommunicatorAggregatorValid() const649 bool RuntimeContextImpl::IsCommunicatorAggregatorValid() const
650 {
651 std::lock_guard<std::mutex> autoLock(communicatorLock_);
652 if (communicatorAggregator_ == nullptr && adapter_ == nullptr) {
653 return false;
654 }
655 return true;
656 }
657
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)658 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifier ¬ifier)
659 {
660 std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
661 databaseStatusNotifyCallback_ = notifier;
662 LOGI("SetStoreStatusNotifier ok");
663 }
664
SetStoreStatusNotifier(const StoreStatusNotifierV2 & notifier)665 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifierV2 ¬ifier)
666 {
667 std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
668 databaseStatusNotifyCallbackV2_ = notifier;
669 LOGI("SetStoreStatusNotifier ok");
670 }
671
NotifyDatabaseStatusChange(const StoreStatusNotifierParam & param,bool onlineStatus)672 void RuntimeContextImpl::NotifyDatabaseStatusChange(const StoreStatusNotifierParam ¶m, bool onlineStatus)
673 {
674 ScheduleTask([this, param, onlineStatus] {
675 std::shared_lock<std::shared_mutex> autoLock(databaseStatusCallbackMutex_);
676 if (databaseStatusNotifyCallbackV2_) {
677 LOGI("start notify database status:%d", onlineStatus);
678 databaseStatusNotifyCallbackV2_(param, onlineStatus);
679 }
680 if (databaseStatusNotifyCallback_) {
681 LOGI("start notify database status:%d", onlineStatus);
682 databaseStatusNotifyCallback_(param.userId, param.appId, param.storeId, param.deviceId, onlineStatus);
683 }
684 });
685 }
686
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)687 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
688 {
689 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
690 syncActivationCheckCallback_ = callback;
691 LOGI("SetSyncActivationCheckCallback ok");
692 return E_OK;
693 }
694
SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 & callback)695 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 &callback)
696 {
697 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
698 syncActivationCheckCallbackV2_ = callback;
699 LOGI("SetSyncActivationCheckCallbackV2 ok");
700 return E_OK;
701 }
702
IsSyncerNeedActive(const DBProperties & properties) const703 bool RuntimeContextImpl::IsSyncerNeedActive(const DBProperties &properties) const
704 {
705 ActivationCheckParam param = {
706 properties.GetStringProp(DBProperties::USER_ID, ""),
707 properties.GetStringProp(DBProperties::APP_ID, ""),
708 properties.GetStringProp(DBProperties::STORE_ID, ""),
709 properties.GetStringProp(DBProperties::SUB_USER, ""),
710 properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
711 };
712 std::shared_lock<std::shared_mutex> autoLock(syncActivationCheckCallbackMutex_);
713 if (syncActivationCheckCallbackV2_) {
714 return syncActivationCheckCallbackV2_(param);
715 } else if (syncActivationCheckCallback_) {
716 return syncActivationCheckCallback_(param.userId, param.appId, param.storeId);
717 }
718 return true;
719 }
720
RegisterUserChangedListener(const UserChangedAction & action,EventType event)721 NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListener(const UserChangedAction &action,
722 EventType event)
723 {
724 int errCode;
725 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
726 if (userChangeMonitor_ == nullptr) {
727 userChangeMonitor_ = std::make_unique<UserChangeMonitor>();
728 errCode = userChangeMonitor_->Start();
729 if (errCode != E_OK) {
730 LOGE("UserChangeMonitor start failed!");
731 userChangeMonitor_ = nullptr;
732 return nullptr;
733 }
734 }
735 NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListener(action, event, errCode);
736 if ((listener == nullptr) || (errCode != E_OK)) {
737 LOGE("Register user status changed listener failed, err = %d", errCode);
738 return nullptr;
739 }
740 return listener;
741 }
742
NotifyUserChanged() const743 int RuntimeContextImpl::NotifyUserChanged() const
744 {
745 {
746 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
747 if (userChangeMonitor_ == nullptr) {
748 LOGD("userChangeMonitor is null, all db is in normal sync mode");
749 return E_OK;
750 }
751 }
752 userChangeMonitor_->NotifyUserChanged();
753 return E_OK;
754 }
755
GenerateSessionId()756 uint32_t RuntimeContextImpl::GenerateSessionId()
757 {
758 uint32_t sessionId = currentSessionId_++;
759 if (sessionId == 0) {
760 sessionId = currentSessionId_++;
761 }
762 return sessionId;
763 }
764
DumpCommonInfo(int fd)765 void RuntimeContextImpl::DumpCommonInfo(int fd)
766 {
767 autoLaunch_.Dump(fd);
768 }
769
CloseAutoLaunchConnection(DBTypeInner type,const DBProperties & properties)770 void RuntimeContextImpl::CloseAutoLaunchConnection(DBTypeInner type, const DBProperties &properties)
771 {
772 autoLaunch_.CloseConnection(type, properties);
773 }
774
SetPermissionConditionCallback(const PermissionConditionCallback & callback)775 int RuntimeContextImpl::SetPermissionConditionCallback(const PermissionConditionCallback &callback)
776 {
777 std::unique_lock<std::shared_mutex> autoLock(permissionConditionLock_);
778 permissionConditionCallback_ = callback;
779 return E_OK;
780 }
781
GetPermissionCheckParam(const DBProperties & properties)782 std::map<std::string, std::string> RuntimeContextImpl::GetPermissionCheckParam(const DBProperties &properties)
783 {
784 PermissionConditionParam param = {
785 properties.GetStringProp(DBProperties::USER_ID, ""),
786 properties.GetStringProp(DBProperties::APP_ID, ""),
787 properties.GetStringProp(DBProperties::STORE_ID, ""),
788 properties.GetStringProp(DBProperties::SUB_USER, ""),
789 properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
790 };
791 std::shared_lock<std::shared_mutex> autoLock(permissionConditionLock_);
792 if (permissionConditionCallback_ == nullptr) {
793 return {};
794 }
795 return permissionConditionCallback_(param);
796 }
797
StopTaskPool()798 void RuntimeContextImpl::StopTaskPool()
799 {
800 std::lock_guard<std::mutex> autoLock(taskLock_);
801 if (taskPool_ != nullptr) {
802 taskPool_->Stop();
803 TaskPool::Release(taskPool_);
804 taskPool_ = nullptr;
805 }
806 }
807
StopTimeTickMonitorIfNeed()808 void RuntimeContextImpl::StopTimeTickMonitorIfNeed()
809 {
810 if (IsCommunicatorAggregatorValid()) {
811 return;
812 }
813 // release monitor in client
814 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
815 if (timeTickMonitor_ == nullptr) {
816 return;
817 }
818 if (timeTickMonitor_->EmptyListener()) {
819 LOGD("[RuntimeContext] TimeTickMonitor exist because no listener");
820 timeTickMonitor_ = nullptr;
821 }
822 }
823
SetDBInfoHandle(const std::shared_ptr<DBInfoHandle> & handle)824 void RuntimeContextImpl::SetDBInfoHandle(const std::shared_ptr<DBInfoHandle> &handle)
825 {
826 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
827 if (dbStatusAdapter != nullptr) {
828 dbStatusAdapter->SetDBInfoHandle(handle);
829 }
830 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
831 if (subscribeRecorder != nullptr) {
832 subscribeRecorder->RemoveAllSubscribe();
833 }
834 }
835
NotifyDBInfos(const DeviceInfos & devInfos,const std::vector<DBInfo> & dbInfos)836 void RuntimeContextImpl::NotifyDBInfos(const DeviceInfos &devInfos, const std::vector<DBInfo> &dbInfos)
837 {
838 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
839 if (dbStatusAdapter != nullptr) {
840 dbStatusAdapter->NotifyDBInfos(devInfos, dbInfos);
841 }
842 }
843
GetDBStatusAdapter()844 std::shared_ptr<DBStatusAdapter> RuntimeContextImpl::GetDBStatusAdapter()
845 {
846 std::lock_guard<std::mutex> autoLock(statusAdapterMutex_);
847 if (dbStatusAdapter_ == nullptr) {
848 dbStatusAdapter_ = std::make_unique<DBStatusAdapter>();
849 }
850 if (dbStatusAdapter_ == nullptr) {
851 LOGE("[RuntimeContextImpl] DbStatusAdapter create failed!");
852 }
853 return dbStatusAdapter_;
854 }
855
RecordRemoteSubscribe(const DBInfo & dbInfo,const DeviceID & deviceId,const QuerySyncObject & query)856 void RuntimeContextImpl::RecordRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId,
857 const QuerySyncObject &query)
858 {
859 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
860 if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) {
861 return;
862 }
863 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
864 if (subscribeRecorder != nullptr) {
865 subscribeRecorder->RecordSubscribe(dbInfo, deviceId, query);
866 }
867 }
868
RemoveRemoteSubscribe(const DeviceID & deviceId)869 void RuntimeContextImpl::RemoveRemoteSubscribe(const DeviceID &deviceId)
870 {
871 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
872 if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) {
873 return;
874 }
875 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
876 if (subscribeRecorder != nullptr) {
877 subscribeRecorder->RemoveRemoteSubscribe(deviceId);
878 }
879 }
880
RemoveRemoteSubscribe(const DBInfo & dbInfo)881 void RuntimeContextImpl::RemoveRemoteSubscribe(const DBInfo &dbInfo)
882 {
883 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
884 if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) {
885 return;
886 }
887 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
888 if (subscribeRecorder != nullptr) {
889 subscribeRecorder->RemoveRemoteSubscribe(dbInfo);
890 }
891 }
892
RemoveRemoteSubscribe(const DBInfo & dbInfo,const DeviceID & deviceId)893 void RuntimeContextImpl::RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId)
894 {
895 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
896 if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) {
897 return;
898 }
899 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
900 if (subscribeRecorder != nullptr) {
901 subscribeRecorder->RemoveRemoteSubscribe(dbInfo, deviceId);
902 }
903 }
904
RemoveRemoteSubscribe(const DBInfo & dbInfo,const DeviceID & deviceId,const QuerySyncObject & query)905 void RuntimeContextImpl::RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId,
906 const QuerySyncObject &query)
907 {
908 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
909 if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) {
910 return;
911 }
912 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
913 if (subscribeRecorder != nullptr) {
914 subscribeRecorder->RemoveRemoteSubscribe(dbInfo, deviceId, query);
915 }
916 }
917
GetSubscribeQuery(const DBInfo & dbInfo,std::map<std::string,std::vector<QuerySyncObject>> & subscribeQuery)918 void RuntimeContextImpl::GetSubscribeQuery(const DBInfo &dbInfo,
919 std::map<std::string, std::vector<QuerySyncObject>> &subscribeQuery)
920 {
921 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
922 if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) {
923 return;
924 }
925 std::shared_ptr<SubscribeRecorder> subscribeRecorder = GetSubscribeRecorder();
926 if (subscribeRecorder != nullptr) {
927 subscribeRecorder->GetSubscribeQuery(dbInfo, subscribeQuery);
928 }
929 }
930
GetSubscribeRecorder()931 std::shared_ptr<SubscribeRecorder> RuntimeContextImpl::GetSubscribeRecorder()
932 {
933 std::lock_guard<std::mutex> autoLock(subscribeRecorderMutex_);
934 if (subscribeRecorder_ == nullptr) {
935 subscribeRecorder_ = std::make_unique<SubscribeRecorder>();
936 }
937 if (subscribeRecorder_ == nullptr) {
938 LOGE("[RuntimeContextImpl] SubscribeRecorder create failed!");
939 }
940 return subscribeRecorder_;
941 }
942
IsNeedAutoSync(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & devInfo)943 bool RuntimeContextImpl::IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId,
944 const std::string &devInfo)
945 {
946 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
947 if (dbStatusAdapter == nullptr) {
948 return true;
949 }
950 return dbStatusAdapter->IsNeedAutoSync(userId, appId, storeId, devInfo);
951 }
952
SetRemoteOptimizeCommunication(const std::string & dev,bool optimize)953 void RuntimeContextImpl::SetRemoteOptimizeCommunication(const std::string &dev, bool optimize)
954 {
955 std::shared_ptr<DBStatusAdapter> dbStatusAdapter = GetDBStatusAdapter();
956 if (dbStatusAdapter == nullptr) {
957 return;
958 }
959 dbStatusAdapter->SetRemoteOptimizeCommunication(dev, optimize);
960 }
961
SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback & callback)962 void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback)
963 {
964 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
965 translateToDeviceIdCallback_ = callback;
966 deviceIdCache_.clear();
967 }
968
TranslateDeviceId(const std::string & deviceId,const StoreInfo & info,std::string & newDeviceId)969 int RuntimeContextImpl::TranslateDeviceId(const std::string &deviceId,
970 const StoreInfo &info, std::string &newDeviceId)
971 {
972 const std::string id = DBCommon::GenerateIdentifierId(info.storeId, info.appId, info.userId);
973 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
974 if (translateToDeviceIdCallback_ == nullptr) {
975 return -E_NOT_SUPPORT;
976 }
977 if (deviceIdCache_.find(deviceId) == deviceIdCache_.end() ||
978 deviceIdCache_[deviceId].find(id) == deviceIdCache_[deviceId].end()) {
979 deviceIdCache_[deviceId][id] = translateToDeviceIdCallback_(deviceId, info);
980 }
981 newDeviceId = deviceIdCache_[deviceId][id];
982 return E_OK;
983 }
984
ExistTranslateDevIdCallback() const985 bool RuntimeContextImpl::ExistTranslateDevIdCallback() const
986 {
987 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
988 return translateToDeviceIdCallback_ != nullptr;
989 }
990
SetThreadPool(const std::shared_ptr<IThreadPool> & threadPool)991 void RuntimeContextImpl::SetThreadPool(const std::shared_ptr<IThreadPool> &threadPool)
992 {
993 std::unique_lock<std::shared_mutex> writeLock(threadPoolLock_);
994 threadPool_ = threadPool;
995 LOGD("[RuntimeContext] Set thread pool finished");
996 }
997
GetThreadPool() const998 std::shared_ptr<IThreadPool> RuntimeContextImpl::GetThreadPool() const
999 {
1000 std::shared_lock<std::shared_mutex> readLock(threadPoolLock_);
1001 return threadPool_;
1002 }
1003
ScheduleTaskByThreadPool(const DistributedDB::TaskAction & task) const1004 int RuntimeContextImpl::ScheduleTaskByThreadPool(const DistributedDB::TaskAction &task) const
1005 {
1006 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
1007 if (threadPool == nullptr) {
1008 return -E_NOT_SUPPORT;
1009 }
1010 (void)threadPool->Execute(task);
1011 return E_OK;
1012 }
1013
SetTimerByThreadPool(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,bool allocTimerId,TimerId & timerId)1014 int RuntimeContextImpl::SetTimerByThreadPool(int milliSeconds, const TimerAction &action,
1015 const TimerFinalizer &finalizer, bool allocTimerId, TimerId &timerId)
1016 {
1017 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
1018 if (threadPool == nullptr) {
1019 return -E_NOT_SUPPORT;
1020 }
1021 int errCode = E_OK;
1022 if (allocTimerId) {
1023 errCode = AllocTimerId(nullptr, timerId);
1024 } else {
1025 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1026 if (taskIds_.find(timerId) == taskIds_.end()) {
1027 LOGD("[SetTimerByThreadPool] Timer has been remove");
1028 return -E_NO_SUCH_ENTRY;
1029 }
1030 }
1031 if (errCode != E_OK) {
1032 return errCode;
1033 }
1034 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1035 if (!allocTimerId && taskIds_.find(timerId) == taskIds_.end()) {
1036 LOGD("[SetTimerByThreadPool] Timer has been remove");
1037 return -E_NO_SUCH_ENTRY;
1038 }
1039 timerFinalizers_[timerId] = finalizer;
1040 Duration duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
1041 std::chrono::milliseconds(milliSeconds));
1042 TaskId taskId = threadPool->Execute([milliSeconds, action, timerId, this]() {
1043 ThreadPoolTimerAction(milliSeconds, action, timerId);
1044 }, duration);
1045 taskIds_[timerId] = taskId;
1046 return E_OK;
1047 }
1048
ModifyTimerByThreadPool(TimerId timerId,int milliSeconds)1049 int RuntimeContextImpl::ModifyTimerByThreadPool(TimerId timerId, int milliSeconds)
1050 {
1051 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
1052 if (threadPool == nullptr) {
1053 return -E_NOT_SUPPORT;
1054 }
1055 TaskId taskId;
1056 {
1057 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1058 if (taskIds_.find(timerId) == taskIds_.end()) {
1059 return -E_NO_SUCH_ENTRY;
1060 }
1061 taskId = taskIds_[timerId];
1062 }
1063 Duration duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
1064 std::chrono::milliseconds(milliSeconds));
1065 TaskId ret = threadPool->Reset(taskId, duration);
1066 if (ret != taskId) {
1067 return -E_NO_SUCH_ENTRY;
1068 }
1069 return E_OK;
1070 }
1071
RemoveTimerByThreadPool(TimerId timerId,bool wait)1072 void RuntimeContextImpl::RemoveTimerByThreadPool(TimerId timerId, bool wait)
1073 {
1074 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
1075 if (threadPool == nullptr) {
1076 return;
1077 }
1078 TaskId taskId;
1079 {
1080 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1081 if (taskIds_.find(timerId) == taskIds_.end()) {
1082 return;
1083 }
1084 taskId = taskIds_[timerId];
1085 taskIds_.erase(timerId);
1086 }
1087 bool removeBeforeExecute = threadPool->Remove(taskId, wait);
1088 TimerFinalizer timerFinalizer = nullptr;
1089 if (removeBeforeExecute) {
1090 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1091 timerFinalizer = timerFinalizers_[timerId];
1092 timerFinalizers_.erase(timerId);
1093 }
1094 if (timerFinalizer) {
1095 timerFinalizer();
1096 }
1097 }
1098
ThreadPoolTimerAction(int milliSeconds,const TimerAction & action,TimerId timerId)1099 void RuntimeContextImpl::ThreadPoolTimerAction(int milliSeconds, const TimerAction &action, TimerId timerId)
1100 {
1101 TimerFinalizer timerFinalizer = nullptr;
1102 bool timerExist = true;
1103 {
1104 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1105 if (timerFinalizers_.find(timerId) == timerFinalizers_.end()) {
1106 LOGD("[ThreadPoolTimerAction] Timer has been finalize");
1107 return;
1108 }
1109 timerFinalizer = timerFinalizers_[timerId];
1110 timerFinalizers_.erase(timerId);
1111 if (taskIds_.find(timerId) == taskIds_.end()) {
1112 LOGD("[ThreadPoolTimerAction] Timer has been removed");
1113 timerExist = false;
1114 }
1115 }
1116 if (timerExist && action(timerId) == E_OK) {
1117 // schedule task again
1118 int errCode = SetTimerByThreadPool(milliSeconds, action, timerFinalizer, false, timerId);
1119 if (errCode == E_OK) {
1120 return;
1121 }
1122 LOGW("[RuntimeContext] create timer failed %d", errCode);
1123 }
1124 if (timerFinalizer) {
1125 timerFinalizer();
1126 }
1127 {
1128 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
1129 taskIds_.erase(timerId);
1130 }
1131 std::lock_guard<std::mutex> autoLock(timersLock_);
1132 timers_.erase(timerId);
1133 }
1134
SetCloudTranslate(const std::shared_ptr<ICloudDataTranslate> & dataTranslate)1135 void RuntimeContextImpl::SetCloudTranslate(const std::shared_ptr<ICloudDataTranslate> &dataTranslate)
1136 {
1137 std::unique_lock<std::shared_mutex> autoLock(dataTranslateLock_);
1138 dataTranslate_ = dataTranslate;
1139 }
1140
AssetToBlob(const Asset & asset,std::vector<uint8_t> & blob)1141 int RuntimeContextImpl::AssetToBlob(const Asset &asset, std::vector<uint8_t> &blob)
1142 {
1143 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
1144 if (dataTranslate_ == nullptr) {
1145 return -E_NOT_INIT;
1146 }
1147 blob = dataTranslate_->AssetToBlob(asset);
1148 return E_OK;
1149 }
1150
AssetsToBlob(const Assets & assets,std::vector<uint8_t> & blob)1151 int RuntimeContextImpl::AssetsToBlob(const Assets &assets, std::vector<uint8_t> &blob)
1152 {
1153 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
1154 if (dataTranslate_ == nullptr) {
1155 return -E_NOT_INIT;
1156 }
1157 blob = dataTranslate_->AssetsToBlob(assets);
1158 return E_OK;
1159 }
1160
BlobToAsset(const std::vector<uint8_t> & blob,Asset & asset)1161 int RuntimeContextImpl::BlobToAsset(const std::vector<uint8_t> &blob, Asset &asset)
1162 {
1163 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
1164 if (dataTranslate_ == nullptr) {
1165 return -E_NOT_INIT;
1166 }
1167 asset = dataTranslate_->BlobToAsset(blob);
1168 return E_OK;
1169 }
1170
BlobToAssets(const std::vector<uint8_t> & blob,Assets & assets)1171 int RuntimeContextImpl::BlobToAssets(const std::vector<uint8_t> &blob, Assets &assets)
1172 {
1173 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
1174 if (dataTranslate_ == nullptr) {
1175 return -E_NOT_INIT;
1176 }
1177 assets = dataTranslate_->BlobToAssets(blob);
1178 DBCommon::RemoveDuplicateAssetsData(assets);
1179 return E_OK;
1180 }
1181
GetDeviceTimeInfo(const std::string & device) const1182 std::pair<int, DeviceTimeInfo> RuntimeContextImpl::GetDeviceTimeInfo(const std::string &device) const
1183 {
1184 std::pair<int, DeviceTimeInfo> res;
1185 auto &[errCode, info] = res;
1186 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1187 if (deviceTimeInfos_.find(device) == deviceTimeInfos_.end()) {
1188 errCode = -E_NOT_FOUND;
1189 } else {
1190 info = deviceTimeInfos_.at(device);
1191 errCode = E_OK;
1192 }
1193 return res;
1194 }
1195
SetDeviceTimeInfo(const std::string & device,const DeviceTimeInfo & deviceTimeInfo)1196 void RuntimeContextImpl::SetDeviceTimeInfo(const std::string &device, const DeviceTimeInfo &deviceTimeInfo)
1197 {
1198 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1199 deviceTimeInfos_[device] = deviceTimeInfo;
1200 }
1201
ClearDeviceTimeInfo(const std::string & device)1202 void RuntimeContextImpl::ClearDeviceTimeInfo(const std::string &device)
1203 {
1204 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1205 deviceTimeInfos_.erase(device);
1206 }
1207
ClearAllDeviceTimeInfo()1208 void RuntimeContextImpl::ClearAllDeviceTimeInfo()
1209 {
1210 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1211 deviceTimeInfos_.clear();
1212 }
1213
RecordAllTimeChange()1214 void RuntimeContextImpl::RecordAllTimeChange()
1215 {
1216 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1217 for (auto &item : dbTimeChange_) {
1218 item.second = true;
1219 }
1220 }
1221
ResetDBTimeChangeStatus(const std::vector<uint8_t> & dbId)1222 void RuntimeContextImpl::ResetDBTimeChangeStatus(const std::vector<uint8_t> &dbId)
1223 {
1224 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1225 dbTimeChange_[dbId] = false;
1226 }
1227
CheckDBTimeChange(const std::vector<uint8_t> & dbId)1228 bool RuntimeContextImpl::CheckDBTimeChange(const std::vector<uint8_t> &dbId)
1229 {
1230 std::lock_guard<std::mutex> autoLock(deviceTimeInfoLock_);
1231 return dbTimeChange_[dbId];
1232 }
1233
IsTimeTickMonitorValid() const1234 bool RuntimeContextImpl::IsTimeTickMonitorValid() const
1235 {
1236 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
1237 return timeTickMonitor_ != nullptr;
1238 }
1239
IsTimeChanged() const1240 bool RuntimeContextImpl::IsTimeChanged() const
1241 {
1242 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
1243 return timeTickMonitor_ != nullptr && timeTickMonitor_->IsTimeChanged();
1244 }
1245
SetTimeChanged(bool timeChange)1246 void RuntimeContextImpl::SetTimeChanged(bool timeChange)
1247 {
1248 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
1249 if (timeTickMonitor_ == nullptr) {
1250 timeTickMonitor_ = std::make_shared<TimeTickMonitor>();
1251 (void)timeTickMonitor_->StartTimeTickMonitor();
1252 LOGD("[RuntimeContext] TimeTickMonitor start success");
1253 }
1254 timeTickMonitor_->SetTimeChanged(timeChange);
1255 }
1256
IsBatchDownloadAssets() const1257 bool RuntimeContextImpl::IsBatchDownloadAssets() const
1258 {
1259 return isBatchDownloadAssets_;
1260 }
1261
SetBatchDownloadAssets(bool isBatchDownload)1262 void RuntimeContextImpl::SetBatchDownloadAssets(bool isBatchDownload)
1263 {
1264 isBatchDownloadAssets_ = isBatchDownload;
1265 }
1266
GetAssetsDownloadManager()1267 std::shared_ptr<AssetsDownloadManager> RuntimeContextImpl::GetAssetsDownloadManager()
1268 {
1269 std::lock_guard<std::mutex> autoLock(assetsDownloadManagerLock_);
1270 if (assetsDownloadManager_ != nullptr) {
1271 return assetsDownloadManager_;
1272 }
1273 assetsDownloadManager_ = std::make_shared<AssetsDownloadManager>();
1274 return assetsDownloadManager_;
1275 }
1276 } // namespace DistributedDB
1277