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