1 /*
2  * Copyright (c) 2024 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 #ifndef FOUNDATION_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H
17 #define FOUNDATION_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H
18 
19 #include <mutex>
20 #include <string>
21 #include <thread>
22 
23 #include "base/memory/ace_type.h"
24 #include "base/thread/cancelable_callback.h"
25 #include "base/thread/task_executor.h"
26 #include "core/common/container.h"
27 
28 namespace OHOS::Ace {
29 template<class T>
30 class UpdateConfigManager : public virtual AceType {
31     DECLARE_ACE_TYPE(UpdateConfigManager<T>, AceType);
32 public:
33     struct UpdateTask {
34         CancelableCallback<void()> updateTask;
35         T target;
36     };
37 
UpdateConfigSync(const T & config,std::function<void ()> && task)38     void UpdateConfigSync(const T& config, std::function<void()> &&task)
39     {
40         // Update current state
41         {
42             std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
43             currentTask_.updateTask.Cancel();
44             currentTask_.target = config;
45         }
46 
47         task();
48     }
49 
50     void UpdatePromiseConfig(const T& config, std::function<void()> &&task, const RefPtr<Container>& container,
51         const std::string& taskName, TaskExecutor::TaskType type = TaskExecutor::TaskType::PLATFORM)
52     {
53         std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
54         CancelUselessTaskLocked();
55         currentTask_.target = config;
56 
57         auto taskExecutor = container->GetTaskExecutor();
58         CHECK_NULL_VOID(taskExecutor);
59         taskExecutor->PostTask(std::move(task), type, taskName);
60     }
61 
62     void UpdateConfig(const T& config, std::function<void()> &&task, const RefPtr<Container>& container,
63         const std::string& taskName, TaskExecutor::TaskType type = TaskExecutor::TaskType::PLATFORM)
64     {
65         CancelableCallback<void()> cancelableTask(std::move(task));
66 
67         std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
68         if (config == currentTask_.target) {
69             // If config is same as current/next state, return directely.
70             return;
71         } else {
72             // Try to cancel useless task.
73             CancelUselessTaskLocked();
74             // Post new task.
75             PostUpdateConfigTaskLocked(config, std::move(cancelableTask), container, taskName, type);
76         }
77     }
78 
StoreConfig(T & config)79     void StoreConfig(T& config)
80     {
81         aceConfig_ = config;
82     }
83 
IsConfigsEqual(const ViewportConfig & other)84     bool IsConfigsEqual(const ViewportConfig& other)
85     {
86         return aceConfig_.config_ == other;
87     }
88 private:
PostUpdateConfigTaskLocked(const T & config,CancelableCallback<void ()> && task,const RefPtr<Container> & container,const std::string & taskName,TaskExecutor::TaskType type)89     void PostUpdateConfigTaskLocked(const T& config, CancelableCallback<void()> &&task,
90         const RefPtr<Container>& container, const std::string& taskName, TaskExecutor::TaskType type)
91     {
92         currentTask_ = {
93             .updateTask = std::move(task),
94             .target = config,
95         };
96         auto taskExecutor = container->GetTaskExecutor();
97         CHECK_NULL_VOID(taskExecutor);
98         taskExecutor->PostTask(currentTask_.updateTask, type, taskName);
99     }
100 
CancelUselessTaskLocked()101     void CancelUselessTaskLocked()
102     {
103         currentTask_.updateTask.Cancel();
104     }
105 
106     std::mutex updateTaskMutex_;
107 
108     UpdateTask currentTask_;
109 
110     T aceConfig_;
111 };
112 } // OHOS::Ace
113 #endif // FOUNDATION_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H
114