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