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_->Stop();
53 mainLoop_->KillAndDecObjRef(mainLoop_);
54 mainLoop_ = nullptr;
55 }
56 SetCommunicatorAggregator(nullptr);
57 (void)SetCommunicatorAdapter(nullptr);
58 systemApiAdapter_ = nullptr;
59 delete lockStatusObserver_;
60 lockStatusObserver_ = nullptr;
61 userChangeMonitor_ = nullptr;
62 SetThreadPool(nullptr);
63 }
64
65 // Set the label of this process.
SetProcessLabel(const std::string & label)66 void RuntimeContextImpl::SetProcessLabel(const std::string &label)
67 {
68 std::lock_guard<std::mutex> labelLock(labelMutex_);
69 processLabel_ = label;
70 }
71
GetProcessLabel() const72 std::string RuntimeContextImpl::GetProcessLabel() const
73 {
74 std::lock_guard<std::mutex> labelLock(labelMutex_);
75 return processLabel_;
76 }
77
SetCommunicatorAdapter(IAdapter * adapter)78 int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter)
79 {
80 {
81 std::lock_guard<std::mutex> autoLock(communicatorLock_);
82 if (adapter_ != nullptr) {
83 if (communicatorAggregator_ != nullptr) {
84 return -E_NOT_SUPPORT;
85 }
86 delete adapter_;
87 }
88 adapter_ = adapter;
89 }
90 ICommunicatorAggregator *communicatorAggregator = nullptr;
91 GetCommunicatorAggregator(communicatorAggregator);
92 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator);
93 return E_OK;
94 }
95
GetCommunicatorAggregator(ICommunicatorAggregator * & outAggregator)96 int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator)
97 {
98 outAggregator = nullptr;
99 std::lock_guard<std::mutex> lock(communicatorLock_);
100 if (communicatorAggregator_ != nullptr) {
101 outAggregator = communicatorAggregator_;
102 return E_OK;
103 }
104
105 if (adapter_ == nullptr) {
106 LOGE("Adapter has not set!");
107 return -E_NOT_INIT;
108 }
109
110 communicatorAggregator_ = new (std::nothrow) CommunicatorAggregator;
111 if (communicatorAggregator_ == nullptr) {
112 LOGE("CommunicatorAggregator create failed, may be no available memory!");
113 return -E_OUT_OF_MEMORY;
114 }
115
116 int errCode = communicatorAggregator_->Initialize(adapter_);
117 if (errCode != E_OK) {
118 LOGE("CommunicatorAggregator init failed, err = %d!", errCode);
119 RefObject::KillAndDecObjRef(communicatorAggregator_);
120 communicatorAggregator_ = nullptr;
121 }
122 outAggregator = communicatorAggregator_;
123 return errCode;
124 }
125
SetCommunicatorAggregator(ICommunicatorAggregator * inAggregator)126 void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator)
127 {
128 std::lock_guard<std::mutex> autoLock(communicatorLock_);
129 if (communicatorAggregator_ != nullptr) {
130 autoLaunch_.SetCommunicatorAggregator(nullptr);
131 communicatorAggregator_->Finalize();
132 RefObject::KillAndDecObjRef(communicatorAggregator_);
133 }
134 communicatorAggregator_ = inAggregator;
135 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_);
136 }
137
GetLocalIdentity(std::string & outTarget)138 int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget)
139 {
140 std::lock_guard<std::mutex> autoLock(communicatorLock_);
141 if (communicatorAggregator_ != nullptr) {
142 return communicatorAggregator_->GetLocalIdentity(outTarget);
143 }
144 return -E_NOT_INIT;
145 }
146
147 // Add and start a timer.
SetTimer(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,TimerId & timerId)148 int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action,
149 const TimerFinalizer &finalizer, TimerId &timerId)
150 {
151 timerId = 0;
152 if ((milliSeconds < 0) || !action) {
153 return -E_INVALID_ARGS;
154 }
155 int errCode = SetTimerByThreadPool(milliSeconds, action, finalizer, true, timerId);
156 if (errCode != -E_NOT_SUPPORT) {
157 return errCode;
158 }
159 IEventLoop *loop = nullptr;
160 errCode = PrepareLoop(loop);
161 if (errCode != E_OK) {
162 LOGE("SetTimer(), prepare loop failed.");
163 return errCode;
164 }
165
166 IEvent *evTimer = IEvent::CreateEvent(milliSeconds, errCode);
167 if (evTimer == nullptr) {
168 loop->DecObjRef(loop);
169 loop = nullptr;
170 return errCode;
171 }
172
173 errCode = AllocTimerId(evTimer, timerId);
174 if (errCode != E_OK) {
175 evTimer->DecObjRef(evTimer);
176 evTimer = nullptr;
177 loop->DecObjRef(loop);
178 loop = nullptr;
179 return errCode;
180 }
181
182 evTimer->SetAction([this, timerId, action](EventsMask revents) -> int {
183 int errCodeInner = action(timerId);
184 if (errCodeInner != E_OK) {
185 RemoveTimer(timerId, false);
186 }
187 return errCodeInner;
188 },
189 finalizer);
190
191 errCode = loop->Add(evTimer);
192 if (errCode != E_OK) {
193 evTimer->IgnoreFinalizer();
194 RemoveTimer(timerId, false);
195 timerId = 0;
196 }
197
198 loop->DecObjRef(loop);
199 loop = nullptr;
200 return errCode;
201 }
202
203 // Modify the interval of the timer.
ModifyTimer(TimerId timerId,int milliSeconds)204 int RuntimeContextImpl::ModifyTimer(TimerId timerId, int milliSeconds)
205 {
206 if (milliSeconds < 0) {
207 return -E_INVALID_ARGS;
208 }
209 int errCode = ModifyTimerByThreadPool(timerId, milliSeconds);
210 if (errCode != -E_NOT_SUPPORT) {
211 return errCode;
212 }
213 std::lock_guard<std::mutex> autoLock(timersLock_);
214 auto iter = timers_.find(timerId);
215 if (iter == timers_.end()) {
216 return -E_NO_SUCH_ENTRY;
217 }
218
219 IEvent *evTimer = iter->second;
220 if (evTimer == nullptr) {
221 return -E_INTERNAL_ERROR;
222 }
223 return evTimer->SetTimeout(milliSeconds);
224 }
225
226 // Remove the timer.
RemoveTimer(TimerId timerId,bool wait)227 void RuntimeContextImpl::RemoveTimer(TimerId timerId, bool wait)
228 {
229 RemoveTimerByThreadPool(timerId, wait);
230 IEvent *evTimer = nullptr;
231 {
232 std::lock_guard<std::mutex> autoLock(timersLock_);
233 auto iter = timers_.find(timerId);
234 if (iter == timers_.end()) {
235 return;
236 }
237 evTimer = iter->second;
238 timers_.erase(iter);
239 }
240
241 if (evTimer != nullptr) {
242 evTimer->Detach(wait);
243 evTimer->DecObjRef(evTimer);
244 evTimer = nullptr;
245 }
246 }
247
248 // Task interfaces.
ScheduleTask(const TaskAction & task)249 int RuntimeContextImpl::ScheduleTask(const TaskAction &task)
250 {
251 if (ScheduleTaskByThreadPool(task) == E_OK) {
252 return E_OK;
253 }
254 std::lock_guard<std::mutex> autoLock(taskLock_);
255 int errCode = PrepareTaskPool();
256 if (errCode != E_OK) {
257 LOGE("Schedule task failed, fail to prepare task pool.");
258 return errCode;
259 }
260 return taskPool_->Schedule(task);
261 }
262
ScheduleQueuedTask(const std::string & queueTag,const TaskAction & task)263 int RuntimeContextImpl::ScheduleQueuedTask(const std::string &queueTag,
264 const TaskAction &task)
265 {
266 if (ScheduleTaskByThreadPool(task) == E_OK) {
267 return E_OK;
268 }
269 std::lock_guard<std::mutex> autoLock(taskLock_);
270 int errCode = PrepareTaskPool();
271 if (errCode != E_OK) {
272 LOGE("Schedule queued task failed, fail to prepare task pool.");
273 return errCode;
274 }
275 return taskPool_->Schedule(queueTag, task);
276 }
277
ShrinkMemory(const std::string & description)278 void RuntimeContextImpl::ShrinkMemory(const std::string &description)
279 {
280 std::lock_guard<std::mutex> autoLock(taskLock_);
281 if (taskPool_ != nullptr) {
282 taskPool_->ShrinkMemory(description);
283 }
284 }
285
RegisterTimeChangedLister(const TimeChangedAction & action,const TimeFinalizeAction & finalize,int & errCode)286 NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const TimeChangedAction &action,
287 const TimeFinalizeAction &finalize, int &errCode)
288 {
289 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
290 if (timeTickMonitor_ == nullptr) {
291 timeTickMonitor_ = std::make_unique<TimeTickMonitor>();
292 errCode = timeTickMonitor_->StartTimeTickMonitor();
293 if (errCode != E_OK) {
294 LOGE("TimeTickMonitor start failed!");
295 timeTickMonitor_ = nullptr;
296 return nullptr;
297 }
298 LOGD("[RuntimeContext] TimeTickMonitor start success");
299 }
300 LOGD("[RuntimeContext] call RegisterTimeChangedLister");
301 return timeTickMonitor_->RegisterTimeChangedLister(action, finalize, errCode);
302 }
303
PrepareLoop(IEventLoop * & loop)304 int RuntimeContextImpl::PrepareLoop(IEventLoop *&loop)
305 {
306 std::lock_guard<std::mutex> autoLock(loopLock_);
307 if (mainLoop_ != nullptr) {
308 loop = mainLoop_;
309 loop->IncObjRef(loop); // ref 1 returned to caller.
310 return E_OK;
311 }
312
313 int errCode = E_OK;
314 loop = IEventLoop::CreateEventLoop(errCode);
315 if (loop == nullptr) {
316 return errCode;
317 }
318
319 loop->IncObjRef(loop); // ref 1 owned by thread.
320 std::thread loopThread([loop]() {
321 loop->Run();
322 loop->DecObjRef(loop); // ref 1 dropped by thread.
323 });
324 loopThread.detach();
325
326 mainLoop_ = loop;
327 loop->IncObjRef(loop); // ref 1 returned to caller.
328 return E_OK;
329 }
330
PrepareTaskPool()331 int RuntimeContextImpl::PrepareTaskPool()
332 {
333 if (taskPool_ != nullptr) {
334 return E_OK;
335 }
336
337 int errCode = E_OK;
338 TaskPool *taskPool = TaskPool::Create(MAX_TP_THREADS, MIN_TP_THREADS, errCode);
339 if (taskPool == nullptr) {
340 return errCode;
341 }
342
343 errCode = taskPool->Start();
344 if (errCode != E_OK) {
345 taskPool->Release(taskPool);
346 return errCode;
347 }
348
349 taskPool_ = taskPool;
350 return E_OK;
351 }
352
AllocTimerId(IEvent * evTimer,TimerId & timerId)353 int RuntimeContextImpl::AllocTimerId(IEvent *evTimer, TimerId &timerId)
354 {
355 std::lock_guard<std::mutex> autoLock(timersLock_);
356 TimerId startId = currentTimerId_;
357 while (++currentTimerId_ != startId) {
358 if (currentTimerId_ == 0) {
359 continue;
360 }
361 if (timers_.find(currentTimerId_) == timers_.end()) {
362 timerId = currentTimerId_;
363 timers_[timerId] = evTimer;
364 return E_OK;
365 }
366 }
367 return -E_OUT_OF_IDS;
368 }
369
SetPermissionCheckCallback(const PermissionCheckCallback & callback)370 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
371 {
372 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
373 permissionCheckCallback_ = callback;
374 LOGI("SetPermissionCheckCallback ok");
375 return E_OK;
376 }
377
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)378 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
379 {
380 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
381 permissionCheckCallbackV2_ = callback;
382 LOGI("SetPermissionCheckCallback V2 ok");
383 return E_OK;
384 }
385
SetPermissionCheckCallback(const PermissionCheckCallbackV3 & callback)386 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV3 &callback)
387 {
388 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
389 permissionCheckCallbackV3_ = callback;
390 LOGI("SetPermissionCheckCallback V3 ok");
391 return E_OK;
392 }
393
RunPermissionCheck(const PermissionCheckParam & param,uint8_t flag) const394 int RuntimeContextImpl::RunPermissionCheck(const PermissionCheckParam ¶m, uint8_t flag) const
395 {
396 bool checkResult = false;
397 std::shared_lock<std::shared_mutex> autoLock(permissionCheckCallbackMutex_);
398 if (permissionCheckCallbackV3_) {
399 checkResult = permissionCheckCallbackV3_(param, flag);
400 } else if (permissionCheckCallbackV2_) {
401 checkResult = permissionCheckCallbackV2_(param.userId, param.appId, param.storeId, param.deviceId, flag);
402 } else if (permissionCheckCallback_) {
403 checkResult = permissionCheckCallback_(param.userId, param.appId, param.storeId, flag);
404 } else {
405 return E_OK;
406 }
407 if (checkResult) {
408 return E_OK;
409 }
410 return -E_NOT_PERMIT;
411 }
412
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)413 int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
414 const AutoLaunchOption &option)
415 {
416 return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option);
417 }
418
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)419 int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier,
420 const std::string &dualTupleIdentifier, const std::string &userId)
421 {
422 return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId);
423 }
424
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const425 void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier,
426 std::vector<std::string> &devices) const
427 {
428 return autoLaunch_.GetAutoLaunchSyncDevices(identifier, devices);
429 }
430
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBTypeInner type)431 void RuntimeContextImpl::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBTypeInner type)
432 {
433 autoLaunch_.SetAutoLaunchRequestCallback(callback, type);
434 }
435
RegisterLockStatusLister(const LockStatusNotifier & action,int & errCode)436 NotificationChain::Listener *RuntimeContextImpl::RegisterLockStatusLister(const LockStatusNotifier &action,
437 int &errCode)
438 {
439 std::lock(lockStatusLock_, systemApiAdapterLock_);
440 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
441 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
442 if (lockStatusObserver_ == nullptr) {
443 lockStatusObserver_ = new (std::nothrow) LockStatusObserver();
444 if (lockStatusObserver_ == nullptr) {
445 LOGE("lockStatusObserver_ is nullptr");
446 errCode = -E_OUT_OF_MEMORY;
447 return nullptr;
448 }
449 }
450
451 if (!lockStatusObserver_->IsStarted()) {
452 errCode = lockStatusObserver_->Start();
453 if (errCode != E_OK) {
454 LOGE("lockStatusObserver start failed, err = %d", errCode);
455 delete lockStatusObserver_;
456 lockStatusObserver_ = nullptr;
457 return nullptr;
458 }
459
460 if (systemApiAdapter_ != nullptr) {
461 auto callback = std::bind(&LockStatusObserver::OnStatusChange,
462 lockStatusObserver_, std::placeholders::_1);
463 errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
464 if (errCode != OK) {
465 LOGE("Register access control event change failed, err = %d", errCode);
466 delete lockStatusObserver_;
467 lockStatusObserver_ = nullptr;
468 return nullptr;
469 }
470 }
471 }
472
473 NotificationChain::Listener *listener = lockStatusObserver_->RegisterLockStatusChangedLister(action, errCode);
474 if ((listener == nullptr) || (errCode != E_OK)) {
475 LOGE("Register lock status changed listener failed, err = %d", errCode);
476 delete lockStatusObserver_;
477 lockStatusObserver_ = nullptr;
478 return nullptr;
479 }
480 return listener;
481 }
482
IsAccessControlled() const483 bool RuntimeContextImpl::IsAccessControlled() const
484 {
485 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
486 if (systemApiAdapter_ == nullptr) {
487 return false;
488 }
489 return systemApiAdapter_->IsAccessControlled();
490 }
491
SetSecurityOption(const std::string & filePath,const SecurityOption & option) const492 int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option) const
493 {
494 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
495 if (systemApiAdapter_ == nullptr || !OS::CheckPathExistence(filePath)) {
496 LOGI("Adapter is not set, or path not existed, not support set security option!");
497 return -E_NOT_SUPPORT;
498 }
499
500 if (option == SecurityOption()) {
501 LOGD("SecurityOption is NOT_SET,Not need to set security option!");
502 return E_OK;
503 }
504
505 std::string fileRealPath;
506 int errCode = OS::GetRealPath(filePath, fileRealPath);
507 if (errCode != E_OK) {
508 LOGE("Get real path failed when set security option!");
509 return errCode;
510 }
511
512 errCode = systemApiAdapter_->SetSecurityOption(fileRealPath, option);
513 if (errCode != OK) {
514 if (errCode == NOT_SUPPORT) {
515 return -E_NOT_SUPPORT;
516 }
517 LOGE("SetSecurityOption failed, errCode = %d", errCode);
518 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
519 }
520 return E_OK;
521 }
522
GetSecurityOption(const std::string & filePath,SecurityOption & option) const523 int RuntimeContextImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
524 {
525 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
526 if (systemApiAdapter_ == nullptr) {
527 LOGI("Get Security option, but not set system api adapter!");
528 return -E_NOT_SUPPORT;
529 }
530 int errCode = systemApiAdapter_->GetSecurityOption(filePath, option);
531 if (errCode != OK) {
532 if (errCode == NOT_SUPPORT) {
533 return -E_NOT_SUPPORT;
534 }
535 LOGE("GetSecurityOption failed, errCode = %d", errCode);
536 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
537 }
538
539 LOGD("Get security option from system adapter [%d, %d]", option.securityLabel, option.securityFlag);
540 // This interface may return success but failed to obtain the flag and modified it to -1
541 if (option.securityFlag == INVALID_SEC_FLAG) {
542 // Currently ignoring the failure to obtain flags -1 other than S3, modify the flag to the default value
543 if (option.securityLabel == S3) {
544 LOGE("GetSecurityOption failed, SecurityOption is invalid [3, -1]!");
545 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
546 }
547 option.securityFlag = 0; // 0 is default value
548 }
549 return E_OK;
550 }
551
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const552 bool RuntimeContextImpl::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const
553 {
554 std::shared_ptr<IProcessSystemApiAdapter> tempSystemApiAdapter = nullptr;
555 {
556 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
557 if (systemApiAdapter_ == nullptr) {
558 LOGI("[CheckDeviceSecurityAbility] security not set");
559 return true;
560 }
561 tempSystemApiAdapter = systemApiAdapter_;
562 }
563
564 return tempSystemApiAdapter->CheckDeviceSecurityAbility(devId, option);
565 }
566
SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)567 int RuntimeContextImpl::SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
568 {
569 std::lock(lockStatusLock_, systemApiAdapterLock_);
570 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
571 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
572 systemApiAdapter_ = adapter;
573 if (systemApiAdapter_ != nullptr && lockStatusObserver_ != nullptr && lockStatusObserver_->IsStarted()) {
574 auto callback = std::bind(&LockStatusObserver::OnStatusChange,
575 lockStatusObserver_, std::placeholders::_1);
576 int errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
577 if (errCode != OK) {
578 LOGE("Register access controlled event failed while setting adapter, err = %d", errCode);
579 delete lockStatusObserver_;
580 lockStatusObserver_ = nullptr;
581 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
582 }
583 }
584 return E_OK;
585 }
586
IsProcessSystemApiAdapterValid() const587 bool RuntimeContextImpl::IsProcessSystemApiAdapterValid() const
588 {
589 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
590 return (systemApiAdapter_ != nullptr);
591 }
592
NotifyTimestampChanged(TimeOffset offset) const593 void RuntimeContextImpl::NotifyTimestampChanged(TimeOffset offset) const
594 {
595 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
596 if (timeTickMonitor_ == nullptr) {
597 LOGD("NotifyTimestampChanged fail, timeTickMonitor_ is null.");
598 return;
599 }
600 timeTickMonitor_->NotifyTimeChange(offset);
601 }
602
IsCommunicatorAggregatorValid() const603 bool RuntimeContextImpl::IsCommunicatorAggregatorValid() const
604 {
605 std::lock_guard<std::mutex> autoLock(communicatorLock_);
606 if (communicatorAggregator_ == nullptr && adapter_ == nullptr) {
607 return false;
608 }
609 return true;
610 }
611
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)612 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifier ¬ifier)
613 {
614 std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
615 databaseStatusNotifyCallback_ = notifier;
616 LOGI("SetStoreStatusNotifier ok");
617 }
618
NotifyDatabaseStatusChange(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,bool onlineStatus)619 void RuntimeContextImpl::NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId,
620 const std::string &storeId, const std::string &deviceId, bool onlineStatus)
621 {
622 ScheduleTask([this, userId, appId, storeId, deviceId, onlineStatus] {
623 std::shared_lock<std::shared_mutex> autoLock(databaseStatusCallbackMutex_);
624 if (databaseStatusNotifyCallback_) {
625 LOGI("start notify database status:%d", onlineStatus);
626 databaseStatusNotifyCallback_(userId, appId, storeId, deviceId, onlineStatus);
627 }
628 });
629 }
630
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)631 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
632 {
633 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
634 syncActivationCheckCallback_ = callback;
635 LOGI("SetSyncActivationCheckCallback ok");
636 return E_OK;
637 }
638
SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 & callback)639 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 &callback)
640 {
641 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
642 syncActivationCheckCallbackV2_ = callback;
643 LOGI("SetSyncActivationCheckCallbackV2 ok");
644 return E_OK;
645 }
646
IsSyncerNeedActive(const DBProperties & properties) const647 bool RuntimeContextImpl::IsSyncerNeedActive(const DBProperties &properties) const
648 {
649 ActivationCheckParam param = {
650 properties.GetStringProp(DBProperties::USER_ID, ""),
651 properties.GetStringProp(DBProperties::APP_ID, ""),
652 properties.GetStringProp(DBProperties::STORE_ID, ""),
653 properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
654 };
655 std::shared_lock<std::shared_mutex> autoLock(syncActivationCheckCallbackMutex_);
656 if (syncActivationCheckCallbackV2_) {
657 return syncActivationCheckCallbackV2_(param);
658 } else if (syncActivationCheckCallback_) {
659 return syncActivationCheckCallback_(param.userId, param.appId, param.storeId);
660 }
661 return true;
662 }
663
RegisterUserChangedListener(const UserChangedAction & action,EventType event)664 NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListener(const UserChangedAction &action,
665 EventType event)
666 {
667 int errCode;
668 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
669 if (userChangeMonitor_ == nullptr) {
670 userChangeMonitor_ = std::make_unique<UserChangeMonitor>();
671 errCode = userChangeMonitor_->Start();
672 if (errCode != E_OK) {
673 LOGE("UserChangeMonitor start failed!");
674 userChangeMonitor_ = nullptr;
675 return nullptr;
676 }
677 }
678 NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListener(action, event, errCode);
679 if ((listener == nullptr) || (errCode != E_OK)) {
680 LOGE("Register user status changed listener failed, err = %d", errCode);
681 return nullptr;
682 }
683 return listener;
684 }
685
NotifyUserChanged() const686 int RuntimeContextImpl::NotifyUserChanged() const
687 {
688 {
689 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
690 if (userChangeMonitor_ == nullptr) {
691 LOGD("userChangeMonitor is null, all db is in normal sync mode");
692 return E_OK;
693 }
694 }
695 userChangeMonitor_->NotifyUserChanged();
696 return E_OK;
697 }
698
GenerateSessionId()699 uint32_t RuntimeContextImpl::GenerateSessionId()
700 {
701 uint32_t sessionId = currentSessionId_++;
702 if (sessionId == 0) {
703 sessionId = currentSessionId_++;
704 }
705 return sessionId;
706 }
707
DumpCommonInfo(int fd)708 void RuntimeContextImpl::DumpCommonInfo(int fd)
709 {
710 autoLaunch_.Dump(fd);
711 }
712
CloseAutoLaunchConnection(DBTypeInner type,const DBProperties & properties)713 void RuntimeContextImpl::CloseAutoLaunchConnection(DBTypeInner type, const DBProperties &properties)
714 {
715 autoLaunch_.CloseConnection(type, properties);
716 }
717
SetPermissionConditionCallback(const PermissionConditionCallback & callback)718 int RuntimeContextImpl::SetPermissionConditionCallback(const PermissionConditionCallback &callback)
719 {
720 std::unique_lock<std::shared_mutex> autoLock(permissionConditionLock_);
721 permissionConditionCallback_ = callback;
722 return E_OK;
723 }
724
GetPermissionCheckParam(const DBProperties & properties)725 std::map<std::string, std::string> RuntimeContextImpl::GetPermissionCheckParam(const DBProperties &properties)
726 {
727 PermissionConditionParam param = {
728 properties.GetStringProp(DBProperties::USER_ID, ""),
729 properties.GetStringProp(DBProperties::APP_ID, ""),
730 properties.GetStringProp(DBProperties::STORE_ID, ""),
731 properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
732 };
733 std::shared_lock<std::shared_mutex> autoLock(permissionConditionLock_);
734 if (permissionConditionCallback_ == nullptr) {
735 return {};
736 }
737 return permissionConditionCallback_(param);
738 }
739
StopTaskPool()740 void RuntimeContextImpl::StopTaskPool()
741 {
742 std::lock_guard<std::mutex> autoLock(taskLock_);
743 if (taskPool_ != nullptr) {
744 taskPool_->Stop();
745 TaskPool::Release(taskPool_);
746 taskPool_ = nullptr;
747 }
748 }
749
StopTimeTickMonitorIfNeed()750 void RuntimeContextImpl::StopTimeTickMonitorIfNeed()
751 {
752 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
753 if (timeTickMonitor_ == nullptr) {
754 return;
755 }
756 if (timeTickMonitor_->EmptyListener()) {
757 LOGD("[RuntimeContext] TimeTickMonitor exist because no listener");
758 timeTickMonitor_ = nullptr;
759 }
760 LOGD("[RuntimeContext] TimeTickMonitor can not stop because listener is not empty");
761 }
762
SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback & callback)763 void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback)
764 {
765 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
766 translateToDeviceIdCallback_ = callback;
767 deviceIdCache_.clear();
768 }
769
TranslateDeviceId(const std::string & deviceId,const StoreInfo & info,std::string & newDeviceId)770 int RuntimeContextImpl::TranslateDeviceId(const std::string &deviceId,
771 const StoreInfo &info, std::string &newDeviceId)
772 {
773 const std::string id = DBCommon::GenerateIdentifierId(info.storeId, info.appId, info.userId);
774 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
775 if (translateToDeviceIdCallback_ == nullptr) {
776 return -E_NOT_SUPPORT;
777 }
778 if (deviceIdCache_.find(deviceId) == deviceIdCache_.end() ||
779 deviceIdCache_[deviceId].find(id) == deviceIdCache_[deviceId].end()) {
780 deviceIdCache_[deviceId][id] = translateToDeviceIdCallback_(deviceId, info);
781 }
782 newDeviceId = deviceIdCache_[deviceId][id];
783 return E_OK;
784 }
785
ExistTranslateDevIdCallback() const786 bool RuntimeContextImpl::ExistTranslateDevIdCallback() const
787 {
788 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
789 return translateToDeviceIdCallback_ != nullptr;
790 }
791
SetThreadPool(const std::shared_ptr<IThreadPool> & threadPool)792 void RuntimeContextImpl::SetThreadPool(const std::shared_ptr<IThreadPool> &threadPool)
793 {
794 std::unique_lock<std::shared_mutex> writeLock(threadPoolLock_);
795 threadPool_ = threadPool;
796 LOGD("[RuntimeContext] Set thread pool finished");
797 }
798
GetThreadPool() const799 std::shared_ptr<IThreadPool> RuntimeContextImpl::GetThreadPool() const
800 {
801 std::shared_lock<std::shared_mutex> readLock(threadPoolLock_);
802 return threadPool_;
803 }
804
ScheduleTaskByThreadPool(const DistributedDB::TaskAction & task) const805 int RuntimeContextImpl::ScheduleTaskByThreadPool(const DistributedDB::TaskAction &task) const
806 {
807 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
808 if (threadPool == nullptr) {
809 return -E_NOT_SUPPORT;
810 }
811 (void)threadPool->Execute(task);
812 return E_OK;
813 }
814
SetTimerByThreadPool(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,bool allocTimerId,TimerId & timerId)815 int RuntimeContextImpl::SetTimerByThreadPool(int milliSeconds, const TimerAction &action,
816 const TimerFinalizer &finalizer, bool allocTimerId, TimerId &timerId)
817 {
818 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
819 if (threadPool == nullptr) {
820 return -E_NOT_SUPPORT;
821 }
822 int errCode = E_OK;
823 if (allocTimerId) {
824 errCode = AllocTimerId(nullptr, timerId);
825 } else {
826 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
827 if (taskIds_.find(timerId) == taskIds_.end()) {
828 LOGD("[SetTimerByThreadPool] Timer has been remove");
829 return -E_NO_SUCH_ENTRY;
830 }
831 }
832 if (errCode != E_OK) {
833 return errCode;
834 }
835 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
836 if (!allocTimerId && taskIds_.find(timerId) == taskIds_.end()) {
837 LOGD("[SetTimerByThreadPool] Timer has been remove");
838 return -E_NO_SUCH_ENTRY;
839 }
840 timerFinalizers_[timerId] = finalizer;
841 Duration duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
842 std::chrono::milliseconds(milliSeconds));
843 TaskId taskId = threadPool->Execute([milliSeconds, action, timerId, this]() {
844 ThreadPoolTimerAction(milliSeconds, action, timerId);
845 }, duration);
846 taskIds_[timerId] = taskId;
847 return E_OK;
848 }
849
ModifyTimerByThreadPool(TimerId timerId,int milliSeconds)850 int RuntimeContextImpl::ModifyTimerByThreadPool(TimerId timerId, int milliSeconds)
851 {
852 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
853 if (threadPool == nullptr) {
854 return -E_NOT_SUPPORT;
855 }
856 TaskId taskId;
857 {
858 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
859 if (taskIds_.find(timerId) == taskIds_.end()) {
860 return -E_NO_SUCH_ENTRY;
861 }
862 taskId = taskIds_[timerId];
863 }
864 Duration duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
865 std::chrono::milliseconds(milliSeconds));
866 TaskId ret = threadPool->Reset(taskId, duration);
867 if (ret != taskId) {
868 return -E_NO_SUCH_ENTRY;
869 }
870 return E_OK;
871 }
872
RemoveTimerByThreadPool(TimerId timerId,bool wait)873 void RuntimeContextImpl::RemoveTimerByThreadPool(TimerId timerId, bool wait)
874 {
875 std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
876 if (threadPool == nullptr) {
877 return;
878 }
879 TaskId taskId;
880 {
881 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
882 if (taskIds_.find(timerId) == taskIds_.end()) {
883 return;
884 }
885 taskId = taskIds_[timerId];
886 taskIds_.erase(timerId);
887 }
888 bool removeBeforeExecute = threadPool->Remove(taskId, wait);
889 TimerFinalizer timerFinalizer = nullptr;
890 if (removeBeforeExecute) {
891 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
892 timerFinalizer = timerFinalizers_[timerId];
893 timerFinalizers_.erase(timerId);
894 }
895 if (timerFinalizer) {
896 timerFinalizer();
897 }
898 }
899
ThreadPoolTimerAction(int milliSeconds,const TimerAction & action,TimerId timerId)900 void RuntimeContextImpl::ThreadPoolTimerAction(int milliSeconds, const TimerAction &action, TimerId timerId)
901 {
902 TimerFinalizer timerFinalizer = nullptr;
903 bool timerExist = true;
904 {
905 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
906 if (timerFinalizers_.find(timerId) == timerFinalizers_.end()) {
907 LOGD("[ThreadPoolTimerAction] Timer has been finalize");
908 return;
909 }
910 timerFinalizer = timerFinalizers_[timerId];
911 timerFinalizers_.erase(timerId);
912 if (taskIds_.find(timerId) == taskIds_.end()) {
913 LOGD("[ThreadPoolTimerAction] Timer has been removed");
914 timerExist = false;
915 }
916 }
917 if (timerExist && action(timerId) == E_OK) {
918 // schedule task again
919 int errCode = SetTimerByThreadPool(milliSeconds, action, timerFinalizer, false, timerId);
920 if (errCode == E_OK) {
921 return;
922 }
923 LOGW("[RuntimeContext] create timer failed %d", errCode);
924 }
925 if (timerFinalizer) {
926 timerFinalizer();
927 }
928 {
929 std::lock_guard<std::mutex> autoLock(timerTaskLock_);
930 taskIds_.erase(timerId);
931 }
932 std::lock_guard<std::mutex> autoLock(timersLock_);
933 timers_.erase(timerId);
934 }
935
SetCloudTranslate(const std::shared_ptr<ICloudDataTranslate> & dataTranslate)936 void RuntimeContextImpl::SetCloudTranslate(const std::shared_ptr<ICloudDataTranslate> &dataTranslate)
937 {
938 std::unique_lock<std::shared_mutex> autoLock(dataTranslateLock_);
939 dataTranslate_ = dataTranslate;
940 }
941
AssetToBlob(const Asset & asset,std::vector<uint8_t> & blob)942 int RuntimeContextImpl::AssetToBlob(const Asset &asset, std::vector<uint8_t> &blob)
943 {
944 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
945 if (dataTranslate_ == nullptr) {
946 return -E_NOT_INIT;
947 }
948 blob = dataTranslate_->AssetToBlob(asset);
949 return E_OK;
950 }
951
AssetsToBlob(const Assets & assets,std::vector<uint8_t> & blob)952 int RuntimeContextImpl::AssetsToBlob(const Assets &assets, std::vector<uint8_t> &blob)
953 {
954 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
955 if (dataTranslate_ == nullptr) {
956 return -E_NOT_INIT;
957 }
958 blob = dataTranslate_->AssetsToBlob(assets);
959 return E_OK;
960 }
961
BlobToAsset(const std::vector<uint8_t> & blob,Asset & asset)962 int RuntimeContextImpl::BlobToAsset(const std::vector<uint8_t> &blob, Asset &asset)
963 {
964 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
965 if (dataTranslate_ == nullptr) {
966 return -E_NOT_INIT;
967 }
968 asset = dataTranslate_->BlobToAsset(blob);
969 return E_OK;
970 }
971
BlobToAssets(std::vector<uint8_t> & blob,Assets & assets)972 int RuntimeContextImpl::BlobToAssets(std::vector<uint8_t> &blob, Assets &assets)
973 {
974 std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
975 if (dataTranslate_ == nullptr) {
976 return -E_NOT_INIT;
977 }
978 assets = dataTranslate_->BlobToAssets(blob);
979 return E_OK;
980 }
981 } // namespace DistributedDB
982