Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: ash/common/devtools/ash_devtools_dom_agent.cc

Issue 2527573003: Refactor remove methods, add DCHECKS, and remove_observer boolean (Closed)
Patch Set: sadruls comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/common/devtools/ash_devtools_dom_agent.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/common/devtools/ash_devtools_dom_agent.h" 5 #include "ash/common/devtools/ash_devtools_dom_agent.h"
6 6
7 #include "ash/common/wm_lookup.h" 7 #include "ash/common/wm_lookup.h"
8 #include "ash/common/wm_window.h" 8 #include "ash/common/wm_window.h"
9 #include "components/ui_devtools/devtools_server.h" 9 #include "components/ui_devtools/devtools_server.h"
10 10
11 namespace ash { 11 namespace ash {
12 namespace devtools { 12 namespace devtools {
13 13
14 namespace { 14 namespace {
15 using namespace ui::devtools::protocol; 15 using namespace ui::devtools::protocol;
16 // TODO(mhashmi): Make ids reusable
16 DOM::NodeId node_ids = 1; 17 DOM::NodeId node_ids = 1;
17 18
18 std::unique_ptr<DOM::Node> BuildNode( 19 std::unique_ptr<DOM::Node> BuildNode(
19 const std::string& name, 20 const std::string& name,
20 std::unique_ptr<Array<std::string>> attributes, 21 std::unique_ptr<Array<std::string>> attributes,
21 std::unique_ptr<Array<DOM::Node>> children) { 22 std::unique_ptr<Array<DOM::Node>> children) {
22 constexpr int kDomElementNodeType = 1; 23 constexpr int kDomElementNodeType = 1;
23 std::unique_ptr<DOM::Node> node = DOM::Node::create() 24 std::unique_ptr<DOM::Node> node = DOM::Node::create()
24 .setNodeId(node_ids++) 25 .setNodeId(node_ids++)
25 .setNodeName(name) 26 .setNodeName(name)
(...skipping 23 matching lines...) Expand all
49 return attributes; 50 return attributes;
50 } 51 }
51 52
52 std::unique_ptr<Array<std::string>> GetAttributes(const views::View* view) { 53 std::unique_ptr<Array<std::string>> GetAttributes(const views::View* view) {
53 std::unique_ptr<Array<std::string>> attributes = Array<std::string>::create(); 54 std::unique_ptr<Array<std::string>> attributes = Array<std::string>::create();
54 attributes->addItem("name"); 55 attributes->addItem("name");
55 attributes->addItem(view->GetClassName()); 56 attributes->addItem(view->GetClassName());
56 return attributes; 57 return attributes;
57 } 58 }
58 59
59
60 WmWindow* FindPreviousSibling(WmWindow* window) { 60 WmWindow* FindPreviousSibling(WmWindow* window) {
61 std::vector<WmWindow*> siblings = window->GetParent()->GetChildren(); 61 std::vector<WmWindow*> siblings = window->GetParent()->GetChildren();
62 std::vector<WmWindow*>::iterator it = 62 std::vector<WmWindow*>::iterator it =
63 std::find(siblings.begin(), siblings.end(), window); 63 std::find(siblings.begin(), siblings.end(), window);
64 DCHECK(it != siblings.end()); 64 DCHECK(it != siblings.end());
65 // If this is the first child of its parent, the previous sibling is null 65 // If this is the first child of its parent, the previous sibling is null
66 return it == siblings.begin() ? nullptr : *std::prev(it); 66 return it == siblings.begin() ? nullptr : *std::prev(it);
67 } 67 }
68 68
69 } // namespace 69 } // namespace
(...skipping 21 matching lines...) Expand all
91 void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window, 91 void AshDevToolsDOMAgent::OnWindowTreeChanging(WmWindow* window,
92 const TreeChangeParams& params) { 92 const TreeChangeParams& params) {
93 // Only trigger this when window == params.old_parent. 93 // Only trigger this when window == params.old_parent.
94 // Only removals are handled here. Removing a node can occur as a result of 94 // Only removals are handled here. Removing a node can occur as a result of
95 // reorganizing a window or just destroying it. OnWindowTreeChanged 95 // reorganizing a window or just destroying it. OnWindowTreeChanged
96 // is only called if there is a new_parent. The only case this method isn't 96 // is only called if there is a new_parent. The only case this method isn't
97 // called is when adding a node because old_parent is then null. 97 // called is when adding a node because old_parent is then null.
98 // Finally, We only trigger this 0 or 1 times as an old_parent will 98 // Finally, We only trigger this 0 or 1 times as an old_parent will
99 // either exist and only call this callback once, or not at all. 99 // either exist and only call this callback once, or not at all.
100 if (window == params.old_parent) 100 if (window == params.old_parent)
101 RemoveWindowNode(params.target); 101 RemoveWindowTree(params.target, true);
102 } 102 }
103 103
104 // Handles adding windows. 104 // Handles adding windows.
105 void AshDevToolsDOMAgent::OnWindowTreeChanged(WmWindow* window, 105 void AshDevToolsDOMAgent::OnWindowTreeChanged(WmWindow* window,
106 const TreeChangeParams& params) { 106 const TreeChangeParams& params) {
107 // Only trigger this when window == params.new_parent. 107 // Only trigger this when window == params.new_parent.
108 // If there is an old_parent + new_parent, then this window's node was 108 // If there is an old_parent + new_parent, then this window's node was
109 // removed in OnWindowTreeChanging and will now be added to the new_parent. 109 // removed in OnWindowTreeChanging and will now be added to the new_parent.
110 // If there is only a new_parent, OnWindowTreeChanging is never called and 110 // If there is only a new_parent, OnWindowTreeChanging is never called and
111 // the window is only added here. 111 // the window is only added here.
112 if (window == params.new_parent) 112 if (window == params.new_parent)
113 AddWindowNode(params.target); 113 AddWindowTree(params.target);
114 } 114 }
115 115
116 void AshDevToolsDOMAgent::OnWindowStackingChanged(WmWindow* window) { 116 void AshDevToolsDOMAgent::OnWindowStackingChanged(WmWindow* window) {
117 RemoveWindowNode(window); 117 RemoveWindowTree(window, false);
118 AddWindowNode(window); 118 AddWindowTree(window);
119 } 119 }
120 120
121 WmWindow* AshDevToolsDOMAgent::GetWindowFromNodeId(int nodeId) { 121 WmWindow* AshDevToolsDOMAgent::GetWindowFromNodeId(int nodeId) {
122 return node_id_to_window_map_.count(nodeId) ? node_id_to_window_map_[nodeId] 122 return node_id_to_window_map_.count(nodeId) ? node_id_to_window_map_[nodeId]
123 : nullptr; 123 : nullptr;
124 } 124 }
125 125
126 views::Widget* AshDevToolsDOMAgent::GetWidgetFromNodeId(int nodeId) { 126 views::Widget* AshDevToolsDOMAgent::GetWidgetFromNodeId(int nodeId) {
127 return node_id_to_widget_map_.count(nodeId) ? node_id_to_widget_map_[nodeId] 127 return node_id_to_widget_map_.count(nodeId) ? node_id_to_widget_map_[nodeId]
128 : nullptr; 128 : nullptr;
(...skipping 12 matching lines...) Expand all
141 int AshDevToolsDOMAgent::GetNodeIdFromWidget(views::Widget* widget) { 141 int AshDevToolsDOMAgent::GetNodeIdFromWidget(views::Widget* widget) {
142 DCHECK(widget_to_node_id_map_.count(widget)); 142 DCHECK(widget_to_node_id_map_.count(widget));
143 return widget_to_node_id_map_[widget]; 143 return widget_to_node_id_map_[widget];
144 } 144 }
145 145
146 int AshDevToolsDOMAgent::GetNodeIdFromView(views::View* view) { 146 int AshDevToolsDOMAgent::GetNodeIdFromView(views::View* view) {
147 DCHECK(view_to_node_id_map_.count(view)); 147 DCHECK(view_to_node_id_map_.count(view));
148 return view_to_node_id_map_[view]; 148 return view_to_node_id_map_[view];
149 } 149 }
150 150
151 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForView( 151 std::unique_ptr<ui::devtools::protocol::DOM::Node>
152 views::View* view) { 152 AshDevToolsDOMAgent::BuildInitialTree() {
153 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); 153 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
154 for (int i = 0, count = view->child_count(); i < count; i++) { 154 for (ash::WmWindow* window : shell_->GetAllRootWindows())
155 children->addItem(BuildTreeForView(view->child_at(i))); 155 children->addItem(BuildTreeForWindow(window));
156 } 156 return BuildNode("root", nullptr, std::move(children));
157 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
158 BuildNode("View", GetAttributes(view), std::move(children));
159 view_to_node_id_map_[view] = node->getNodeId();
160 node_id_to_view_map_[node->getNodeId()] = view;
161 return node;
162 }
163
164 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForRootWidget(
165 views::Widget* widget) {
166 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
167 children->addItem(BuildTreeForView(widget->GetRootView()));
168 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
169 BuildNode("Widget", GetAttributes(widget), std::move(children));
170 widget_to_node_id_map_[widget] = node->getNodeId();
171 node_id_to_widget_map_[node->getNodeId()] = widget;
172 return node;
173 } 157 }
174 158
175 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow( 159 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForWindow(
176 ash::WmWindow* window) { 160 ash::WmWindow* window) {
161 DCHECK(!window_to_node_id_map_.count(window));
177 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); 162 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
178 views::Widget* widget = window->GetInternalWidget(); 163 views::Widget* widget = window->GetInternalWidget();
179 if (widget) 164 if (widget)
180 children->addItem(BuildTreeForRootWidget(widget)); 165 children->addItem(BuildTreeForRootWidget(widget));
181 for (ash::WmWindow* child : window->GetChildren()) { 166 for (ash::WmWindow* child : window->GetChildren())
182 children->addItem(BuildTreeForWindow(child)); 167 children->addItem(BuildTreeForWindow(child));
183 } 168
184 std::unique_ptr<ui::devtools::protocol::DOM::Node> node = 169 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
185 BuildNode("Window", GetAttributes(window), std::move(children)); 170 BuildNode("Window", GetAttributes(window), std::move(children));
186 // Only add as observer if window is not in map 171 if (!window->HasObserver(this))
187 if (!window_to_node_id_map_.count(window))
188 window->AddObserver(this); 172 window->AddObserver(this);
189 window_to_node_id_map_[window] = node->getNodeId(); 173 window_to_node_id_map_[window] = node->getNodeId();
190 node_id_to_window_map_[node->getNodeId()] = window; 174 node_id_to_window_map_[node->getNodeId()] = window;
191 return node; 175 return node;
192 } 176 }
193 177
194 std::unique_ptr<ui::devtools::protocol::DOM::Node> 178 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForRootWidget(
195 AshDevToolsDOMAgent::BuildInitialTree() { 179 views::Widget* widget) {
180 DCHECK(!widget_to_node_id_map_.count(widget));
196 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); 181 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
197 for (ash::WmWindow* window : shell_->GetAllRootWindows()) { 182 children->addItem(BuildTreeForView(widget->GetRootView()));
198 children->addItem(BuildTreeForWindow(window)); 183 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
199 } 184 BuildNode("Widget", GetAttributes(widget), std::move(children));
200 return BuildNode("root", nullptr, std::move(children)); 185 // TODO(mhashmi): Add WidgetRemovalsObserver here
186 widget_to_node_id_map_[widget] = node->getNodeId();
187 node_id_to_widget_map_[node->getNodeId()] = widget;
188 return node;
201 } 189 }
202 190
203 void AshDevToolsDOMAgent::AddWindowNode(WmWindow* window) { 191 std::unique_ptr<DOM::Node> AshDevToolsDOMAgent::BuildTreeForView(
192 views::View* view) {
193 DCHECK(!view_to_node_id_map_.count(view));
194 std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
195 for (int i = 0, count = view->child_count(); i < count; i++)
196 children->addItem(BuildTreeForView(view->child_at(i)));
197 std::unique_ptr<ui::devtools::protocol::DOM::Node> node =
198 BuildNode("View", GetAttributes(view), std::move(children));
199 // TODO(mhashmi): Add ViewObserver here
200 view_to_node_id_map_[view] = node->getNodeId();
201 node_id_to_view_map_[node->getNodeId()] = view;
202 return node;
203 }
204
205 void AshDevToolsDOMAgent::AddWindowTree(WmWindow* window) {
204 DCHECK(window_to_node_id_map_.count(window->GetParent())); 206 DCHECK(window_to_node_id_map_.count(window->GetParent()));
205 WmWindow* prev_sibling = FindPreviousSibling(window); 207 WmWindow* prev_sibling = FindPreviousSibling(window);
206 frontend()->childNodeInserted( 208 frontend()->childNodeInserted(
207 window_to_node_id_map_[window->GetParent()], 209 window_to_node_id_map_[window->GetParent()],
208 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0, 210 prev_sibling ? window_to_node_id_map_[prev_sibling] : 0,
209 BuildTreeForWindow(window)); 211 BuildTreeForWindow(window));
210 } 212 }
211 213
212 void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window) { 214 void AshDevToolsDOMAgent::RemoveWindowTree(WmWindow* window,
213 WmWindow* parent = window->GetParent(); 215 bool remove_observer) {
214 DCHECK(parent); 216 DCHECK(window);
217 if (window->GetInternalWidget())
218 RemoveWidgetTree(window->GetInternalWidget(), remove_observer);
219
220 for (ash::WmWindow* child : window->GetChildren())
221 RemoveWindowTree(child, remove_observer);
222
223 RemoveWindowNode(window, remove_observer);
224 }
225
226 void AshDevToolsDOMAgent::RemoveWindowNode(WmWindow* window,
227 bool remove_observer) {
215 WindowToNodeIdMap::iterator window_to_node_id_it = 228 WindowToNodeIdMap::iterator window_to_node_id_it =
216 window_to_node_id_map_.find(window); 229 window_to_node_id_map_.find(window);
217 DCHECK(window_to_node_id_it != window_to_node_id_map_.end()); 230 DCHECK(window_to_node_id_it != window_to_node_id_map_.end());
218 231
219 int node_id = window_to_node_id_it->second; 232 int node_id = window_to_node_id_it->second;
220 int parent_id = GetNodeIdFromWindow(parent); 233 int parent_id = GetNodeIdFromWindow(window->GetParent());
221 234
222 NodeIdToWindowMap::iterator node_id_to_window_it = 235 NodeIdToWindowMap::iterator node_id_to_window_it =
223 node_id_to_window_map_.find(node_id); 236 node_id_to_window_map_.find(node_id);
224 DCHECK(node_id_to_window_it != node_id_to_window_map_.end()); 237 DCHECK(node_id_to_window_it != node_id_to_window_map_.end());
225 238
226 views::Widget* widget = window->GetInternalWidget(); 239 if (remove_observer)
227 if (widget) 240 window->RemoveObserver(this);
228 RemoveWidgetNode(widget);
229
230 window->RemoveObserver(this);
231 node_id_to_window_map_.erase(node_id_to_window_it); 241 node_id_to_window_map_.erase(node_id_to_window_it);
232 window_to_node_id_map_.erase(window_to_node_id_it); 242 window_to_node_id_map_.erase(window_to_node_id_it);
233 frontend()->childNodeRemoved(parent_id, node_id); 243 frontend()->childNodeRemoved(parent_id, node_id);
234 } 244 }
235 245
236 void AshDevToolsDOMAgent::RemoveWidgetNode(views::Widget* widget) { 246 void AshDevToolsDOMAgent::RemoveWidgetTree(views::Widget* widget,
247 bool remove_observer) {
248 DCHECK(widget);
249 if (widget->GetRootView())
250 RemoveViewTree(widget->GetRootView(), nullptr, remove_observer);
251 RemoveWidgetNode(widget, remove_observer);
252 }
253
254 void AshDevToolsDOMAgent::RemoveWidgetNode(views::Widget* widget,
255 bool remove_observer) {
237 WidgetToNodeIdMap::iterator widget_to_node_id_it = 256 WidgetToNodeIdMap::iterator widget_to_node_id_it =
238 widget_to_node_id_map_.find(widget); 257 widget_to_node_id_map_.find(widget);
239 DCHECK(widget_to_node_id_it != widget_to_node_id_map_.end()); 258 DCHECK(widget_to_node_id_it != widget_to_node_id_map_.end());
240 259
241 int node_id = widget_to_node_id_it->second; 260 int node_id = widget_to_node_id_it->second;
242 int parent_id = 261 int parent_id =
243 GetNodeIdFromWindow(WmLookup::Get()->GetWindowForWidget(widget)); 262 GetNodeIdFromWindow(WmLookup::Get()->GetWindowForWidget(widget));
244 263
245 RemoveViewNode(widget->GetRootView()); 264 // TODO(mhashmi): Add WidgetRemovalsObserver and remove it here based on
265 // |remove_observer|
246 266
247 NodeIdToWidgetMap::iterator node_id_to_widget_it = 267 NodeIdToWidgetMap::iterator node_id_to_widget_it =
248 node_id_to_widget_map_.find(node_id); 268 node_id_to_widget_map_.find(node_id);
249 DCHECK(node_id_to_widget_it != node_id_to_widget_map_.end()); 269 DCHECK(node_id_to_widget_it != node_id_to_widget_map_.end());
250 270
251 widget_to_node_id_map_.erase(widget_to_node_id_it); 271 widget_to_node_id_map_.erase(widget_to_node_id_it);
252 node_id_to_widget_map_.erase(node_id_to_widget_it); 272 node_id_to_widget_map_.erase(node_id_to_widget_it);
253 frontend()->childNodeRemoved(parent_id, node_id); 273 frontend()->childNodeRemoved(parent_id, node_id);
254 } 274 }
255 275
256 void AshDevToolsDOMAgent::RemoveViewNode(views::View* view) { 276 void AshDevToolsDOMAgent::RemoveViewTree(views::View* view,
257 // TODO(mhashmi): Add observers to views/widgets so new views exist 277 views::View* parent,
258 // in the map and can be removed here 278 bool remove_observer) {
279 DCHECK(view);
280 for (int i = 0, count = view->child_count(); i < count; i++)
281 RemoveViewTree(view->child_at(i), view, remove_observer);
282 RemoveViewNode(view, parent, remove_observer);
283 }
284
285 void AshDevToolsDOMAgent::RemoveViewNode(views::View* view,
286 views::View* parent,
287 bool remove_observer) {
288 ViewToNodeIdMap::iterator view_to_node_id_it =
289 view_to_node_id_map_.find(view);
290 DCHECK(view_to_node_id_it != view_to_node_id_map_.end());
291
292 int node_id = view_to_node_id_it->second;
293 int parent_id = 0;
294 if (parent)
295 parent_id = GetNodeIdFromView(parent);
296 else // views::RootView
297 parent_id = GetNodeIdFromWidget(view->GetWidget());
298
299 // TODO(mhashmi): Add ViewObserver and remove it here based on
300 // |remove_observer|
301
302 NodeIdToViewMap::iterator node_id_to_view_it =
303 node_id_to_view_map_.find(node_id);
304 DCHECK(node_id_to_view_it != node_id_to_view_map_.end());
305
306 view_to_node_id_map_.erase(view_to_node_id_it);
307 node_id_to_view_map_.erase(node_id_to_view_it);
308 frontend()->childNodeRemoved(parent_id, node_id);
259 } 309 }
260 310
261 void AshDevToolsDOMAgent::RemoveObserverFromAllWindows() { 311 void AshDevToolsDOMAgent::RemoveObserverFromAllWindows() {
262 for (auto& pair : window_to_node_id_map_) 312 for (auto& pair : window_to_node_id_map_)
263 pair.first->RemoveObserver(this); 313 pair.first->RemoveObserver(this);
264 } 314 }
265 315
266 void AshDevToolsDOMAgent::Reset() { 316 void AshDevToolsDOMAgent::Reset() {
267 RemoveObserverFromAllWindows(); 317 RemoveObserverFromAllWindows();
268 window_to_node_id_map_.clear(); 318 window_to_node_id_map_.clear();
269 widget_to_node_id_map_.clear(); 319 widget_to_node_id_map_.clear();
270 view_to_node_id_map_.clear(); 320 view_to_node_id_map_.clear();
271 node_id_to_window_map_.clear(); 321 node_id_to_window_map_.clear();
272 node_id_to_widget_map_.clear(); 322 node_id_to_widget_map_.clear();
273 node_id_to_view_map_.clear(); 323 node_id_to_view_map_.clear();
274 node_ids = 1; 324 node_ids = 1;
275 } 325 }
276 326
277 } // namespace devtools 327 } // namespace devtools
278 } // namespace ash 328 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/devtools/ash_devtools_dom_agent.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698