1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_VIEWS_ACCESSIBILITY_AX_AURA_OBJ_CACHE_H_ 6 #define UI_VIEWS_ACCESSIBILITY_AX_AURA_OBJ_CACHE_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 #include <set> 13 #include <vector> 14 15 #include "ui/accessibility/ax_enums.mojom-forward.h" 16 #include "ui/aura/client/focus_change_observer.h" 17 #include "ui/views/views_export.h" 18 19 namespace base { 20 template <typename T> 21 class NoDestructor; 22 } // namespace base 23 24 namespace aura { 25 class Window; 26 } // namespace aura 27 28 namespace views { 29 class AXAuraObjWrapper; 30 class View; 31 class Widget; 32 33 // A cache responsible for assigning id's to a set of interesting Aura views. 34 class VIEWS_EXPORT AXAuraObjCache : public aura::client::FocusChangeObserver { 35 public: 36 AXAuraObjCache(); 37 AXAuraObjCache(const AXAuraObjCache&) = delete; 38 AXAuraObjCache& operator=(const AXAuraObjCache&) = delete; 39 ~AXAuraObjCache() override; 40 41 class Delegate { 42 public: 43 virtual ~Delegate() = default; 44 45 virtual void OnChildWindowRemoved(AXAuraObjWrapper* parent) = 0; 46 virtual void OnEvent(AXAuraObjWrapper* aura_obj, 47 ax::mojom::Event event_type) = 0; 48 }; 49 50 // Get or create an entry in the cache. May return null if the View is not 51 // associated with a Widget. 52 AXAuraObjWrapper* GetOrCreate(View* view); 53 54 // Get or create an entry in the cache. 55 AXAuraObjWrapper* GetOrCreate(Widget* widget); 56 AXAuraObjWrapper* GetOrCreate(aura::Window* window); 57 58 // Creates an entry in this cache given a wrapper object. Use this method when 59 // creating a wrapper not backed by any of the supported views above. This 60 // cache will take ownership. Will replace an existing entry with the same id. 61 void CreateOrReplace(std::unique_ptr<AXAuraObjWrapper> obj); 62 63 // Gets an id given an Aura view. 64 int32_t GetID(View* view) const; 65 int32_t GetID(Widget* widget) const; 66 int32_t GetID(aura::Window* window) const; 67 68 // Removes an entry from this cache based on an Aura view. 69 void Remove(View* view); 70 void Remove(Widget* widget); 71 72 // Removes |window| and optionally notifies delegate by sending an event on 73 // the |parent| if provided. 74 void Remove(aura::Window* window, aura::Window* parent); 75 76 // Removes a view and all of its descendants from the cache. 77 void RemoveViewSubtree(View* view); 78 79 // Lookup a cached entry based on an id. 80 AXAuraObjWrapper* Get(int32_t id); 81 82 // Get all top level windows this cache knows about. Under classic ash and 83 // SingleProcessMash this is a list of per-display root windows. 84 void GetTopLevelWindows(std::vector<AXAuraObjWrapper*>* children); 85 86 // Get the object that has focus. 87 AXAuraObjWrapper* GetFocus(); 88 89 // Send a notification that the focused view may have changed. 90 void OnFocusedViewChanged(); 91 92 // Tell our delegate to fire an event on a given object. 93 void FireEvent(AXAuraObjWrapper* aura_obj, ax::mojom::Event event_type); 94 95 // Notifies this cache of a change in root window. 96 void OnRootWindowObjCreated(aura::Window* window); 97 98 // Notifies this cache of a change in root window. 99 void OnRootWindowObjDestroyed(aura::Window* window); 100 SetDelegate(Delegate * delegate)101 void SetDelegate(Delegate* delegate) { delegate_ = delegate; } 102 103 // Changes the behavior of GetFocusedView() so that it only considers 104 // views within the given Widget, this enables making tests 105 // involving focus reliable. set_focused_widget_for_testing(views::Widget * widget)106 void set_focused_widget_for_testing(views::Widget* widget) { 107 focused_widget_for_testing_ = widget; 108 } 109 110 private: 111 friend class base::NoDestructor<AXAuraObjCache>; 112 113 View* GetFocusedView(); 114 115 // aura::client::FocusChangeObserver override. 116 void OnWindowFocused(aura::Window* gained_focus, 117 aura::Window* lost_focus) override; 118 119 template <typename AuraViewWrapper, typename AuraView> 120 AXAuraObjWrapper* CreateInternal( 121 AuraView* aura_view, 122 std::map<AuraView*, int32_t>* aura_view_to_id_map); 123 124 template <typename AuraView> 125 int32_t GetIDInternal( 126 AuraView* aura_view, 127 const std::map<AuraView*, int32_t>& aura_view_to_id_map) const; 128 129 template <typename AuraView> 130 void RemoveInternal(AuraView* aura_view, 131 std::map<AuraView*, int32_t>* aura_view_to_id_map); 132 133 std::map<views::View*, int32_t> view_to_id_map_; 134 std::map<views::Widget*, int32_t> widget_to_id_map_; 135 std::map<aura::Window*, int32_t> window_to_id_map_; 136 137 std::map<int32_t, std::unique_ptr<AXAuraObjWrapper>> cache_; 138 139 Delegate* delegate_ = nullptr; 140 141 std::set<aura::Window*> root_windows_; 142 143 views::Widget* focused_widget_for_testing_ = nullptr; 144 }; 145 146 } // namespace views 147 148 #endif // UI_VIEWS_ACCESSIBILITY_AX_AURA_OBJ_CACHE_H_ 149