• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         std::unordered_map<int32_t, CancelableCallback<void()>> promiseTaskMap;
36         T target;
37     };
38 
UpdateConfigSync(const T & config,std::function<void ()> && task)39     void UpdateConfigSync(const T& config, std::function<void()> &&task)
40     {
41         // Update current state
42         {
43             std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
44             currentTask_.updateTask.Cancel();
45             currentTask_.target = config;
46         }
47 
48         task();
49     }
50 
UpdateViewConfigTaskDone(int32_t taskId)51     void UpdateViewConfigTaskDone(int32_t taskId)
52     {
53         std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
54         currentTask_.promiseTaskMap.erase(taskId);
55     }
56 
CancelAllPromiseTaskLocked()57     void CancelAllPromiseTaskLocked()
58     {
59         std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
60         for (auto it = currentTask_.promiseTaskMap.begin(); it != currentTask_.promiseTaskMap.end();) {
61             it = it->second.Cancel() ? currentTask_.promiseTaskMap.erase(it) : ++it;
62         }
63     }
64 
CancelUselessTaskLocked()65     void CancelUselessTaskLocked()
66     {
67         currentTask_.updateTask.Cancel();
68     }
69 
70     void UpdatePromiseConfig(const T& config, std::function<void()> &&task, const RefPtr<Container>& container,
71         int32_t taskId, const std::string& taskName, TaskExecutor::TaskType type = TaskExecutor::TaskType::PLATFORM)
72     {
73         std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
74         CancelUselessTaskLocked();
75         CancelableCallback<void()> promiseTask(std::move(task));
76         currentTask_.promiseTaskMap[taskId] = promiseTask;
77         currentTask_.target = config;
78 
79         auto taskExecutor = container->GetTaskExecutor();
80         CHECK_NULL_VOID(taskExecutor);
81         taskExecutor->PostTask(std::move(promiseTask), type, taskName);
82     }
83 
84     void UpdateConfig(const T& config, std::function<void()> &&task, const RefPtr<Container>& container,
85         const std::string& taskName, TaskExecutor::TaskType type = TaskExecutor::TaskType::PLATFORM)
86     {
87         CancelableCallback<void()> cancelableTask(std::move(task));
88 
89         std::lock_guard<std::mutex> taskLock(updateTaskMutex_);
90         if (config == currentTask_.target) {
91             // If config is same as current/next state, return directely.
92             return;
93         } else {
94             // Try to cancel useless task.
95             CancelUselessTaskLocked();
96             // Post new task.
97             PostUpdateConfigTaskLocked(config, std::move(cancelableTask), container, taskName, type);
98         }
99     }
100 
StoreConfig(T & config)101     void StoreConfig(T& config)
102     {
103         aceConfig_ = config;
104     }
105 
IsConfigsEqual(const ViewportConfig & other)106     bool IsConfigsEqual(const ViewportConfig& other)
107     {
108         return aceConfig_.config_ == other;
109     }
110 
StoreInfo(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo> & info)111     void StoreInfo(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo>& info)
112     {
113         info_ = info;
114     }
115 
IsInfoEqual(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo> & info)116     bool IsInfoEqual(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo>& info)
117     {
118         if (!info_) {
119             if (info) {
120                 return false;
121             }
122             return true;
123         }
124         if (!info) {
125             return false;
126         }
127         auto rect_ = info_->rect_;
128         auto rect = info->rect_;
129         if (info_->textFieldPositionY_ != info->textFieldPositionY_) {
130             return false;
131         }
132         if (info_->textFieldHeight_ != info->textFieldHeight_) {
133             return false;
134         }
135         if (rect_.posX_ != rect.posX_ || rect_.posY_ != rect.posY_ ||
136             rect_.width_ != rect.width_ || rect_.height_ != rect.height_) {
137             return false;
138         }
139         return true;
140     }
141 
MakeTaskId()142     int32_t MakeTaskId()
143     {
144         return nextTaskId_.fetch_add(1);
145     }
146 private:
PostUpdateConfigTaskLocked(const T & config,CancelableCallback<void ()> && task,const RefPtr<Container> & container,const std::string & taskName,TaskExecutor::TaskType type)147     void PostUpdateConfigTaskLocked(const T& config, CancelableCallback<void()> &&task,
148         const RefPtr<Container>& container, const std::string& taskName, TaskExecutor::TaskType type)
149     {
150         currentTask_ = {
151             .updateTask = std::move(task),
152             .target = config,
153         };
154         auto taskExecutor = container->GetTaskExecutor();
155         CHECK_NULL_VOID(taskExecutor);
156         taskExecutor->PostTask(currentTask_.updateTask, type, taskName);
157     }
158 
159     std::mutex updateTaskMutex_;
160 
161     UpdateTask currentTask_;
162 
163     std::atomic<int32_t> nextTaskId_ = 0;
164 
165     T aceConfig_;
166 
167     sptr<OHOS::Rosen::OccupiedAreaChangeInfo> info_ = nullptr;
168 };
169 } // OHOS::Ace
170 #endif // FOUNDATION_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H
171