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_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FOCUS_FOCUS_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FOCUS_FOCUS_MANAGER_H 18 19 #include <list> 20 #include <optional> 21 22 #include "base/error/error_code.h" 23 #include "base/memory/ace_type.h" 24 #include "base/memory/referenced.h" 25 #include "base/utils/listener.h" 26 #include "core/components_ng/manager/focus/focus_view.h" 27 28 namespace OHOS::Ace::NG { 29 30 class PipelineContext; 31 32 template<typename ContainerType, typename... Args> 33 class ACE_EXPORT FocusCallbackManager : public virtual AceType { 34 DECLARE_ACE_TYPE(FocusCallbackManager, AceType); 35 36 public: 37 using ValueType = std::function<void(Args...)>; 38 FocusCallbackManager() = default; 39 ~FocusCallbackManager() override = default; 40 SetListener(int32_t key,const ValueType & callback)41 void SetListener(int32_t key, const ValueType& callback) 42 { 43 callbackContainer_.insert_or_assign(key, callback); 44 } 45 AddListener(const ValueType & callback)46 int32_t AddListener(const ValueType& callback) 47 { 48 if (callbackContainer_.size() == static_cast<size_t>(std::numeric_limits<int32_t>::max() - 1)) { 49 return -1; 50 } 51 int32_t handler = nextKey_; 52 callbackContainer_.emplace(handler, callback); 53 54 do { 55 nextKey_ = (nextKey_ == std::numeric_limits<int32_t>::max()) ? 0 : ++nextKey_; 56 } while (callbackContainer_.count(nextKey_) != 0); 57 return handler; 58 } 59 RemoveListener(int32_t key)60 void RemoveListener(int32_t key) 61 { 62 callbackContainer_.erase(key); 63 } 64 ClearListener()65 void ClearListener() 66 { 67 callbackContainer_.clear(); 68 } 69 NotifyListener(Args...args)70 void NotifyListener(Args... args) 71 { 72 for (const auto& [id, callback] : callbackContainer_) { 73 if (callback) { 74 callback(args...); 75 } 76 } 77 } 78 79 private: 80 ContainerType callbackContainer_; 81 int32_t nextKey_ { 0 }; 82 }; 83 84 using FocusViewMap = std::unordered_map<int32_t, std::pair<WeakPtr<FocusView>, std::list<WeakPtr<FocusView>>>>; 85 using RequestFocusCallback = std::function<void(NG::RequestFocusResult result)>; 86 using FocusHubScopeMap = std::unordered_map<std::string, std::pair<WeakPtr<FocusHub>, std::list<WeakPtr<FocusHub>>>>; 87 88 using FocusChangeCallback = 89 std::function<void(const WeakPtr<FocusHub>& last, const RefPtr<FocusHub>& current, FocusReason focusReason)>; 90 using FocusActiveChangeCallback = std::function<void(bool isFocusActive)>; 91 using IsFocusActiveUpdateEvent = std::function<void(bool isFocusActive)>; 92 93 using FocusChangeCallbackManager = FocusCallbackManager<std::map<int32_t, FocusChangeCallback>, const WeakPtr<FocusHub>, 94 const RefPtr<FocusHub>, FocusReason>; 95 using FocusActiveChangeCallbackManager = 96 FocusCallbackManager<std::unordered_map<int32_t, FocusActiveChangeCallback>, bool>; 97 using IsFocusActiveUpdateEventManager = FocusCallbackManager<std::map<int32_t, IsFocusActiveUpdateEvent>, bool>; 98 99 enum class FocusActiveReason : int32_t { 100 POINTER_EVENT = 0, 101 DEFAULT = 1, 102 USE_API = 2, 103 KEY_TAB = 3, 104 ACTIVE_MARK = 4, 105 JOYSTICK_DPAD = 5, 106 }; 107 108 enum class FocusViewStackState : int32_t { 109 IDLE = 0, 110 SHOW = 1, 111 CLOSE = 2, 112 }; 113 114 enum class KeyProcessingMode : int32_t { 115 FOCUS_NAVIGATION = 0, 116 ANCESTOR_EVENT = 1, 117 }; 118 119 #define DECLARE_FOCUS_CALLBACK_MANAGER(callbackName, callbackType, managerName, managerType) \ 120 public: \ 121 void Set##callbackName(int32_t key, const callbackType& callback) \ 122 { \ 123 if (!focusCallbacks_) { \ 124 focusCallbacks_ = MakeRefPtr<FocusCallbacks>(); \ 125 } \ 126 focusCallbacks_->managerName##_->SetListener(key, callback); \ 127 } \ 128 int32_t Add##callbackName(const callbackType& callback) \ 129 { \ 130 if (!focusCallbacks_) { \ 131 focusCallbacks_ = MakeRefPtr<FocusCallbacks>(); \ 132 } \ 133 return focusCallbacks_->managerName##_->AddListener(callback); \ 134 } \ 135 void Remove##callbackName(int32_t key) \ 136 { \ 137 if (focusCallbacks_) { \ 138 focusCallbacks_->managerName##_->RemoveListener(key); \ 139 } \ 140 } \ 141 void Clear##callbackName() \ 142 { \ 143 if (focusCallbacks_) { \ 144 focusCallbacks_->managerName##_->ClearListener(); \ 145 } \ 146 } \ 147 RefPtr<managerType> Get##callbackName##Manager() \ 148 { \ 149 if (focusCallbacks_) { \ 150 return focusCallbacks_->managerName##_; \ 151 } \ 152 return nullptr; \ 153 } 154 155 class FocusCallbacks : public virtual AceType { 156 DECLARE_ACE_TYPE(FocusCallbacks, AceType); 157 158 public: FocusCallbacks()159 FocusCallbacks() 160 { 161 focusActiveChangeCallbacks_ = MakeRefPtr<FocusActiveChangeCallbackManager>(); 162 focusChangeCallbacks_ = MakeRefPtr<FocusChangeCallbackManager>(); 163 isFocusActiveUpdateEvents_ = MakeRefPtr<IsFocusActiveUpdateEventManager>(); 164 } 165 ~FocusCallbacks() override = default; 166 167 RefPtr<FocusActiveChangeCallbackManager> focusActiveChangeCallbacks_; 168 RefPtr<FocusChangeCallbackManager> focusChangeCallbacks_; 169 RefPtr<IsFocusActiveUpdateEventManager> isFocusActiveUpdateEvents_; 170 }; 171 class FocusManager : public virtual AceType { 172 DECLARE_ACE_TYPE(FocusManager, AceType); 173 174 public: 175 class FocusGuard { 176 public: 177 explicit FocusGuard(const RefPtr<FocusHub>& focushub, SwitchingStartReason reason); 178 FocusGuard() = delete; 179 ~FocusGuard(); 180 void CreateFocusGuard(const RefPtr<FocusHub>& focushub, const RefPtr<FocusManager>& focusManager, 181 SwitchingStartReason reason); 182 private: 183 RefPtr<FocusManager> focusMng_; 184 }; 185 friend FocusGuard; 186 187 explicit FocusManager(const RefPtr<PipelineContext>& pipeline); 188 ~FocusManager() override = default; 189 190 void FocusViewShow(const RefPtr<FocusView>& focusView, bool isTriggerByStep = false); 191 void FocusViewHide(const RefPtr<FocusView>& focusView); 192 void FocusViewClose(const RefPtr<FocusView>& focusView, bool isDetachFromTree = false); 193 194 void FlushFocusView(); 195 196 void DumpFocusManager(); 197 GetLastFocusView()198 WeakPtr<FocusView> GetLastFocusView() const 199 { 200 return lastFocusView_; 201 } 202 GetWeakFocusViewList()203 const std::list<WeakPtr<FocusView>>& GetWeakFocusViewList() const 204 { 205 return focusViewStack_; 206 } 207 SetRequestFocusCallback(const RequestFocusCallback & callback)208 void SetRequestFocusCallback(const RequestFocusCallback& callback) 209 { 210 requestCallback_ = std::move(callback); 211 } 212 ResetRequestFocusCallback()213 void ResetRequestFocusCallback() 214 { 215 requestCallback_ = nullptr; 216 } 217 TriggerRequestFocusCallback(NG::RequestFocusResult result)218 void TriggerRequestFocusCallback(NG::RequestFocusResult result) 219 { 220 if (requestCallback_) { 221 requestCallback_(result); 222 requestCallback_ = nullptr; 223 } 224 } 225 SetRequestFocusResult(const int32_t requestFocusResult)226 void SetRequestFocusResult(const int32_t requestFocusResult) 227 { 228 requestFocusResult_ = requestFocusResult; 229 } 230 GetRequestFocusResult()231 int32_t GetRequestFocusResult() 232 { 233 return requestFocusResult_; 234 } 235 ResetRequestFocusResult()236 void ResetRequestFocusResult() 237 { 238 requestFocusResult_ = ERROR_CODE_NO_ERROR; 239 } 240 SetLastFocusStateNode(const RefPtr<FocusHub> & node)241 void SetLastFocusStateNode(const RefPtr<FocusHub>& node) 242 { 243 lastFocusStateNode_ = AceType::WeakClaim(AceType::RawPtr(node)); 244 if (isNeedTriggerScroll_.has_value()) { 245 isNeedTriggerScroll_ = true; 246 } 247 } GetLastFocusStateNode()248 RefPtr<FocusHub> GetLastFocusStateNode() const 249 { 250 return lastFocusStateNode_.Upgrade(); 251 } 252 SetNeedTriggerScroll(std::optional<bool> isNeedTriggerScroll)253 void SetNeedTriggerScroll(std::optional<bool> isNeedTriggerScroll) 254 { 255 isNeedTriggerScroll_ = isNeedTriggerScroll; 256 } 257 GetNeedTriggerScroll()258 bool GetNeedTriggerScroll() const 259 { 260 return isNeedTriggerScroll_.value_or(false); 261 } 262 SetIsAutoFocusTransfer(bool isAutoFocusTransfer)263 void SetIsAutoFocusTransfer(bool isAutoFocusTransfer) 264 { 265 isAutoFocusTransfer_ = isAutoFocusTransfer; 266 } 267 IsAutoFocusTransfer()268 bool IsAutoFocusTransfer() const 269 { 270 return isAutoFocusTransfer_; 271 } 272 273 bool RearrangeViewStack(); 274 SetFocusViewStackState(FocusViewStackState focusViewStackState)275 void SetFocusViewStackState(FocusViewStackState focusViewStackState) 276 { 277 focusViewStackState_ = focusViewStackState; 278 } 279 SetKeyProcessingMode(KeyProcessingMode keyProcessingMode)280 void SetKeyProcessingMode(KeyProcessingMode keyProcessingMode) 281 { 282 keyProcessingMode_ = keyProcessingMode; 283 } 284 GetKeyProcessingMode()285 KeyProcessingMode GetKeyProcessingMode() const 286 { 287 return keyProcessingMode_; 288 } 289 290 bool SetFocusViewRootScope(const RefPtr<FocusView>& focusView); 291 292 void PaintFocusState(); 293 294 bool AddFocusScope(const std::string& focusScopeId, const RefPtr<FocusHub>& scopeFocusHub); 295 void RemoveFocusScope(const std::string& focusScopeId); 296 void AddScopePriorityNode(const std::string& focusScopeId, const RefPtr<FocusHub>& priorFocusHub, bool pushFront); 297 void RemoveScopePriorityNode(const std::string& focusScopeId, const RefPtr<FocusHub>& priorFocusHub); 298 std::optional<std::list<WeakPtr<FocusHub>>*> GetFocusScopePriorityList(const std::string& focusScopeId); 299 300 void UpdateCurrentFocus(const RefPtr<FocusHub>& current, SwitchingUpdateReason reason); 301 RefPtr<FocusHub> GetCurrentFocus(); UpdateSwitchingEndReason(SwitchingEndReason reason)302 void UpdateSwitchingEndReason(SwitchingEndReason reason) 303 { 304 if (isSwitchingFocus_.value_or(false)) { 305 endReason_ = reason; 306 } 307 } 308 void TriggerAllFocusActiveChangeCallback(bool isFocusActive); 309 void FocusSwitchingStart(const RefPtr<FocusHub>& focusHub, SwitchingStartReason reason); 310 void FocusSwitchingEnd(SwitchingEndReason reason = SwitchingEndReason::FOCUS_GUARD_DESTROY); 311 void WindowFocusMoveStart(); 312 void WindowFocusMoveEnd(); 313 void WindowFocus(bool isFocus); GetCurrentFocusEvent()314 std::optional<FocusEvent> GetCurrentFocusEvent() 315 { 316 return currentFocusEvent_; 317 } 318 SetCurrentFocusEvent(const FocusEvent & event)319 void SetCurrentFocusEvent(const FocusEvent& event) 320 { 321 currentFocusEvent_.reset(); 322 currentFocusEvent_.emplace(event); 323 } 324 ResetCurrentFocusEvent()325 void ResetCurrentFocusEvent() 326 { 327 currentFocusEvent_.reset(); 328 } 329 330 static RefPtr<FocusManager> GetFocusManager(RefPtr<FrameNode>& node); 331 332 bool SetIsFocusActive( 333 bool isFocusActive, FocusActiveReason reason = FocusActiveReason::DEFAULT, bool autoFocusInactive = true); 334 bool SyncWindowsFocus( 335 bool isFocusActive, FocusActiveReason reason = FocusActiveReason::DEFAULT, bool autoFocusInactive = true); GetIsFocusActive()336 bool GetIsFocusActive() const 337 { 338 return isFocusActive_; 339 } 340 bool HandleKeyForExtendOrActivateFocus(const KeyEvent& event, const RefPtr<FocusView>& curFocusView); 341 bool ExtendOrActivateFocus( 342 const RefPtr<FocusView>& curFocusView, FocusActiveReason reason = FocusActiveReason::DEFAULT); 343 344 private: 345 void GetFocusViewMap(FocusViewMap& focusViewMap); 346 void ReportFocusSwitching(FocusReason focusReason); 347 bool NeedChangeFocusAvtive(bool isFocusActive, FocusActiveReason reason, bool autoFocusInactive); 348 349 std::list<WeakPtr<FocusView>> focusViewStack_; 350 WeakPtr<FocusView> lastFocusView_; 351 const WeakPtr<PipelineContext> pipeline_; 352 353 RequestFocusCallback requestCallback_; 354 355 WeakPtr<FocusHub> lastFocusStateNode_; 356 WeakPtr<FocusHub> currentFocus_; 357 /** 358 * In the case of a scrollable component's sliding state, this variable will be set to nullopt to prevent the 359 * ScrollBy animation triggered by FireFocusScroll from interrupting the sliding animation of the component. 360 * In the SetLastFocusStateNode method, this variable will not be set to true until it has value. 361 */ 362 std::optional<bool> isNeedTriggerScroll_ = false; 363 FocusHubScopeMap focusHubScopeMap_; 364 365 DECLARE_FOCUS_CALLBACK_MANAGER(FocusActiveChangeCallback, FocusActiveChangeCallback, focusActiveChangeCallbacks, 366 FocusActiveChangeCallbackManager); 367 DECLARE_FOCUS_CALLBACK_MANAGER( 368 FocusChangeCallback, FocusChangeCallback, focusChangeCallbacks, FocusChangeCallbackManager); 369 DECLARE_FOCUS_CALLBACK_MANAGER( 370 IsFocusActiveUpdateEvent, IsFocusActiveUpdateEvent, isFocusActiveUpdateEvents, IsFocusActiveUpdateEventManager); 371 RefPtr<FocusCallbacks> focusCallbacks_; 372 373 std::optional<bool> isSwitchingFocus_; 374 bool isSwitchingWindow_ = false; 375 RefPtr<FocusHub> switchingFocus_; 376 377 std::optional<SwitchingStartReason> startReason_; 378 std::optional<SwitchingEndReason> endReason_; 379 std::optional<SwitchingUpdateReason> updateReason_; 380 381 bool isAutoFocusTransfer_ = true; 382 bool isFocusActive_ = false; 383 bool autoFocusInactive_ = true; 384 FocusViewStackState focusViewStackState_ = FocusViewStackState::IDLE; 385 386 int32_t requestFocusResult_ = ERROR_CODE_NO_ERROR; 387 std::optional<FocusEvent> currentFocusEvent_; 388 KeyProcessingMode keyProcessingMode_ = KeyProcessingMode::FOCUS_NAVIGATION; 389 ACE_DISALLOW_COPY_AND_MOVE(FocusManager); 390 }; 391 } // namespace OHOS::Ace::NG 392 393 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FOCUS_FOCUS_MANAGER_H 394