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