• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SAFE_AREA_SAFE_AREA_MANAGER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SAFE_AREA_SAFE_AREA_MANAGER_H
18 
19 #include "base/memory/ace_type.h"
20 #include "base/utils/noncopyable.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/property/safe_area_insets.h"
23 #include "core/components_ng/property/transition_property.h"
24 
25 namespace OHOS::Ace::NG {
26 // SafeAreaManager stores layout information to apply SafeArea correctly.
27 class SafeAreaManager : public virtual AceType {
28     DECLARE_ACE_TYPE(SafeAreaManager, AceType);
29 
30 public:
31     SafeAreaManager() = default;
32     ~SafeAreaManager() override = default;
33 
34     /**
35      * @brief Check if the incoming safe area is identical to the system safe area
36      *
37      * @param safeArea The new system safe area.
38      * @return True if the incoming safe area is identical to the current one, false otherwise.
39      */
40     bool CheckSystemSafeArea(const SafeAreaInsets& safeArea);
41 
42     /**
43      * @brief Updates the system safe area.
44      *
45      * @param safeArea The new system safe area.
46      * @return True if the system safe area was modified, false otherwise.
47      */
48     bool UpdateSystemSafeArea(const SafeAreaInsets& safeArea);
49 
50     /**
51      * @brief Check if the incoming safe area is identical to the navigation indictor safe area.
52      *
53      * @param safeArea The new navigation indictor safe area.
54      * @return True if the incoming safe area is identical to the current one, false otherwise.
55      */
56     bool CheckNavArea(const SafeAreaInsets& safeArea);
57 
58     /**
59      * @brief Updates the navigation indictor safe area.
60      *
61      * @param safeArea The new navigation indictor safe area.
62      * @return True if the system safe area was modified, false otherwise.
63      */
64     bool UpdateNavArea(const SafeAreaInsets& safeArea);
65 
66     /**
67      * @brief Retrieves the system safe area insets.
68      *
69      * This function returns the safe area insets of the system, which represents the portion of the screen that is
70      * covered by system UI elements such as the status bar or navigation bar.
71      *
72      * @return The system safe area insets.
73      */
74     SafeAreaInsets GetSystemSafeArea() const;
75 
76     /**
77      * @brief Cut the incoming area with root size, then check if the result is identical to the cutout safe area.
78      *
79      * @param safeArea The SafeAreaInsets representing the new cutout safe area, which would be modified.
80      * @return True if the incoming safe area is identical to the current one, false otherwise.
81      */
82     bool CheckCutoutSafeArea(
83         const SafeAreaInsets& safeArea, NG::OptionalSize<uint32_t> rootSize = NG::OptionalSize<uint32_t>());
84 
85     /**
86      * @brief Updates the cutout safe area.
87      *
88      * This function is responsible for updating the cutout safe area based on the provided SafeAreaInsets.
89      *
90      * @param safeArea The SafeAreaInsets representing the new cutout safe area.
91      * @return true if the cutout safe area was successfully updated, false otherwise.
92      */
93     bool UpdateCutoutSafeArea(
94         const SafeAreaInsets& safeArea, NG::OptionalSize<uint32_t> rootSize = NG::OptionalSize<uint32_t>());
95 
96     /**
97      * @brief Retrieves the safe area insets that account for any cutout areas on the screen.
98      *
99      * @return The safe area insets that account for any cutout areas on the screen.
100      */
101     SafeAreaInsets GetCutoutSafeArea() const;
102 
103     /**
104      * @brief Retrieves the safe area insets combining System and Cutout.
105      *
106      * @return The System & Cutout safe area insets.
107      */
108     SafeAreaInsets GetSafeArea() const;
109 
110     /**
111      * @brief Retrieves the safe area insets only System.
112      *
113      * @return The System safe area insets.
114      */
115     SafeAreaInsets GetSafeAreaWithoutCutout() const;
116 
117     /**
118      * @brief Updates the safe area to accommodate the keyboard.
119      *
120      * This function is called to update the safe area when the keyboard is shown or hidden.
121      *
122      * @param keyboardHeight The height of the keyboard in pixels.
123      * @return true if the safe area was modified, false otherwise.
124      */
125     bool UpdateKeyboardSafeArea(float keyboardHeight, std::optional<uint32_t> rootHeight = std::nullopt);
126 
127     /**
128      * @brief Retrieves the inset of the safe area caused by the keyboard.
129      *
130      * @return The inset of the safe area caused by the keyboard.
131      */
GetKeyboardInset()132     SafeAreaInsets::Inset GetKeyboardInset() const
133     {
134         return keyboardInset_;
135     }
136 
UpdateKeyboardOffset(float offset)137     void UpdateKeyboardOffset(float offset)
138     {
139         keyboardOffset_ = offset;
140     }
141     float GetKeyboardOffset() const;
142 
GetRawKeyboardHeight()143     float GetRawKeyboardHeight() const
144     {
145         return rawKeyboardHeight_;
146     }
147 
SetRawKeyboardHeight(float height)148     void SetRawKeyboardHeight(float height)
149     {
150         rawKeyboardHeight_ = height;
151     }
152 
KeyboardSafeAreaEnabled()153     bool KeyboardSafeAreaEnabled() const
154     {
155         return keyboardSafeAreaEnabled_;
156     }
157 
158     SafeAreaInsets GetCombinedSafeArea(const SafeAreaExpandOpts& opts) const;
159 
GetGeoRestoreNodes()160     const std::set<WeakPtr<FrameNode>>& GetGeoRestoreNodes() const
161     {
162         return geoRestoreNodes_;
163     }
164 
AddGeoRestoreNode(const WeakPtr<FrameNode> & node)165     void AddGeoRestoreNode(const WeakPtr<FrameNode>& node)
166     {
167         geoRestoreNodes_.insert(node);
168     }
169 
AddNeedExpandNode(const WeakPtr<FrameNode> & node)170     void AddNeedExpandNode(const WeakPtr<FrameNode>& node)
171     {
172         needExpandNodes_.insert(node);
173     }
174 
175     bool AddNodeToExpandListIfNeeded(const WeakPtr<FrameNode>& node);
176 
ClearNeedExpandNode()177     void ClearNeedExpandNode()
178     {
179         needExpandNodes_.clear();
180     }
181 
RemoveRestoreNode(const WeakPtr<FrameNode> & node)182     void RemoveRestoreNode(const WeakPtr<FrameNode>& node)
183     {
184         geoRestoreNodes_.erase(node);
185     }
186 
GetSafeAreaCurve()187     RefPtr<InterpolatingSpring> GetSafeAreaCurve() const
188     {
189         return safeAreaCurve_;
190     }
191     void ExpandSafeArea();
192 
193     OffsetF GetWindowWrapperOffset();
194 
195     SafeAreaInsets GetSafeAreaWithoutProcess() const;
196 
197     bool SetIsFullScreen(bool value);
198     bool SetIsNeedAvoidWindow(bool value);
199     bool SetIgnoreSafeArea(bool value);
200     bool SetKeyBoardAvoidMode(bool value);
IsIgnoreAsfeArea()201     bool IsIgnoreAsfeArea()
202     {
203         return ignoreSafeArea_;
204     }
IsNeedAvoidWindow()205     bool IsNeedAvoidWindow()
206     {
207         return isNeedAvoidWindow_;
208     }
IsFullScreen()209     bool IsFullScreen()
210     {
211         return isFullScreen_;
212     }
213     bool SetIsAtomicService(bool value);
214     bool IsAtomicService() const;
215 
GetSafeHeight()216     float GetSafeHeight() const
217     {
218         Dimension safeDistance = 16.0_vp;
219         return safeDistance.ConvertToPx();
220     }
221 
SetLastKeyboardPoistion(float position)222     void SetLastKeyboardPoistion(float position)
223     {
224         lastKeyboardY_ = position;
225     }
226 
GetLastKeyboardPoistion()227     float GetLastKeyboardPoistion() const
228     {
229         return lastKeyboardY_;
230     }
231 
232     bool IsSafeAreaValid() const;
233     // check if the page node needs to be avoid keyboard
234     bool CheckPageNeedAvoidKeyboard(const RefPtr<FrameNode>& frameNode);
235 
GetkeyboardHeightConsideringUIExtension()236     uint32_t GetkeyboardHeightConsideringUIExtension()
237     {
238         return keyboardHeightConsideringUIExtension_;
239     }
SetkeyboardHeightConsideringUIExtension(uint32_t height)240     void SetkeyboardHeightConsideringUIExtension(uint32_t height)
241     {
242         if (keyboardHeightConsideringUIExtension_ != height) {
243             for (const auto& [nodeId, callback] : keyboardChangeCbsConsideringUIExt_) {
244                 if (callback) {
245                     callback();
246                 }
247             }
248             keyboardHeightConsideringUIExtension_ = height;
249         }
250     }
AddKeyboardChangeCallbackConsideringUIExt(int32_t nodeId,const std::function<void ()> & callback)251     void AddKeyboardChangeCallbackConsideringUIExt(int32_t nodeId, const std::function<void()>& callback)
252     {
253         keyboardChangeCbsConsideringUIExt_[nodeId] = callback;
254     }
RemoveKeyboardChangeCallbackConsideringUIExt(int32_t nodeId)255     void RemoveKeyboardChangeCallbackConsideringUIExt(int32_t nodeId)
256     {
257         keyboardChangeCbsConsideringUIExt_.erase(nodeId);
258     }
259 
260 private:
261     bool isAtomicService_ = false;
262 
263     // app window is full screen
264     // todo: remove and only use isNeedAvoidWindow_
265     bool isFullScreen_ = false;
266 
267     /**
268      * @brief Indicates whether the UI within the current window type needs to avoid SafeAreaInsets.
269      */
270     bool isNeedAvoidWindow_ = false;
271 
272     /**
273      * @brief Indicates whether to ignore the SafeAreaInsets, specified by the developer from frontend.
274      */
275     bool ignoreSafeArea_ = false;
276 
277     /**
278      * @brief Indicates whether the keyboard safe area is enabled. When enabled, UI avoids the keyboard inset and the
279      * Page is compressed when the keyboard is up. When disabled, the size of Page doesn't change, but Page would
280      * offset vertically according to [keyboardOffset_].
281      */
282     bool keyboardSafeAreaEnabled_ = false;
283 
284     SafeAreaInsets systemSafeArea_;
285     SafeAreaInsets cutoutSafeArea_;
286     SafeAreaInsets navSafeArea_;
287     // keyboard is bottom direction only
288     SafeAreaInsets::Inset keyboardInset_;
289 
290     /**
291      * @brief A set of weak pointers to FrameNode objects whose geometry info are saved before their SafeArea
292      * expansion. The geometry info of these nodes need to be restored when their next Layout task begins.
293      */
294     std::set<WeakPtr<FrameNode>> geoRestoreNodes_;
295 
296     struct DepthCompare {
operatorDepthCompare297         bool operator()(const WeakPtr<FrameNode>& a, const WeakPtr<FrameNode>& b) const
298         {
299             auto ptrA = a.Upgrade();
300             auto ptrB = b.Upgrade();
301             if (!ptrA || !ptrB) {
302                 return false;
303             }
304             if (ptrA->GetDepth() < ptrB->GetDepth()) {
305                 return true;
306             }
307             if (ptrA->GetDepth() == ptrB->GetDepth()) {
308                 return ptrA < ptrB;
309             }
310             return false;
311         }
312     };
313     std::set<WeakPtr<FrameNode>, DepthCompare> needExpandNodes_;
314     // amount of offset to apply to Page when keyboard is up
315     float keyboardOffset_ = 0.0f;
316     float lastKeyboardY_ = 0.0f;
317     float rawKeyboardHeight_ = 0.0f;
318 
319     static constexpr float SAFE_AREA_VELOCITY = 0.0f;
320     static constexpr float SAFE_AREA_MASS = 1.0f;
321     static constexpr float SAFE_AREA_STIFFNESS = 228.0f;
322     static constexpr float SAFE_AREA_DAMPING = 30.0f;
323     RefPtr<InterpolatingSpring> safeAreaCurve_ = AceType::MakeRefPtr<InterpolatingSpring>(
324         SAFE_AREA_VELOCITY, SAFE_AREA_MASS, SAFE_AREA_STIFFNESS, SAFE_AREA_DAMPING);
325 
326     uint32_t keyboardHeightConsideringUIExtension_ = 0;
327     std::unordered_map<int32_t, std::function<void()>> keyboardChangeCbsConsideringUIExt_;
328 
329     ACE_DISALLOW_COPY_AND_MOVE(SafeAreaManager);
330 };
331 } // namespace OHOS::Ace::NG
332 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SAFE_AREA_SAFE_AREA_MANAGER_H
333