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

Side by Side Diff: chrome/browser/devtools/chrome_devtools_manager_delegate.cc

Issue 2734123004: add a new set of commands to resize and position windows (Closed)
Patch Set: fix all tests Created 3 years, 8 months 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "chrome/browser/devtools/chrome_devtools_manager_delegate.h" 5 #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h"
6 6
7 #include <utility>
8
7 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
8 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
9 #include "build/build_config.h" 11 #include "build/build_config.h"
10 #include "chrome/browser/devtools/device/android_device_manager.h" 12 #include "chrome/browser/devtools/device/android_device_manager.h"
11 #include "chrome/browser/devtools/device/tcp_device_provider.h" 13 #include "chrome/browser/devtools/device/tcp_device_provider.h"
12 #include "chrome/browser/devtools/devtools_network_protocol_handler.h" 14 #include "chrome/browser/devtools/devtools_network_protocol_handler.h"
13 #include "chrome/browser/devtools/devtools_protocol_constants.h" 15 #include "chrome/browser/devtools/devtools_protocol_constants.h"
14 #include "chrome/browser/devtools/devtools_window.h" 16 #include "chrome/browser/devtools/devtools_window.h"
15 #include "chrome/browser/extensions/extension_tab_util.h" 17 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/profiles/profile_manager.h" 19 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/ui/browser_navigator.h" 20 #include "chrome/browser/ui/browser_navigator.h"
19 #include "chrome/browser/ui/browser_navigator_params.h" 21 #include "chrome/browser/ui/browser_navigator_params.h"
22 #include "chrome/browser/ui/browser_window.h"
23 #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
20 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 24 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/grit/browser_resources.h" 26 #include "chrome/grit/browser_resources.h"
22 #include "components/guest_view/browser/guest_view_base.h" 27 #include "components/guest_view/browser/guest_view_base.h"
23 #include "content/public/browser/devtools_agent_host.h" 28 #include "content/public/browser/devtools_agent_host.h"
24 #include "content/public/browser/render_frame_host.h" 29 #include "content/public/browser/render_frame_host.h"
25 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
26 #include "extensions/browser/extension_host.h" 31 #include "extensions/browser/extension_host.h"
27 #include "extensions/browser/extension_registry.h" 32 #include "extensions/browser/extension_registry.h"
28 #include "extensions/browser/process_manager.h" 33 #include "extensions/browser/process_manager.h"
29 #include "ui/base/resource/resource_bundle.h" 34 #include "ui/base/resource/resource_bundle.h"
30 35
31 using content::DevToolsAgentHost; 36 using content::DevToolsAgentHost;
32 37
33 char ChromeDevToolsManagerDelegate::kTypeApp[] = "app"; 38 char ChromeDevToolsManagerDelegate::kTypeApp[] = "app";
34 char ChromeDevToolsManagerDelegate::kTypeBackgroundPage[] = "background_page"; 39 char ChromeDevToolsManagerDelegate::kTypeBackgroundPage[] = "background_page";
35 char ChromeDevToolsManagerDelegate::kTypeWebView[] = "webview"; 40 char ChromeDevToolsManagerDelegate::kTypeWebView[] = "webview";
36 41
37 char kLocationsParam[] = "locations"; 42 char kLocationsParam[] = "locations";
38 char kHostParam[] = "host"; 43 char kHostParam[] = "host";
39 char kPortParam[] = "port"; 44 char kPortParam[] = "port";
40 45
46 namespace {
47
48 BrowserWindow* GetBrowserWindow(int window_id) {
49 for (auto* b : *BrowserList::GetInstance()) {
50 if (b->session_id().id() == window_id)
51 return b->window();
52 }
53 return nullptr;
54 }
55
56 // Get the bounds and state of the browser window. The bounds is for the
57 // restored window when the window is minimized. Otherwise, it is for the actual
58 // window.
59 std::unique_ptr<base::DictionaryValue> GetBounds(BrowserWindow* window) {
60 gfx::Rect bounds;
61 if (window->IsMinimized())
62 bounds = window->GetRestoredBounds();
63 else
64 bounds = window->GetBounds();
65
66 auto bounds_object = base::MakeUnique<base::DictionaryValue>();
67
68 bounds_object->SetInteger("left", bounds.x());
69 bounds_object->SetInteger("top", bounds.y());
70 bounds_object->SetInteger("width", bounds.width());
71 bounds_object->SetInteger("height", bounds.height());
72
73 std::string window_state = "normal";
74 if (window->IsMinimized())
75 window_state = "minimized";
76 if (window->IsMaximized())
77 window_state = "maximized";
78 if (window->IsFullscreen())
79 window_state = "fullscreen";
80 bounds_object->SetString("windowState", window_state);
81
82 return bounds_object;
83 }
84
85 // Encapsulates waiting for the browser window to change state, then perform
86 // Maximize. For example, on Mac, window->Maximize is ignored when the browser
87 // window is exiting fullscreen.
88 void Maximize(BrowserWindow* window, int retry_attempts) {
89 if (window->IsMaximized() || retry_attempts <= 0)
dgozman 2017/04/05 17:57:23 Retrying is a bad practice. Let's ask for help fro
jzfeng 2017/04/06 01:36:13 Sure, will do. Windows also has such problem, if E
90 return;
91 window->Maximize();
92 content::BrowserThread::PostDelayedTask(
93 content::BrowserThread::UI, FROM_HERE,
94 base::Bind(&Maximize, window, retry_attempts - 1),
95 base::TimeDelta::FromMilliseconds(100));
96 }
97
98 // Encapsulates waiting for the browser window to change state, then perform
99 // Minimize. For example, on Mac, window->Minimize is ignored when the browser
100 // window is exiting fullscreen.
101 void Minimize(BrowserWindow* window, int retry_attempts) {
102 if (window->IsMinimized() || retry_attempts <= 0)
103 return;
104 window->Minimize();
105 content::BrowserThread::PostDelayedTask(
106 content::BrowserThread::UI, FROM_HERE,
107 base::Bind(&Minimize, window, retry_attempts - 1),
108 base::TimeDelta::FromMilliseconds(100));
109 }
110
111 // Encapsulates waiting for the browser window to change state, then perform
112 // SetBounds. For example, on Mac and Windows, window->SetBounds is ignored when
113 // the browser window is exiting fullscreen.
114 void SetBounds(BrowserWindow* window, gfx::Rect bounds, int retry_attempts) {
115 if (window->GetBounds() == bounds || retry_attempts <= 0)
116 return;
117 window->SetBounds(bounds);
118 content::BrowserThread::PostDelayedTask(
119 content::BrowserThread::UI, FROM_HERE,
120 base::Bind(&SetBounds, window, bounds, retry_attempts - 1),
121 base::TimeDelta::FromMilliseconds(100));
122 }
123
124 } // namespace
125
126 // static
127 std::unique_ptr<base::DictionaryValue>
128 ChromeDevToolsManagerDelegate::GetWindowForTarget(
129 int id,
130 base::DictionaryValue* params) {
131 std::string target_id;
132 if (!params->GetString("targetId", &target_id))
133 return DevToolsProtocol::CreateInvalidParamsResponse(id, "targetId");
134
135 Browser* browser = nullptr;
136 scoped_refptr<DevToolsAgentHost> host =
137 DevToolsAgentHost::GetForId(target_id);
138 if (!host)
139 return DevToolsProtocol::CreateErrorResponse(id, "No target with given id");
140 content::WebContents* web_contents = host->GetWebContents();
141 if (!web_contents) {
142 return DevToolsProtocol::CreateErrorResponse(
143 id, "No web contents in the target");
144 }
145 for (auto* b : *BrowserList::GetInstance()) {
146 int tab_index = b->tab_strip_model()->GetIndexOfWebContents(web_contents);
147 if (tab_index != TabStripModel::kNoTab)
148 browser = b;
149 }
150 if (!browser) {
151 return DevToolsProtocol::CreateErrorResponse(id,
152 "Browser window not found");
153 }
154
155 auto result = base::MakeUnique<base::DictionaryValue>();
156 result->SetInteger("windowId", browser->session_id().id());
157 result->Set("bounds", GetBounds(browser->window()));
158 return DevToolsProtocol::CreateSuccessResponse(id, std::move(result));
159 }
160
161 // static
162 std::unique_ptr<base::DictionaryValue>
163 ChromeDevToolsManagerDelegate::GetWindowBounds(int id,
164 base::DictionaryValue* params) {
165 int window_id;
166 if (!params->GetInteger("windowId", &window_id))
167 return DevToolsProtocol::CreateInvalidParamsResponse(id, "windowId");
168 BrowserWindow* window = GetBrowserWindow(window_id);
169 if (!window) {
170 return DevToolsProtocol::CreateErrorResponse(id,
171 "Browser window not found");
172 }
173
174 auto result = base::MakeUnique<base::DictionaryValue>();
175 result->Set("bounds", GetBounds(window));
176 return DevToolsProtocol::CreateSuccessResponse(id, std::move(result));
177 }
178
179 // static
180 std::unique_ptr<base::DictionaryValue>
181 ChromeDevToolsManagerDelegate::SetWindowBounds(int id,
182 base::DictionaryValue* params) {
183 int window_id;
184 if (!params->GetInteger("windowId", &window_id))
185 return DevToolsProtocol::CreateInvalidParamsResponse(id, "windowId");
186 BrowserWindow* window = GetBrowserWindow(window_id);
187 if (!window) {
188 return DevToolsProtocol::CreateErrorResponse(id,
189 "Browser window not found");
190 }
191
192 const base::Value* value = nullptr;
193 const base::DictionaryValue* bounds_dict = nullptr;
194 if (!params->Get("bounds", &value) || !value->GetAsDictionary(&bounds_dict))
195 return DevToolsProtocol::CreateInvalidParamsResponse(id, "bounds");
196
197 // Get the bounds before manipulating window state for safe.
198 gfx::Rect bounds;
199 if (window->IsMinimized() || window->IsMaximized() || window->IsFullscreen())
200 bounds = window->GetRestoredBounds();
201 else
202 bounds = window->GetBounds();
203
204 std::string window_state;
205 if (!bounds_dict->GetString("windowState", &window_state))
206 window_state = "normal";
207 else if (window_state != "normal" && window_state != "minimized" &&
208 window_state != "maximized" && window_state != "fullscreen")
209 return DevToolsProtocol::CreateInvalidParamsResponse(id, "windowState");
210
211 if (window_state != "fullscreen" && window->IsFullscreen())
212 window->GetExclusiveAccessContext()->ExitFullscreen();
213 if (window_state != "minimized" && window->IsMinimized())
214 window->Show();
215
216 const int max_retry_attempts = 10;
217 if (window_state == "minimized") {
218 Minimize(window, max_retry_attempts);
219 } else if (window_state == "maximized") {
220 Maximize(window, max_retry_attempts);
221 } else if (window_state == "fullscreen") {
222 window->GetExclusiveAccessContext()->EnterFullscreen(
223 GURL(), EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE);
224 } else if (window->IsMaximized() || window->IsMinimized()) {
225 window->Restore();
226 #if defined(OS_MACOSX)
227 // GetRestoredBounds behave differently on Mac. Get the actual restored
dgozman 2017/04/05 17:57:23 What's the difference? Let's ask someone from chro
jzfeng 2017/04/06 01:36:13 In mac, GetRestoredBounds is always exactly the sa
228 // bounds here.
229 bounds = window->GetBounds();
230 #endif
231 }
232
233 // Compute updated bounds when window state is normal.
234 bool set_bounds = false;
235 int left, top, width, height;
236 if (bounds_dict->GetInteger("left", &left)) {
237 bounds.set_x(left);
238 set_bounds = true;
239 }
240 if (bounds_dict->GetInteger("top", &top)) {
241 bounds.set_y(top);
242 set_bounds = true;
243 }
244 if (bounds_dict->GetInteger("width", &width)) {
245 if (width < 0)
246 return DevToolsProtocol::CreateInvalidParamsResponse(id, "width");
247 bounds.set_width(width);
248 set_bounds = true;
249 }
250 if (bounds_dict->GetInteger("height", &height)) {
251 if (height < 0)
252 return DevToolsProtocol::CreateInvalidParamsResponse(id, "height");
253 bounds.set_height(height);
254 set_bounds = true;
255 }
256
257 if (set_bounds && window_state != "normal") {
258 return DevToolsProtocol::CreateErrorResponse(
259 id,
260 "The 'minimized', 'maximized' and 'fullscreen' states cannot be "
261 "combined with 'left', 'top', 'width' or 'height'");
262 }
263
264 if (set_bounds)
265 SetBounds(window, bounds, max_retry_attempts);
266
267 return DevToolsProtocol::CreateSuccessResponse(id, nullptr);
268 }
269
270 std::unique_ptr<base::DictionaryValue>
271 ChromeDevToolsManagerDelegate::HandleBrowserCommand(
272 int id,
273 std::string method,
274 base::DictionaryValue* params) {
275 if (method == chrome::devtools::Browser::getWindowForTarget::kName)
276 return GetWindowForTarget(id, params);
277 if (method == chrome::devtools::Browser::getWindowBounds::kName)
278 return GetWindowBounds(id, params);
279 if (method == chrome::devtools::Browser::setWindowBounds::kName)
280 return SetWindowBounds(id, params);
281 return nullptr;
282 }
283
41 class ChromeDevToolsManagerDelegate::HostData { 284 class ChromeDevToolsManagerDelegate::HostData {
42 public: 285 public:
43 HostData() {} 286 HostData() {}
44 ~HostData() {} 287 ~HostData() {}
45 288
46 RemoteLocations& remote_locations() { return remote_locations_; } 289 RemoteLocations& remote_locations() { return remote_locations_; }
47 290
48 void set_remote_locations(RemoteLocations& locations) { 291 void set_remote_locations(RemoteLocations& locations) {
49 remote_locations_.swap(locations); 292 remote_locations_.swap(locations);
50 } 293 }
(...skipping 19 matching lines...) Expand all
70 base::DictionaryValue* ChromeDevToolsManagerDelegate::HandleCommand( 313 base::DictionaryValue* ChromeDevToolsManagerDelegate::HandleCommand(
71 DevToolsAgentHost* agent_host, 314 DevToolsAgentHost* agent_host,
72 base::DictionaryValue* command_dict) { 315 base::DictionaryValue* command_dict) {
73 316
74 int id = 0; 317 int id = 0;
75 std::string method; 318 std::string method;
76 base::DictionaryValue* params = nullptr; 319 base::DictionaryValue* params = nullptr;
77 if (!DevToolsProtocol::ParseCommand(command_dict, &id, &method, &params)) 320 if (!DevToolsProtocol::ParseCommand(command_dict, &id, &method, &params))
78 return nullptr; 321 return nullptr;
79 322
323 if (agent_host->GetType() == DevToolsAgentHost::kTypeBrowser &&
324 method.find("Browser.") == 0)
325 return HandleBrowserCommand(id, method, params).release();
326
80 if (method == chrome::devtools::Target::setRemoteLocations::kName) 327 if (method == chrome::devtools::Target::setRemoteLocations::kName)
81 return SetRemoteLocations(agent_host, id, params).release(); 328 return SetRemoteLocations(agent_host, id, params).release();
82 329
83 return network_protocol_handler_->HandleCommand(agent_host, command_dict); 330 return network_protocol_handler_->HandleCommand(agent_host, command_dict);
84 } 331 }
85 332
86 std::string ChromeDevToolsManagerDelegate::GetTargetType( 333 std::string ChromeDevToolsManagerDelegate::GetTargetType(
87 content::RenderFrameHost* host) { 334 content::RenderFrameHost* host) {
88 content::WebContents* web_contents = 335 content::WebContents* web_contents =
89 content::WebContents::FromRenderFrameHost(host); 336 content::WebContents::FromRenderFrameHost(host);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 if (!dictionary->GetIntegerWithoutPathExpansion(kPortParam, &port)) { 516 if (!dictionary->GetIntegerWithoutPathExpansion(kPortParam, &port)) {
270 return DevToolsProtocol::CreateInvalidParamsResponse(command_id, 517 return DevToolsProtocol::CreateInvalidParamsResponse(command_id,
271 kLocationsParam); 518 kLocationsParam);
272 } 519 }
273 tcp_locations.insert(net::HostPortPair(host, port)); 520 tcp_locations.insert(net::HostPortPair(host, port));
274 } 521 }
275 522
276 host_data_[agent_host]->set_remote_locations(tcp_locations); 523 host_data_[agent_host]->set_remote_locations(tcp_locations);
277 UpdateDeviceDiscovery(); 524 UpdateDeviceDiscovery();
278 525
279 std::unique_ptr<base::DictionaryValue> result( 526 return DevToolsProtocol::CreateSuccessResponse(command_id, nullptr);
280 base::MakeUnique<base::DictionaryValue>());
281 return DevToolsProtocol::CreateSuccessResponse(command_id, std::move(result));
282 } 527 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/chrome_devtools_manager_delegate.h ('k') | chrome/browser/devtools/devtools_protocol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698