123b3eb3cSopenharmony_ci/* 223b3eb3cSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd. 323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License. 523b3eb3cSopenharmony_ci * You may obtain a copy of the License at 623b3eb3cSopenharmony_ci * 723b3eb3cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 823b3eb3cSopenharmony_ci * 923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and 1323b3eb3cSopenharmony_ci * limitations under the License. 1423b3eb3cSopenharmony_ci */ 1523b3eb3cSopenharmony_ci 1623b3eb3cSopenharmony_ci#include "component_test/idle_watcher.h" 1723b3eb3cSopenharmony_ci 1823b3eb3cSopenharmony_ci#include "component_test/component_test_manager_impl.h" 1923b3eb3cSopenharmony_ci 2023b3eb3cSopenharmony_ci#include "base/log/log.h" 2123b3eb3cSopenharmony_ci#include "base/thread/task_executor.h" 2223b3eb3cSopenharmony_ci#include "core/common/task_runner_adapter.h" 2323b3eb3cSopenharmony_ci#include "core/common/task_runner_adapter_factory.h" 2423b3eb3cSopenharmony_ci 2523b3eb3cSopenharmony_cinamespace OHOS::Ace::ComponentTest { 2623b3eb3cSopenharmony_ci 2723b3eb3cSopenharmony_ciconstexpr uint32_t period = 2000 / 4; 2823b3eb3cSopenharmony_ciconstexpr uint32_t delay_next_check = 1000 / 4; 2923b3eb3cSopenharmony_ciconstexpr uint32_t delay_double_confirm = 2000 / 4; 3023b3eb3cSopenharmony_ciconstexpr uint32_t delay_after_change = 5000 / 4; 3123b3eb3cSopenharmony_ci 3223b3eb3cSopenharmony_ciconstexpr uint8_t max_idle_check_retry = 10; 3323b3eb3cSopenharmony_ci 3423b3eb3cSopenharmony_civoid UpdatePipelineStatus() 3523b3eb3cSopenharmony_ci{ 3623b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.Update(); 3723b3eb3cSopenharmony_ci} 3823b3eb3cSopenharmony_ci 3923b3eb3cSopenharmony_civoid IdleMonitorThread::VsyncCountFirstCheck() 4023b3eb3cSopenharmony_ci{ 4123b3eb3cSopenharmony_ci if (ComponentTestManagerImpl::Get()->pipelineStatusHolder.Check()) { 4223b3eb3cSopenharmony_ci PostCheckTask([this]() { VsyncCountSecondCheck(); }, delay_double_confirm); 4323b3eb3cSopenharmony_ci } else { 4423b3eb3cSopenharmony_ci if (ComponentTestManagerImpl::Get()->pipelineStatusHolder.RetryCounterReached(max_idle_check_retry)) { 4523b3eb3cSopenharmony_ci LOGI("IdleMonitorThread wait pipeline idle timeout"); 4623b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.RetryCounterClear(); 4723b3eb3cSopenharmony_ci callback_(); 4823b3eb3cSopenharmony_ci } 4923b3eb3cSopenharmony_ci PostCheckTask([this]() { VsyncCountFirstCheck(); }, delay_next_check); 5023b3eb3cSopenharmony_ci } 5123b3eb3cSopenharmony_ci} 5223b3eb3cSopenharmony_ci 5323b3eb3cSopenharmony_civoid IdleMonitorThread::VsyncCountSecondCheck() 5423b3eb3cSopenharmony_ci{ 5523b3eb3cSopenharmony_ci if (ComponentTestManagerImpl::Get()->pipelineStatusHolder.Check()) { 5623b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.RetryCounterClear(); 5723b3eb3cSopenharmony_ci callback_(); 5823b3eb3cSopenharmony_ci IdleMonitorThread::PostCheckTask([this]() { VsyncCountFirstCheck(); }, period); 5923b3eb3cSopenharmony_ci } else { 6023b3eb3cSopenharmony_ci IdleMonitorThread::PostCheckTask([this]() { VsyncCountFirstCheck(); }, delay_after_change); 6123b3eb3cSopenharmony_ci } 6223b3eb3cSopenharmony_ci} 6323b3eb3cSopenharmony_ci 6423b3eb3cSopenharmony_ciRefPtr<IdleMonitorThread> IdleMonitorThread::Create() 6523b3eb3cSopenharmony_ci{ 6623b3eb3cSopenharmony_ci auto idleMonitorThread = MakeRefPtr<IdleMonitorThread>(); 6723b3eb3cSopenharmony_ci idleMonitorThread->thread = TaskRunnerAdapterFactory::Create(false, "IdleMonitorThread"); 6823b3eb3cSopenharmony_ci return idleMonitorThread; 6923b3eb3cSopenharmony_ci} 7023b3eb3cSopenharmony_ci 7123b3eb3cSopenharmony_civoid IdleMonitorThread::Stop() 7223b3eb3cSopenharmony_ci{ 7323b3eb3cSopenharmony_ci thread.Reset(); 7423b3eb3cSopenharmony_ci} 7523b3eb3cSopenharmony_ci 7623b3eb3cSopenharmony_civoid IdleMonitorThread::SetIdleNotifycallback(IdleNotifycallback callback) 7723b3eb3cSopenharmony_ci{ 7823b3eb3cSopenharmony_ci callback_ = callback; 7923b3eb3cSopenharmony_ci} 8023b3eb3cSopenharmony_ci 8123b3eb3cSopenharmony_civoid IdleMonitorThread::SetTaskExecutor(RefPtr<TaskExecutor> taskExecutor) 8223b3eb3cSopenharmony_ci{ 8323b3eb3cSopenharmony_ci taskExecutor_ = taskExecutor; 8423b3eb3cSopenharmony_ci} 8523b3eb3cSopenharmony_ci 8623b3eb3cSopenharmony_civoid IdleMonitorThread::PostInitializeTask() 8723b3eb3cSopenharmony_ci{ 8823b3eb3cSopenharmony_ci thread->PostDelayedTask([this]() { PostCheckTask([this]() { VsyncCountFirstCheck(); }, period); }, period, {}); 8923b3eb3cSopenharmony_ci} 9023b3eb3cSopenharmony_ci 9123b3eb3cSopenharmony_civoid IdleMonitorThread::PostCheckTask(std::function<void()>&& task, uint32_t delay) 9223b3eb3cSopenharmony_ci{ 9323b3eb3cSopenharmony_ci thread->PostDelayedTask(std::move(task), delay, {}); 9423b3eb3cSopenharmony_ci} 9523b3eb3cSopenharmony_ci 9623b3eb3cSopenharmony_ciIdleWatcher::IdleWatcher(RefPtr<TaskExecutor> taskExecutor) 9723b3eb3cSopenharmony_ci{ 9823b3eb3cSopenharmony_ci keepingIdle_ = false; 9923b3eb3cSopenharmony_ci idleMonitorThread_ = IdleMonitorThread::Create(); 10023b3eb3cSopenharmony_ci idleMonitorThread_->SetIdleNotifycallback([this] { TriggerIdleNotification(); }); 10123b3eb3cSopenharmony_ci idleMonitorThread_->SetTaskExecutor(taskExecutor); 10223b3eb3cSopenharmony_ci idleMonitorThread_->PostInitializeTask(); 10323b3eb3cSopenharmony_ci} 10423b3eb3cSopenharmony_ci 10523b3eb3cSopenharmony_civoid IdleWatcher::Destroy() 10623b3eb3cSopenharmony_ci{ 10723b3eb3cSopenharmony_ci idleMonitorThread_->Stop(); 10823b3eb3cSopenharmony_ci std::lock_guard<std::mutex> lock(observersMutex_); 10923b3eb3cSopenharmony_ci pendingIdleObservers_.clear(); 11023b3eb3cSopenharmony_ci} 11123b3eb3cSopenharmony_ci 11223b3eb3cSopenharmony_civoid IdleWatcher::TriggerIdleNotification() 11323b3eb3cSopenharmony_ci{ 11423b3eb3cSopenharmony_ci LOGI("Triggering idle notification"); 11523b3eb3cSopenharmony_ci keepingIdle_ = true; 11623b3eb3cSopenharmony_ci if (pendingIdleObservers_.empty()) { 11723b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.IdleCounterAdd(); 11823b3eb3cSopenharmony_ci if (ComponentTestManagerImpl::Get()->pipelineStatusHolder.IdleCounterReached(CONTINUOUS_IDLE_TIME) && 11923b3eb3cSopenharmony_ci continuousIdleCallback_) { 12023b3eb3cSopenharmony_ci continuousIdleCallback_(); 12123b3eb3cSopenharmony_ci continuousIdleCallback_ = nullptr; 12223b3eb3cSopenharmony_ci } 12323b3eb3cSopenharmony_ci } else { 12423b3eb3cSopenharmony_ci std::lock_guard<std::mutex> lock(observersMutex_); 12523b3eb3cSopenharmony_ci for (IdleNotifycallback& notifycallback : pendingIdleObservers_) { 12623b3eb3cSopenharmony_ci notifycallback(); 12723b3eb3cSopenharmony_ci } 12823b3eb3cSopenharmony_ci pendingIdleObservers_.clear(); 12923b3eb3cSopenharmony_ci } 13023b3eb3cSopenharmony_ci} 13123b3eb3cSopenharmony_ci 13223b3eb3cSopenharmony_civoid IdleWatcher::RequestNextIdleStatusNotification(IdleNotifycallback&& notifycallback, bool haveUIChange) 13323b3eb3cSopenharmony_ci{ 13423b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.IdleCounterClear(); 13523b3eb3cSopenharmony_ci if (haveUIChange) { 13623b3eb3cSopenharmony_ci notifycallback = [this, notifycallback]() { 13723b3eb3cSopenharmony_ci keepingIdle_ = false; 13823b3eb3cSopenharmony_ci notifycallback(); 13923b3eb3cSopenharmony_ci }; 14023b3eb3cSopenharmony_ci } 14123b3eb3cSopenharmony_ci if (keepingIdle_) { 14223b3eb3cSopenharmony_ci notifycallback(); 14323b3eb3cSopenharmony_ci } else { 14423b3eb3cSopenharmony_ci std::lock_guard<std::mutex> lock(observersMutex_); 14523b3eb3cSopenharmony_ci pendingIdleObservers_.emplace_back(notifycallback); 14623b3eb3cSopenharmony_ci } 14723b3eb3cSopenharmony_ci} 14823b3eb3cSopenharmony_ci 14923b3eb3cSopenharmony_civoid IdleWatcher::RequestContinuousIdleStatusNotification(IdleNotifycallback&& continuousIdleCallback) 15023b3eb3cSopenharmony_ci{ 15123b3eb3cSopenharmony_ci continuousIdleCallback_ = std::move(continuousIdleCallback); 15223b3eb3cSopenharmony_ci} 15323b3eb3cSopenharmony_ci 15423b3eb3cSopenharmony_civoid IdleWatcher::ClaimLongOperation() 15523b3eb3cSopenharmony_ci{ 15623b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.IncreaseLongOpt(); 15723b3eb3cSopenharmony_ci} 15823b3eb3cSopenharmony_ci 15923b3eb3cSopenharmony_civoid IdleWatcher::LongOperationComplete() 16023b3eb3cSopenharmony_ci{ 16123b3eb3cSopenharmony_ci ComponentTestManagerImpl::Get()->pipelineStatusHolder.DecreaseLongOpt(); 16223b3eb3cSopenharmony_ci} 16323b3eb3cSopenharmony_ci} // namespace OHOS::Ace::ComponentTest 164