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