114cf0368Sopenharmony_ci/* 214cf0368Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 314cf0368Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 414cf0368Sopenharmony_ci * you may not use this file except in compliance with the License. 514cf0368Sopenharmony_ci * You may obtain a copy of the License at 614cf0368Sopenharmony_ci * 714cf0368Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 814cf0368Sopenharmony_ci * 914cf0368Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1014cf0368Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1114cf0368Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1214cf0368Sopenharmony_ci * See the License for the specific language governing permissions and 1314cf0368Sopenharmony_ci * limitations under the License. 1414cf0368Sopenharmony_ci */ 1514cf0368Sopenharmony_ci#include "async_obtain_data.h" 1614cf0368Sopenharmony_ci#define LOG_TAG "AsyncObtainData" 1714cf0368Sopenharmony_ci#include <cstdint> 1814cf0368Sopenharmony_ci#include <algorithm> 1914cf0368Sopenharmony_ci#include "unified_types.h" 2014cf0368Sopenharmony_ci#include "logger.h" 2114cf0368Sopenharmony_ci#include "udmf_service_client.h" 2214cf0368Sopenharmony_ci#include "securec.h" 2314cf0368Sopenharmony_ci 2414cf0368Sopenharmony_cinamespace OHOS { 2514cf0368Sopenharmony_cinamespace UDMF { 2614cf0368Sopenharmony_cistatic constexpr size_t MAX_THREADS = 2; 2714cf0368Sopenharmony_cistatic constexpr size_t MIN_THREADS = 0; 2814cf0368Sopenharmony_cistatic constexpr uint32_t MAX_PROGRESS = 100; 2914cf0368Sopenharmony_cistatic constexpr double MAX_PROGRESS_DOUBLE = 100.0; 3014cf0368Sopenharmony_cistatic constexpr double SYNC_COEFF = 0.5; 3114cf0368Sopenharmony_cistatic constexpr double PERM_COEFF = 0.4; 3214cf0368Sopenharmony_ci 3314cf0368Sopenharmony_ciAsyncObtainData::AsyncObtainData() : executor_(MAX_THREADS, MIN_THREADS) {} 3414cf0368Sopenharmony_ci 3514cf0368Sopenharmony_ciStatus AsyncObtainData::InitTask(const QueryOption &query, ObtainDataCallback callback) 3614cf0368Sopenharmony_ci{ 3714cf0368Sopenharmony_ci if (callback == nullptr) { 3814cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "callback invalid"); 3914cf0368Sopenharmony_ci taskStatus_ = ASYNC_FAILURE; 4014cf0368Sopenharmony_ci return E_INVALID_PARAMETERS; 4114cf0368Sopenharmony_ci } 4214cf0368Sopenharmony_ci 4314cf0368Sopenharmony_ci serviceClient_ = UdmfServiceClient::GetInstance(); 4414cf0368Sopenharmony_ci if (serviceClient_ == nullptr) { 4514cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Service unavailable"); 4614cf0368Sopenharmony_ci taskStatus_ = ASYNC_FAILURE; 4714cf0368Sopenharmony_ci return E_IPC; 4814cf0368Sopenharmony_ci } 4914cf0368Sopenharmony_ci 5014cf0368Sopenharmony_ci initialized_ = true; 5114cf0368Sopenharmony_ci query_ = query; 5214cf0368Sopenharmony_ci callback_ = callback; 5314cf0368Sopenharmony_ci taskStatus_ = ASYNC_RUNNING; 5414cf0368Sopenharmony_ci processInfo_.syncStatus = ASYNC_RUNNING; 5514cf0368Sopenharmony_ci return E_OK; 5614cf0368Sopenharmony_ci} 5714cf0368Sopenharmony_ci 5814cf0368Sopenharmony_ciStatus AsyncObtainData::RunTask() 5914cf0368Sopenharmony_ci{ 6014cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "Enter"); 6114cf0368Sopenharmony_ci if (serviceClient_ == nullptr) { 6214cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! service client is nullptr"); 6314cf0368Sopenharmony_ci return E_IPC; 6414cf0368Sopenharmony_ci } 6514cf0368Sopenharmony_ci if (!initialized_) { 6614cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! not init"); 6714cf0368Sopenharmony_ci return E_ERROR; 6814cf0368Sopenharmony_ci } 6914cf0368Sopenharmony_ci obtainDataTaskId_ = executor_.Execute(std::bind(&AsyncObtainData::ObtainDataTask, this)); 7014cf0368Sopenharmony_ci progressTaskId_ = executor_.Execute(std::bind(&AsyncObtainData::ProgressTask, this)); 7114cf0368Sopenharmony_ci 7214cf0368Sopenharmony_ci return E_OK; 7314cf0368Sopenharmony_ci} 7414cf0368Sopenharmony_ci 7514cf0368Sopenharmony_civoid AsyncObtainData::ObtainDataTask() 7614cf0368Sopenharmony_ci{ 7714cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "Enter"); 7814cf0368Sopenharmony_ci if ((taskStatus_ == ASYNC_RUNNING) && (processInfo_.syncStatus == ASYNC_RUNNING)) { 7914cf0368Sopenharmony_ci Executor::Duration delay = std::chrono::milliseconds(500); 8014cf0368Sopenharmony_ci obtainDataTaskId_ = executor_.Schedule(delay, std::bind(&AsyncObtainData::ObtainDataTask, this)); 8114cf0368Sopenharmony_ci return; 8214cf0368Sopenharmony_ci } 8314cf0368Sopenharmony_ci 8414cf0368Sopenharmony_ci UnifiedData unifiedData; 8514cf0368Sopenharmony_ci if (taskStatus_ != ASYNC_FAILURE) { 8614cf0368Sopenharmony_ci if (serviceClient_ == nullptr) { 8714cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! serviceClient_ is nullptr"); 8814cf0368Sopenharmony_ci return; 8914cf0368Sopenharmony_ci } 9014cf0368Sopenharmony_ci int32_t ret = serviceClient_->GetData(query_, unifiedData); 9114cf0368Sopenharmony_ci if (ret != E_OK) { 9214cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); 9314cf0368Sopenharmony_ci taskStatus_ = ASYNC_FAILURE; 9414cf0368Sopenharmony_ci } else { 9514cf0368Sopenharmony_ci taskStatus_ = ASYNC_SUCCESS; 9614cf0368Sopenharmony_ci } 9714cf0368Sopenharmony_ci } 9814cf0368Sopenharmony_ci InvokeCallback(unifiedData); 9914cf0368Sopenharmony_ci ClearTask(); 10014cf0368Sopenharmony_ci} 10114cf0368Sopenharmony_ci 10214cf0368Sopenharmony_civoid AsyncObtainData::ProgressTask() 10314cf0368Sopenharmony_ci{ 10414cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "Enter"); 10514cf0368Sopenharmony_ci if (serviceClient_ == nullptr) { 10614cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! serviceClient_ is nullptr"); 10714cf0368Sopenharmony_ci return; 10814cf0368Sopenharmony_ci } 10914cf0368Sopenharmony_ci AsyncProcessInfo processInfo; 11014cf0368Sopenharmony_ci int32_t ret = serviceClient_->ObtainAsynProcess(processInfo); 11114cf0368Sopenharmony_ci if (ret != E_OK) { 11214cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); 11314cf0368Sopenharmony_ci taskStatus_ = ASYNC_FAILURE; 11414cf0368Sopenharmony_ci return; 11514cf0368Sopenharmony_ci } 11614cf0368Sopenharmony_ci 11714cf0368Sopenharmony_ci UpdateProcessInfo(processInfo); 11814cf0368Sopenharmony_ci 11914cf0368Sopenharmony_ci UnifiedData unifiedData; 12014cf0368Sopenharmony_ci InvokeCallback(unifiedData); 12114cf0368Sopenharmony_ci 12214cf0368Sopenharmony_ci if ((taskStatus_ == ASYNC_RUNNING) && 12314cf0368Sopenharmony_ci ((processInfo.syncStatus == ASYNC_RUNNING) || (processInfo.permStatus == ASYNC_RUNNING))) { 12414cf0368Sopenharmony_ci Executor::Duration delay = std::chrono::milliseconds(500); 12514cf0368Sopenharmony_ci progressTaskId_ = executor_.Schedule(delay, std::bind(&AsyncObtainData::ProgressTask, this)); 12614cf0368Sopenharmony_ci } 12714cf0368Sopenharmony_ci} 12814cf0368Sopenharmony_ci 12914cf0368Sopenharmony_civoid AsyncObtainData::InvokeCallback(UnifiedData &data) 13014cf0368Sopenharmony_ci{ 13114cf0368Sopenharmony_ci ProgressInfo progress{ "", ASYNC_IDLE, 0 }; 13214cf0368Sopenharmony_ci progress.status = taskStatus_; 13314cf0368Sopenharmony_ci progress.srcDevName = processInfo_.srcDevName; 13414cf0368Sopenharmony_ci 13514cf0368Sopenharmony_ci progress.progress = CalProgress(); 13614cf0368Sopenharmony_ci if (progress.progress <= lastProgress_) { 13714cf0368Sopenharmony_ci progress.progress = lastProgress_; 13814cf0368Sopenharmony_ci } else { 13914cf0368Sopenharmony_ci lastProgress_ = progress.progress; 14014cf0368Sopenharmony_ci } 14114cf0368Sopenharmony_ci if (callback_ == nullptr) { 14214cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! callback_ is nullptr"); 14314cf0368Sopenharmony_ci return; 14414cf0368Sopenharmony_ci } 14514cf0368Sopenharmony_ci callback_(progress, data); 14614cf0368Sopenharmony_ci} 14714cf0368Sopenharmony_ci 14814cf0368Sopenharmony_civoid AsyncObtainData::UpdateProcessInfo(AsyncProcessInfo &info) 14914cf0368Sopenharmony_ci{ 15014cf0368Sopenharmony_ci processInfo_.syncStatus = info.syncStatus; 15114cf0368Sopenharmony_ci processInfo_.permStatus = info.permStatus; 15214cf0368Sopenharmony_ci processInfo_.srcDevName = (info.syncStatus == ASYNC_IDLE ? "Local" : info.srcDevName); 15314cf0368Sopenharmony_ci processInfo_.syncFinished = info.syncFinished; 15414cf0368Sopenharmony_ci processInfo_.syncTotal = info.syncTotal; 15514cf0368Sopenharmony_ci processInfo_.syncId = info.syncId; 15614cf0368Sopenharmony_ci processInfo_.permFnished = info.permFnished; 15714cf0368Sopenharmony_ci processInfo_.permTotal = info.permTotal; 15814cf0368Sopenharmony_ci 15914cf0368Sopenharmony_ci if (processInfo_.syncStatus == ASYNC_FAILURE || processInfo_.permStatus == ASYNC_FAILURE) { 16014cf0368Sopenharmony_ci taskStatus_ = ASYNC_FAILURE; 16114cf0368Sopenharmony_ci } 16214cf0368Sopenharmony_ci} 16314cf0368Sopenharmony_ci 16414cf0368Sopenharmony_civoid AsyncObtainData::ClearTask() 16514cf0368Sopenharmony_ci{ 16614cf0368Sopenharmony_ci initialized_ = false; 16714cf0368Sopenharmony_ci taskStatus_ = ASYNC_IDLE; 16814cf0368Sopenharmony_ci lastProgress_ = 0; 16914cf0368Sopenharmony_ci progressTaskId_ = ExecutorPool::INVALID_TASK_ID; 17014cf0368Sopenharmony_ci obtainDataTaskId_ = ExecutorPool::INVALID_TASK_ID; 17114cf0368Sopenharmony_ci (void)memset_s(&processInfo_, sizeof(processInfo_), 0, sizeof(processInfo_)); 17214cf0368Sopenharmony_ci 17314cf0368Sopenharmony_ci serviceClient_ = UdmfServiceClient::GetInstance(); 17414cf0368Sopenharmony_ci if (serviceClient_ == nullptr) { 17514cf0368Sopenharmony_ci return; 17614cf0368Sopenharmony_ci } 17714cf0368Sopenharmony_ci auto ret = serviceClient_->ClearAsynProcess(); 17814cf0368Sopenharmony_ci if (ret != E_OK) { 17914cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); 18014cf0368Sopenharmony_ci } 18114cf0368Sopenharmony_ci serviceClient_ = nullptr; 18214cf0368Sopenharmony_ci} 18314cf0368Sopenharmony_ci 18414cf0368Sopenharmony_ciuint32_t AsyncObtainData::CalProgress() 18514cf0368Sopenharmony_ci{ 18614cf0368Sopenharmony_ci if (taskStatus_ == ASYNC_SUCCESS) { 18714cf0368Sopenharmony_ci return MAX_PROGRESS; 18814cf0368Sopenharmony_ci } 18914cf0368Sopenharmony_ci if ((taskStatus_ == ASYNC_FAILURE) || (processInfo_.syncStatus == ASYNC_FAILURE) || 19014cf0368Sopenharmony_ci processInfo_.permStatus == ASYNC_FAILURE) { 19114cf0368Sopenharmony_ci return lastProgress_; 19214cf0368Sopenharmony_ci } 19314cf0368Sopenharmony_ci 19414cf0368Sopenharmony_ci uint32_t syncProgress = CalSyncProgress(); 19514cf0368Sopenharmony_ci uint32_t permProgress = CalPermProgress(); 19614cf0368Sopenharmony_ci double totalProgress = syncProgress * SYNC_COEFF + permProgress * PERM_COEFF; 19714cf0368Sopenharmony_ci return static_cast<uint32_t>(totalProgress); 19814cf0368Sopenharmony_ci} 19914cf0368Sopenharmony_ci 20014cf0368Sopenharmony_ciuint32_t AsyncObtainData::CalSyncProgress() 20114cf0368Sopenharmony_ci{ 20214cf0368Sopenharmony_ci if (processInfo_.syncStatus == ASYNC_SUCCESS || processInfo_.syncStatus == ASYNC_IDLE) { 20314cf0368Sopenharmony_ci return MAX_PROGRESS; 20414cf0368Sopenharmony_ci } 20514cf0368Sopenharmony_ci if (processInfo_.syncTotal == 0) { 20614cf0368Sopenharmony_ci return 0; 20714cf0368Sopenharmony_ci } 20814cf0368Sopenharmony_ci return std::min(MAX_PROGRESS, 20914cf0368Sopenharmony_ci static_cast<uint32_t>(processInfo_.syncFinished * MAX_PROGRESS_DOUBLE / processInfo_.syncTotal)); 21014cf0368Sopenharmony_ci} 21114cf0368Sopenharmony_ci 21214cf0368Sopenharmony_ciuint32_t AsyncObtainData::CalPermProgress() 21314cf0368Sopenharmony_ci{ 21414cf0368Sopenharmony_ci if (processInfo_.permStatus == ASYNC_SUCCESS) { 21514cf0368Sopenharmony_ci return MAX_PROGRESS; 21614cf0368Sopenharmony_ci } 21714cf0368Sopenharmony_ci if (processInfo_.permTotal == 0) { 21814cf0368Sopenharmony_ci return 0; 21914cf0368Sopenharmony_ci } 22014cf0368Sopenharmony_ci return std::min(MAX_PROGRESS, 22114cf0368Sopenharmony_ci static_cast<uint32_t>(processInfo_.permFnished * MAX_PROGRESS_DOUBLE / processInfo_.permTotal)); 22214cf0368Sopenharmony_ci} 22314cf0368Sopenharmony_ci} // namespace UDMF 22414cf0368Sopenharmony_ci} // namespace OHOS