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