• 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 {
RuntimeContextImpl()25 RuntimeContextImpl::RuntimeContextImpl()
26     : adapter_(nullptr),
27       communicatorAggregator_(nullptr),
28       mainLoop_(nullptr),
29       currentTimerId_(0),
30       taskPool_(nullptr),
31       taskPoolReportsTimerId_(0),
32       timeTickMonitor_(nullptr),
33       systemApiAdapter_(nullptr),
34       lockStatusObserver_(nullptr),
35       currentSessionId_(1)
36 {
37 }
38 
39 // Destruct the object.
~RuntimeContextImpl()40 RuntimeContextImpl::~RuntimeContextImpl()
41 {
42     if (taskPoolReportsTimerId_ > 0) {
43         RemoveTimer(taskPoolReportsTimerId_, true);
44         taskPoolReportsTimerId_ = 0;
45     }
46     if (taskPool_ != nullptr) {
47         taskPool_->Stop();
48         taskPool_->Release(taskPool_);
49         taskPool_ = nullptr;
50     }
51     if (mainLoop_ != nullptr) {
52         mainLoop_->KillAndDecObjRef(mainLoop_);
53         mainLoop_ = nullptr;
54     }
55     SetCommunicatorAggregator(nullptr);
56     (void)SetCommunicatorAdapter(nullptr);
57     systemApiAdapter_ = nullptr;
58     delete lockStatusObserver_;
59     lockStatusObserver_ = nullptr;
60     userChangeMonitor_ = nullptr;
61 }
62 
63 // Set the label of this process.
SetProcessLabel(const std::string & label)64 void RuntimeContextImpl::SetProcessLabel(const std::string &label)
65 {
66     std::lock_guard<std::mutex> labelLock(labelMutex_);
67     processLabel_ = label;
68 }
69 
GetProcessLabel() const70 std::string RuntimeContextImpl::GetProcessLabel() const
71 {
72     std::lock_guard<std::mutex> labelLock(labelMutex_);
73     return processLabel_;
74 }
75 
SetCommunicatorAdapter(IAdapter * adapter)76 int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter)
77 {
78     {
79         std::lock_guard<std::mutex> autoLock(communicatorLock_);
80         if (adapter_ != nullptr) {
81             if (communicatorAggregator_ != nullptr) {
82                 return -E_NOT_SUPPORT;
83             }
84             delete adapter_;
85         }
86         adapter_ = adapter;
87     }
88     ICommunicatorAggregator *communicatorAggregator = nullptr;
89     GetCommunicatorAggregator(communicatorAggregator);
90     autoLaunch_.SetCommunicatorAggregator(communicatorAggregator);
91     return E_OK;
92 }
93 
GetCommunicatorAggregator(ICommunicatorAggregator * & outAggregator)94 int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator)
95 {
96     outAggregator = nullptr;
97     std::lock_guard<std::mutex> lock(communicatorLock_);
98     if (communicatorAggregator_ != nullptr) {
99         outAggregator = communicatorAggregator_;
100         return E_OK;
101     }
102 
103     if (adapter_ == nullptr) {
104         LOGE("Adapter has not set!");
105         return -E_NOT_INIT;
106     }
107 
108     communicatorAggregator_ = new (std::nothrow) CommunicatorAggregator;
109     if (communicatorAggregator_ == nullptr) {
110         LOGE("CommunicatorAggregator create failed, may be no available memory!");
111         return -E_OUT_OF_MEMORY;
112     }
113 
114     int errCode = communicatorAggregator_->Initialize(adapter_);
115     if (errCode != E_OK) {
116         LOGE("CommunicatorAggregator init failed, err = %d!", errCode);
117         RefObject::KillAndDecObjRef(communicatorAggregator_);
118         communicatorAggregator_ = nullptr;
119     }
120     outAggregator = communicatorAggregator_;
121     return errCode;
122 }
123 
SetCommunicatorAggregator(ICommunicatorAggregator * inAggregator)124 void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator)
125 {
126     std::lock_guard<std::mutex> autoLock(communicatorLock_);
127     if (communicatorAggregator_ != nullptr) {
128         autoLaunch_.SetCommunicatorAggregator(nullptr);
129         communicatorAggregator_->Finalize();
130         RefObject::KillAndDecObjRef(communicatorAggregator_);
131     }
132     communicatorAggregator_ = inAggregator;
133     autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_);
134 }
135 
GetLocalIdentity(std::string & outTarget)136 int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget)
137 {
138     std::lock_guard<std::mutex> autoLock(communicatorLock_);
139     if (communicatorAggregator_ != nullptr) {
140         return communicatorAggregator_->GetLocalIdentity(outTarget);
141     }
142     return -E_NOT_INIT;
143 }
144 
145 // Add and start a timer.
SetTimer(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,TimerId & timerId)146 int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action,
147     const TimerFinalizer &finalizer, TimerId &timerId)
148 {
149     timerId = 0;
150     if ((milliSeconds < 0) || !action) {
151         return -E_INVALID_ARGS;
152     }
153 
154     IEventLoop *loop = nullptr;
155     int errCode = PrepareLoop(loop);
156     if (errCode != E_OK) {
157         LOGE("SetTimer(), prepare loop failed.");
158         return errCode;
159     }
160 
161     IEvent *evTimer = IEvent::CreateEvent(milliSeconds, errCode);
162     if (evTimer == nullptr) {
163         loop->DecObjRef(loop);
164         loop = nullptr;
165         return errCode;
166     }
167 
168     errCode = AllocTimerId(evTimer, timerId);
169     if (errCode != E_OK) {
170         evTimer->DecObjRef(evTimer);
171         evTimer = nullptr;
172         loop->DecObjRef(loop);
173         loop = nullptr;
174         return errCode;
175     }
176 
177     evTimer->SetAction([this, timerId, action](EventsMask revents) -> int {
178             int errCodeInner = action(timerId);
179             if (errCodeInner != E_OK) {
180                 RemoveTimer(timerId, false);
181             }
182             return errCodeInner;
183         },
184         finalizer);
185 
186     errCode = loop->Add(evTimer);
187     if (errCode != E_OK) {
188         evTimer->IgnoreFinalizer();
189         RemoveTimer(timerId, false);
190         timerId = 0;
191     }
192 
193     loop->DecObjRef(loop);
194     loop = nullptr;
195     return errCode;
196 }
197 
198 // Modify the interval of the timer.
ModifyTimer(TimerId timerId,int milliSeconds)199 int RuntimeContextImpl::ModifyTimer(TimerId timerId, int milliSeconds)
200 {
201     if (milliSeconds < 0) {
202         return -E_INVALID_ARGS;
203     }
204 
205     std::lock_guard<std::mutex> autoLock(timersLock_);
206     auto iter = timers_.find(timerId);
207     if (iter == timers_.end()) {
208         return -E_NO_SUCH_ENTRY;
209     }
210 
211     IEvent *evTimer = iter->second;
212     if (evTimer == nullptr) {
213         return -E_INTERNAL_ERROR;
214     }
215     return evTimer->SetTimeout(milliSeconds);
216 }
217 
218 // Remove the timer.
RemoveTimer(TimerId timerId,bool wait)219 void RuntimeContextImpl::RemoveTimer(TimerId timerId, bool wait)
220 {
221     IEvent *evTimer = nullptr;
222     {
223         std::lock_guard<std::mutex> autoLock(timersLock_);
224         auto iter = timers_.find(timerId);
225         if (iter == timers_.end()) {
226             return;
227         }
228         evTimer = iter->second;
229         timers_.erase(iter);
230     }
231 
232     if (evTimer != nullptr) {
233         evTimer->Detach(wait);
234         evTimer->DecObjRef(evTimer);
235         evTimer = nullptr;
236     }
237 }
238 
239 // Task interfaces.
ScheduleTask(const TaskAction & task)240 int RuntimeContextImpl::ScheduleTask(const TaskAction &task)
241 {
242     std::lock_guard<std::mutex> autoLock(taskLock_);
243     int errCode = PrepareTaskPool();
244     if (errCode != E_OK) {
245         LOGE("Schedule task failed, fail to prepare task pool.");
246         return errCode;
247     }
248     return taskPool_->Schedule(task);
249 }
250 
ScheduleQueuedTask(const std::string & queueTag,const TaskAction & task)251 int RuntimeContextImpl::ScheduleQueuedTask(const std::string &queueTag,
252     const TaskAction &task)
253 {
254     std::lock_guard<std::mutex> autoLock(taskLock_);
255     int errCode = PrepareTaskPool();
256     if (errCode != E_OK) {
257         LOGE("Schedule queued task failed, fail to prepare task pool.");
258         return errCode;
259     }
260     return taskPool_->Schedule(queueTag, task);
261 }
262 
ShrinkMemory(const std::string & description)263 void RuntimeContextImpl::ShrinkMemory(const std::string &description)
264 {
265     std::lock_guard<std::mutex> autoLock(taskLock_);
266     if (taskPool_ != nullptr) {
267         taskPool_->ShrinkMemory(description);
268     }
269 }
270 
RegisterTimeChangedLister(const TimeChangedAction & action,int & errCode)271 NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const TimeChangedAction &action,
272     int &errCode)
273 {
274     std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
275     if (timeTickMonitor_ == nullptr) {
276         timeTickMonitor_ = std::make_unique<TimeTickMonitor>();
277         errCode = timeTickMonitor_->StartTimeTickMonitor();
278         if (errCode != E_OK) {
279             LOGE("TimeTickMonitor start failed!");
280             timeTickMonitor_ = nullptr;
281             return nullptr;
282         }
283         LOGD("[RuntimeContext] TimeTickMonitor start success");
284     }
285     return timeTickMonitor_->RegisterTimeChangedLister(action, errCode);
286 }
287 
PrepareLoop(IEventLoop * & loop)288 int RuntimeContextImpl::PrepareLoop(IEventLoop *&loop)
289 {
290     std::lock_guard<std::mutex> autoLock(loopLock_);
291     if (mainLoop_ != nullptr) {
292         loop = mainLoop_;
293         loop->IncObjRef(loop); // ref 1 returned to caller.
294         return E_OK;
295     }
296 
297     int errCode = E_OK;
298     loop = IEventLoop::CreateEventLoop(errCode);
299     if (loop == nullptr) {
300         return errCode;
301     }
302 
303     loop->IncObjRef(loop); // ref 1 owned by thread.
304     std::thread loopThread([loop]() {
305             loop->Run();
306             loop->DecObjRef(loop); // ref 1 dropped by thread.
307         });
308     loopThread.detach();
309 
310     mainLoop_ = loop;
311     loop->IncObjRef(loop); // ref 1 returned to caller.
312     return E_OK;
313 }
314 
PrepareTaskPool()315 int RuntimeContextImpl::PrepareTaskPool()
316 {
317     if (taskPool_ != nullptr) {
318         return E_OK;
319     }
320 
321     int errCode = E_OK;
322     TaskPool *taskPool = TaskPool::Create(MAX_TP_THREADS, MIN_TP_THREADS, errCode);
323     if (taskPool == nullptr) {
324         return errCode;
325     }
326 
327     errCode = taskPool->Start();
328     if (errCode != E_OK) {
329         taskPool->Release(taskPool);
330         return errCode;
331     }
332 
333     taskPool_ = taskPool;
334     return E_OK;
335 }
336 
AllocTimerId(IEvent * evTimer,TimerId & timerId)337 int RuntimeContextImpl::AllocTimerId(IEvent *evTimer, TimerId &timerId)
338 {
339     if (evTimer == nullptr) {
340         return -E_INVALID_ARGS;
341     }
342 
343     std::lock_guard<std::mutex> autoLock(timersLock_);
344     TimerId startId = currentTimerId_;
345     while (++currentTimerId_ != startId) {
346         if (currentTimerId_ == 0) {
347             continue;
348         }
349         if (timers_.find(currentTimerId_) == timers_.end()) {
350             timerId = currentTimerId_;
351             timers_[timerId] = evTimer;
352             return E_OK;
353         }
354     }
355     return -E_OUT_OF_IDS;
356 }
357 
SetPermissionCheckCallback(const PermissionCheckCallback & callback)358 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
359 {
360     std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
361     permissionCheckCallback_ = callback;
362     LOGI("SetPermissionCheckCallback ok");
363     return E_OK;
364 }
365 
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)366 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
367 {
368     std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
369     permissionCheckCallbackV2_ = callback;
370     LOGI("SetPermissionCheckCallback V2 ok");
371     return E_OK;
372 }
373 
SetPermissionCheckCallback(const PermissionCheckCallbackV3 & callback)374 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV3 &callback)
375 {
376     std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
377     permissionCheckCallbackV3_ = callback;
378     LOGI("SetPermissionCheckCallback V3 ok");
379     return E_OK;
380 }
381 
RunPermissionCheck(const PermissionCheckParam & param,uint8_t flag) const382 int RuntimeContextImpl::RunPermissionCheck(const PermissionCheckParam &param, uint8_t flag) const
383 {
384     bool checkResult = false;
385     std::shared_lock<std::shared_mutex> autoLock(permissionCheckCallbackMutex_);
386     if (permissionCheckCallbackV3_) {
387         checkResult = permissionCheckCallbackV3_(param, flag);
388     } else if (permissionCheckCallbackV2_) {
389         checkResult = permissionCheckCallbackV2_(param.userId, param.appId, param.storeId, param.deviceId, flag);
390     } else if (permissionCheckCallback_) {
391         checkResult = permissionCheckCallback_(param.userId, param.appId, param.storeId, flag);
392     } else {
393         return E_OK;
394     }
395     if (checkResult) {
396         return E_OK;
397     } else {
398         return -E_NOT_PERMIT;
399     }
400 }
401 
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)402 int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
403     const AutoLaunchOption &option)
404 {
405     return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option);
406 }
407 
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)408 int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier,
409     const std::string &dualTupleIdentifier, const std::string &userId)
410 {
411     return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId);
412 }
413 
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const414 void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier,
415     std::vector<std::string> &devices) const
416 {
417     return autoLaunch_.GetAutoLaunchSyncDevices(identifier, devices);
418 }
419 
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBType type)420 void RuntimeContextImpl::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBType type)
421 {
422     autoLaunch_.SetAutoLaunchRequestCallback(callback, type);
423 }
424 
RegisterLockStatusLister(const LockStatusNotifier & action,int & errCode)425 NotificationChain::Listener *RuntimeContextImpl::RegisterLockStatusLister(const LockStatusNotifier &action,
426     int &errCode)
427 {
428     std::lock(lockStatusLock_, systemApiAdapterLock_);
429     std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
430     std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
431     if (lockStatusObserver_ == nullptr) {
432         lockStatusObserver_ = new (std::nothrow) LockStatusObserver();
433         if (lockStatusObserver_ == nullptr) {
434             LOGE("lockStatusObserver_ is nullptr");
435             errCode = -E_OUT_OF_MEMORY;
436             return nullptr;
437         }
438     }
439 
440     if (!lockStatusObserver_->IsStarted()) {
441         errCode = lockStatusObserver_->Start();
442         if (errCode != E_OK) {
443             LOGE("lockStatusObserver start failed, err = %d", errCode);
444             delete lockStatusObserver_;
445             lockStatusObserver_ = nullptr;
446             return nullptr;
447         }
448 
449         if (systemApiAdapter_ != nullptr) {
450             auto callback = std::bind(&LockStatusObserver::OnStatusChange,
451                 lockStatusObserver_, std::placeholders::_1);
452             errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
453             if (errCode != OK) {
454                 LOGE("Register access control event change failed, err = %d", errCode);
455                 delete lockStatusObserver_;
456                 lockStatusObserver_ = nullptr;
457                 return nullptr;
458             }
459         }
460     }
461 
462     NotificationChain::Listener *listener = lockStatusObserver_->RegisterLockStatusChangedLister(action, errCode);
463     if ((listener == nullptr) || (errCode != E_OK)) {
464         LOGE("Register lock status changed listener failed, err = %d", errCode);
465         delete lockStatusObserver_;
466         lockStatusObserver_ = nullptr;
467         return nullptr;
468     }
469     return listener;
470 }
471 
IsAccessControlled() const472 bool RuntimeContextImpl::IsAccessControlled() const
473 {
474     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
475     if (systemApiAdapter_ == nullptr) {
476         return false;
477     }
478     return systemApiAdapter_->IsAccessControlled();
479 }
480 
SetSecurityOption(const std::string & filePath,const SecurityOption & option) const481 int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option) const
482 {
483     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
484     if (systemApiAdapter_ == nullptr || !OS::CheckPathExistence(filePath)) {
485         LOGI("Adapter is not set, or path not existed, not support set security option!");
486         return -E_NOT_SUPPORT;
487     }
488 
489     if (option == SecurityOption()) {
490         LOGD("SecurityOption is NOT_SET,Not need to set security option!");
491         return E_OK;
492     }
493 
494     std::string fileRealPath;
495     int errCode = OS::GetRealPath(filePath, fileRealPath);
496     if (errCode != E_OK) {
497         LOGE("Get real path failed when set security option!");
498         return errCode;
499     }
500 
501     errCode = systemApiAdapter_->SetSecurityOption(fileRealPath, option);
502     if (errCode != OK) {
503         if (errCode == NOT_SUPPORT) {
504             return -E_NOT_SUPPORT;
505         }
506         LOGE("SetSecurityOption failed, errCode = %d", errCode);
507         return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
508     }
509     return E_OK;
510 }
511 
GetSecurityOption(const std::string & filePath,SecurityOption & option) const512 int RuntimeContextImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
513 {
514     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
515     if (systemApiAdapter_ == nullptr) {
516         LOGI("Get Security option, but not set system api adapter!");
517         return -E_NOT_SUPPORT;
518     }
519     int errCode = systemApiAdapter_->GetSecurityOption(filePath, option);
520     if (errCode != OK) {
521         if (errCode == NOT_SUPPORT) {
522             return -E_NOT_SUPPORT;
523         }
524         LOGE("GetSecurityOption failed, errCode = %d", errCode);
525         return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
526     }
527 
528     LOGD("Get security option from system adapter [%d, %d]", option.securityLabel, option.securityFlag);
529     // This interface may return success but failed to obtain the flag and modified it to -1
530     if (option.securityFlag == INVALID_SEC_FLAG) {
531         // Currently ignoring the failure to obtain flags -1 other than S3, modify the flag to the default value
532         if (option.securityLabel == S3) {
533             LOGE("GetSecurityOption failed, SecurityOption is invalid [3, -1]!");
534             return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
535         }
536         option.securityFlag = 0; // 0 is default value
537     }
538     return E_OK;
539 }
540 
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const541 bool RuntimeContextImpl::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const
542 {
543     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
544     if (systemApiAdapter_ == nullptr) {
545         return true;
546     }
547     return systemApiAdapter_->CheckDeviceSecurityAbility(devId, option);
548 }
549 
SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)550 int RuntimeContextImpl::SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
551 {
552     std::lock(lockStatusLock_, systemApiAdapterLock_);
553     std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
554     std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
555     systemApiAdapter_ = adapter;
556     if (systemApiAdapter_ != nullptr && lockStatusObserver_ != nullptr && lockStatusObserver_->IsStarted()) {
557         auto callback = std::bind(&LockStatusObserver::OnStatusChange,
558             lockStatusObserver_, std::placeholders::_1);
559         int errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
560         if (errCode != OK) {
561             LOGE("Register access controlled event failed while setting adapter, err = %d", errCode);
562             delete lockStatusObserver_;
563             lockStatusObserver_ = nullptr;
564             return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
565         }
566     }
567     return E_OK;
568 }
569 
IsProcessSystemApiAdapterValid() const570 bool RuntimeContextImpl::IsProcessSystemApiAdapterValid() const
571 {
572     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
573     return (systemApiAdapter_ != nullptr);
574 }
575 
NotifyTimestampChanged(TimeOffset offset) const576 void RuntimeContextImpl::NotifyTimestampChanged(TimeOffset offset) const
577 {
578     std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
579     if (timeTickMonitor_ == nullptr) {
580         LOGD("NotifyTimestampChanged fail, timeTickMonitor_ is null.");
581         return;
582     }
583     timeTickMonitor_->NotifyTimeChange(offset);
584 }
585 
IsCommunicatorAggregatorValid() const586 bool RuntimeContextImpl::IsCommunicatorAggregatorValid() const
587 {
588     std::lock_guard<std::mutex> autoLock(communicatorLock_);
589     if (communicatorAggregator_ == nullptr && adapter_ == nullptr) {
590         return false;
591     }
592     return true;
593 }
594 
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)595 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifier &notifier)
596 {
597     std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
598     databaseStatusNotifyCallback_ = notifier;
599     LOGI("SetStoreStatusNotifier ok");
600 }
601 
NotifyDatabaseStatusChange(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,bool onlineStatus)602 void RuntimeContextImpl::NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId,
603     const std::string &storeId, const std::string &deviceId, bool onlineStatus)
604 {
605     ScheduleTask([this, userId, appId, storeId, deviceId, onlineStatus] {
606         std::shared_lock<std::shared_mutex> autoLock(databaseStatusCallbackMutex_);
607         if (databaseStatusNotifyCallback_) {
608             LOGI("start notify database status:%d", onlineStatus);
609             databaseStatusNotifyCallback_(userId, appId, storeId, deviceId, onlineStatus);
610         }
611     });
612 }
613 
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)614 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
615 {
616     std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
617     syncActivationCheckCallback_ = callback;
618     LOGI("SetSyncActivationCheckCallback ok");
619     return E_OK;
620 }
621 
SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 & callback)622 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 &callback)
623 {
624     std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
625     syncActivationCheckCallbackV2_ = callback;
626     LOGI("SetSyncActivationCheckCallbackV2 ok");
627     return E_OK;
628 }
629 
IsSyncerNeedActive(const DBProperties & properties) const630 bool RuntimeContextImpl::IsSyncerNeedActive(const DBProperties &properties) const
631 {
632     ActivationCheckParam param = {
633         properties.GetStringProp(DBProperties::USER_ID, ""),
634         properties.GetStringProp(DBProperties::APP_ID, ""),
635         properties.GetStringProp(DBProperties::STORE_ID, ""),
636         properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
637     };
638     std::shared_lock<std::shared_mutex> autoLock(syncActivationCheckCallbackMutex_);
639     if (syncActivationCheckCallbackV2_) {
640         return syncActivationCheckCallbackV2_(param);
641     } else if (syncActivationCheckCallback_) {
642         return syncActivationCheckCallback_(param.userId, param.appId, param.storeId);
643     }
644     return true;
645 }
646 
RegisterUserChangedListener(const UserChangedAction & action,EventType event)647 NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListener(const UserChangedAction &action,
648     EventType event)
649 {
650     int errCode;
651     std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
652     if (userChangeMonitor_ == nullptr) {
653         userChangeMonitor_ = std::make_unique<UserChangeMonitor>();
654         errCode = userChangeMonitor_->Start();
655         if (errCode != E_OK) {
656             LOGE("UserChangeMonitor start failed!");
657             userChangeMonitor_ = nullptr;
658             return nullptr;
659         }
660     }
661     NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListener(action, event, errCode);
662     if ((listener == nullptr) || (errCode != E_OK)) {
663         LOGE("Register user status changed listener failed, err = %d", errCode);
664         return nullptr;
665     }
666     return listener;
667 }
668 
NotifyUserChanged() const669 int RuntimeContextImpl::NotifyUserChanged() const
670 {
671     {
672         std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
673         if (userChangeMonitor_ == nullptr) {
674             LOGD("userChangeMonitor is null, all db is in normal sync mode");
675             return E_OK;
676         }
677     }
678     userChangeMonitor_->NotifyUserChanged();
679     return E_OK;
680 }
681 
GenerateSessionId()682 uint32_t RuntimeContextImpl::GenerateSessionId()
683 {
684     uint32_t sessionId = currentSessionId_++;
685     if (sessionId == 0) {
686         sessionId = currentSessionId_++;
687     }
688     return sessionId;
689 }
690 
DumpCommonInfo(int fd)691 void RuntimeContextImpl::DumpCommonInfo(int fd)
692 {
693     autoLaunch_.Dump(fd);
694 }
695 
CloseAutoLaunchConnection(DBType type,const DBProperties & properties)696 void RuntimeContextImpl::CloseAutoLaunchConnection(DBType type, const DBProperties &properties)
697 {
698     autoLaunch_.CloseConnection(type, properties);
699 }
700 
SetPermissionConditionCallback(const PermissionConditionCallback & callback)701 int RuntimeContextImpl::SetPermissionConditionCallback(const PermissionConditionCallback &callback)
702 {
703     std::unique_lock<std::shared_mutex> autoLock(permissionConditionLock_);
704     permissionConditionCallback_ = callback;
705     return E_OK;
706 }
707 
GetPermissionCheckParam(const DBProperties & properties)708 std::map<std::string, std::string> RuntimeContextImpl::GetPermissionCheckParam(const DBProperties &properties)
709 {
710     PermissionConditionParam param = {
711         properties.GetStringProp(DBProperties::USER_ID, ""),
712         properties.GetStringProp(DBProperties::APP_ID, ""),
713         properties.GetStringProp(DBProperties::STORE_ID, ""),
714         properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
715     };
716     std::shared_lock<std::shared_mutex> autoLock(permissionConditionLock_);
717     if (permissionConditionCallback_ == nullptr) {
718         return {};
719     }
720     return permissionConditionCallback_(param);
721 }
722 
StopTaskPool()723 void RuntimeContextImpl::StopTaskPool()
724 {
725     std::lock_guard<std::mutex> autoLock(taskLock_);
726     if (taskPool_ != nullptr) {
727         taskPool_->Stop();
728         TaskPool::Release(taskPool_);
729         taskPool_ = nullptr;
730     }
731 }
732 
StopTimeTickMonitorIfNeed()733 void RuntimeContextImpl::StopTimeTickMonitorIfNeed()
734 {
735     std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
736     if (timeTickMonitor_ == nullptr) {
737         return;
738     }
739     if (timeTickMonitor_->EmptyListener()) {
740         LOGD("[RuntimeContext] TimeTickMonitor exist because no listener");
741         timeTickMonitor_ = nullptr;
742     }
743 }
744 
SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback & callback)745 void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback)
746 {
747     std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
748     translateToDeviceIdCallback_ = callback;
749     deviceIdCache_.clear();
750 }
751 
TranslateDeviceId(const std::string & deviceId,const StoreInfo & info,std::string & newDeviceId)752 int RuntimeContextImpl::TranslateDeviceId(const std::string &deviceId,
753     const StoreInfo &info, std::string &newDeviceId)
754 {
755     const std::string id = DBCommon::GenerateIdentifierId(info.storeId, info.appId, info.userId);
756     std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
757     if (translateToDeviceIdCallback_ == nullptr) {
758         return -E_NOT_SUPPORT;
759     }
760     if (deviceIdCache_.find(deviceId) == deviceIdCache_.end() ||
761         deviceIdCache_[deviceId].find(id) == deviceIdCache_[deviceId].end()) {
762         deviceIdCache_[deviceId][id] = translateToDeviceIdCallback_(deviceId, info);
763     }
764     newDeviceId = deviceIdCache_[deviceId][id];
765     return E_OK;
766 }
767 
ExistTranslateDevIdCallback() const768 bool RuntimeContextImpl::ExistTranslateDevIdCallback() const
769 {
770     std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
771     return translateToDeviceIdCallback_ != nullptr;
772 }
773 } // namespace DistributedDB
774