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 ¶m, 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 ¬ifier)
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