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