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

Side by Side Diff: chrome/browser/ui/webui/devtools_ui.cc

Issue 489893002: DevTools: add support for chrome-devtools://devtools/remote/open? URL. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/webui/devtools_ui.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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/webui/devtools_ui.h" 5 #include "chrome/browser/ui/webui/devtools_ui.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h"
9 #include "base/memory/ref_counted_memory.h" 10 #include "base/memory/ref_counted_memory.h"
10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
15 #include "chrome/browser/devtools/devtools_target_impl.h"
13 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/url_constants.h" 18 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/devtools_http_handler.h" 20 #include "content/public/browser/devtools_http_handler.h"
21 #include "content/public/browser/navigation_controller.h"
22 #include "content/public/browser/navigation_details.h"
23 #include "content/public/browser/navigation_entry.h"
17 #include "content/public/browser/url_data_source.h" 24 #include "content/public/browser/url_data_source.h"
18 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
19 #include "content/public/browser/web_ui.h" 26 #include "content/public/browser/web_ui.h"
20 #include "net/url_request/url_fetcher.h" 27 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_fetcher_delegate.h" 28 #include "net/url_request/url_fetcher_delegate.h"
22 #include "net/url_request/url_request_context_getter.h" 29 #include "net/url_request/url_request_context_getter.h"
23 #include "ui/base/resource/resource_bundle.h" 30 #include "ui/base/resource/resource_bundle.h"
24 31
25 using content::BrowserThread; 32 using content::BrowserThread;
26 using content::WebContents; 33 using content::WebContents;
(...skipping 13 matching lines...) Expand all
40 #if defined(DEBUG_DEVTOOLS) 47 #if defined(DEBUG_DEVTOOLS)
41 // Local frontend url provided by InspectUI. 48 // Local frontend url provided by InspectUI.
42 const char kFallbackFrontendURL[] = 49 const char kFallbackFrontendURL[] =
43 "chrome-devtools://devtools/bundled/devtools.html"; 50 "chrome-devtools://devtools/bundled/devtools.html";
44 #else 51 #else
45 // URL causing the DevTools window to display a plain text warning. 52 // URL causing the DevTools window to display a plain text warning.
46 const char kFallbackFrontendURL[] = 53 const char kFallbackFrontendURL[] =
47 "data:text/plain,Cannot load DevTools frontend from an untrusted origin"; 54 "data:text/plain,Cannot load DevTools frontend from an untrusted origin";
48 #endif // defined(DEBUG_DEVTOOLS) 55 #endif // defined(DEBUG_DEVTOOLS)
49 56
57 const char kRemoteOpenPrefix[] = "remote/open";
58
59 #if defined(DEBUG_DEVTOOLS)
60 const char kLocalSerial[] = "local";
61 #endif // defined(DEBUG_DEVTOOLS)
62
50 // FetchRequest --------------------------------------------------------------- 63 // FetchRequest ---------------------------------------------------------------
51 64
52 class FetchRequest : public net::URLFetcherDelegate { 65 class FetchRequest : public net::URLFetcherDelegate {
53 public: 66 public:
54 FetchRequest(net::URLRequestContextGetter* request_context, 67 FetchRequest(net::URLRequestContextGetter* request_context,
55 const GURL& url, 68 const GURL& url,
56 const content::URLDataSource::GotDataCallback& callback); 69 const content::URLDataSource::GotDataCallback& callback);
57 70
58 private: 71 private:
59 virtual ~FetchRequest() {} 72 virtual ~FetchRequest() {}
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return "text/css"; 111 return "text/css";
99 } else if (EndsWith(filename, ".js", false)) { 112 } else if (EndsWith(filename, ".js", false)) {
100 return "application/javascript"; 113 return "application/javascript";
101 } else if (EndsWith(filename, ".png", false)) { 114 } else if (EndsWith(filename, ".png", false)) {
102 return "image/png"; 115 return "image/png";
103 } else if (EndsWith(filename, ".gif", false)) { 116 } else if (EndsWith(filename, ".gif", false)) {
104 return "image/gif"; 117 return "image/gif";
105 } else if (EndsWith(filename, ".manifest", false)) { 118 } else if (EndsWith(filename, ".manifest", false)) {
106 return "text/cache-manifest"; 119 return "text/cache-manifest";
107 } 120 }
108 NOTREACHED(); 121 return "text/html";
109 return "text/plain";
110 } 122 }
111 123
112 // An URLDataSource implementation that handles chrome-devtools://devtools/ 124 // An URLDataSource implementation that handles chrome-devtools://devtools/
113 // requests. Three types of requests could be handled based on the URL path: 125 // requests. Three types of requests could be handled based on the URL path:
114 // 1. /bundled/: bundled DevTools frontend is served. 126 // 1. /bundled/: bundled DevTools frontend is served.
115 // 2. /remote/: Remote DevTools frontend is served from App Engine. 127 // 2. /remote/: remote DevTools frontend is served from App Engine.
128 // 3. /remote/open/: query is URL which is opened on remote device.
116 class DevToolsDataSource : public content::URLDataSource { 129 class DevToolsDataSource : public content::URLDataSource {
117 public: 130 public:
118 explicit DevToolsDataSource(net::URLRequestContextGetter* request_context); 131 explicit DevToolsDataSource(net::URLRequestContextGetter* request_context);
119 132
120 // content::URLDataSource implementation. 133 // content::URLDataSource implementation.
121 virtual std::string GetSource() const OVERRIDE; 134 virtual std::string GetSource() const OVERRIDE;
122 135
123 virtual void StartDataRequest( 136 virtual void StartDataRequest(
124 const std::string& path, 137 const std::string& path,
125 int render_process_id, 138 int render_process_id,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 const content::URLDataSource::GotDataCallback& callback) { 181 const content::URLDataSource::GotDataCallback& callback) {
169 // Serve request from local bundle. 182 // Serve request from local bundle.
170 std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath); 183 std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath);
171 bundled_path_prefix += "/"; 184 bundled_path_prefix += "/";
172 if (StartsWithASCII(path, bundled_path_prefix, false)) { 185 if (StartsWithASCII(path, bundled_path_prefix, false)) {
173 StartBundledDataRequest(path.substr(bundled_path_prefix.length()), 186 StartBundledDataRequest(path.substr(bundled_path_prefix.length()),
174 render_process_id, render_frame_id, callback); 187 render_process_id, render_frame_id, callback);
175 return; 188 return;
176 } 189 }
177 190
191 // Serve static response while connecting to the remote device.
192 if (StartsWithASCII(path, kRemoteOpenPrefix, false)) {
193 std::string response = "Connecting to the device...";
194 callback.Run(base::RefCountedString::TakeString(&response));
195 return;
196 }
197
178 // Serve request from remote location. 198 // Serve request from remote location.
179 std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath); 199 std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath);
180 remote_path_prefix += "/"; 200 remote_path_prefix += "/";
181 if (StartsWithASCII(path, remote_path_prefix, false)) { 201 if (StartsWithASCII(path, remote_path_prefix, false)) {
182 StartRemoteDataRequest(path.substr(remote_path_prefix.length()), 202 StartRemoteDataRequest(path.substr(remote_path_prefix.length()),
183 render_process_id, render_frame_id, callback); 203 render_process_id, render_frame_id, callback);
184 return; 204 return;
185 } 205 }
186 206
187 callback.Run(NULL); 207 callback.Run(NULL);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 void DevToolsDataSource::StartRemoteDataRequest( 241 void DevToolsDataSource::StartRemoteDataRequest(
222 const std::string& path, 242 const std::string& path,
223 int render_process_id, 243 int render_process_id,
224 int render_frame_id, 244 int render_frame_id,
225 const content::URLDataSource::GotDataCallback& callback) { 245 const content::URLDataSource::GotDataCallback& callback) {
226 GURL url = GURL(kRemoteFrontendBase + path); 246 GURL url = GURL(kRemoteFrontendBase + path);
227 CHECK_EQ(url.host(), kRemoteFrontendDomain); 247 CHECK_EQ(url.host(), kRemoteFrontendDomain);
228 new FetchRequest(request_context_, url, callback); 248 new FetchRequest(request_context_, url, callback);
229 } 249 }
230 250
251 // OpenRemotePageRequest ------------------------------------------------------
252
253 class OpenRemotePageRequest : public DevToolsAndroidBridge::DeviceListListener {
254 public:
255 OpenRemotePageRequest(
256 Profile* profile,
257 const std::string url,
258 const DevToolsAndroidBridge::RemotePageCallback& callback);
259 virtual ~OpenRemotePageRequest() {}
260
261 // DevToolsAndroidBridge::Listener overrides.
262 virtual void DeviceListChanged(
pfeldman 2014/08/21 12:38:46 private:
dgozman 2014/08/22 09:03:06 Done.
263 const DevToolsAndroidBridge::RemoteDevices& devices) OVERRIDE;
264
265 bool OpenInBrowser(DevToolsAndroidBridge::RemoteBrowser* browser);
266 void RemotePageOpened(DevToolsAndroidBridge::RemotePage* page);
267
268 std::string url_;
269 DevToolsAndroidBridge::RemotePageCallback callback_;
270 bool opening_;
271 scoped_refptr<DevToolsAndroidBridge> android_bridge_;
272
273 DISALLOW_COPY_AND_ASSIGN(OpenRemotePageRequest);
274 };
275
276 OpenRemotePageRequest::OpenRemotePageRequest(
277 Profile* profile,
278 const std::string url,
279 const DevToolsAndroidBridge::RemotePageCallback& callback)
280 : url_(url),
281 callback_(callback),
282 opening_(false),
283 android_bridge_(
284 DevToolsAndroidBridge::Factory::GetForProfile(profile)) {
285 android_bridge_->AddDeviceListListener(this);
286 }
287
288 void OpenRemotePageRequest::DeviceListChanged(
289 const DevToolsAndroidBridge::RemoteDevices& devices) {
290 if (opening_)
291 return;
292
293 for (DevToolsAndroidBridge::RemoteDevices::const_iterator dit =
294 devices.begin(); dit != devices.end(); ++dit) {
295 DevToolsAndroidBridge::RemoteDevice* device = dit->get();
296 if (!device->is_connected())
297 continue;
298
299 DevToolsAndroidBridge::RemoteBrowsers& browsers = device->browsers();
300 for (DevToolsAndroidBridge::RemoteBrowsers::iterator bit =
301 browsers.begin(); bit != browsers.end(); ++bit) {
302 if (OpenInBrowser(bit->get())) {
303 opening_ = true;
304 return;
305 }
306 }
307 }
308 }
309
310 bool OpenRemotePageRequest::OpenInBrowser(
311 DevToolsAndroidBridge::RemoteBrowser* browser) {
312 if (!browser->IsChrome())
313 return false;
314 #if defined(DEBUG_DEVTOOLS)
315 if (browser->serial() == kLocalSerial)
316 return false;
317 #endif // defined(DEBUG_DEVTOOLS)
318 browser->Open(url_, base::Bind(&OpenRemotePageRequest::RemotePageOpened,
319 base::Unretained(this)));
320 return true;
321 }
322
323 void OpenRemotePageRequest::RemotePageOpened(
324 DevToolsAndroidBridge::RemotePage* page) {
325 callback_.Run(page);
326 android_bridge_->RemoveDeviceListListener(this);
327 delete this;
328 }
329
231 } // namespace 330 } // namespace
232 331
233 // DevToolsUI ----------------------------------------------------------------- 332 // DevToolsUI -----------------------------------------------------------------
234 333
235 // static 334 // static
236 GURL DevToolsUI::GetProxyURL(const std::string& frontend_url) { 335 GURL DevToolsUI::GetProxyURL(const std::string& frontend_url) {
237 GURL url(frontend_url); 336 GURL url(frontend_url);
238 if (!url.is_valid() || url.host() != kRemoteFrontendDomain) 337 if (!url.is_valid() || url.host() != kRemoteFrontendDomain)
239 return GURL(kFallbackFrontendURL); 338 return GURL(kFallbackFrontendURL);
240 return GURL(base::StringPrintf("%s://%s/%s/%s", 339 return GURL(base::StringPrintf("%s://%s/%s/%s",
241 content::kChromeDevToolsScheme, 340 content::kChromeDevToolsScheme,
242 chrome::kChromeUIDevToolsHost, 341 chrome::kChromeUIDevToolsHost,
243 chrome::kChromeUIDevToolsRemotePath, 342 chrome::kChromeUIDevToolsRemotePath,
244 url.path().substr(1).c_str())); 343 url.path().substr(1).c_str()));
245 } 344 }
246 345
247 DevToolsUI::DevToolsUI(content::WebUI* web_ui) 346 DevToolsUI::DevToolsUI(content::WebUI* web_ui)
248 : WebUIController(web_ui), 347 : WebUIController(web_ui),
249 bindings_(web_ui->GetWebContents()) { 348 content::WebContentsObserver(web_ui->GetWebContents()),
349 bindings_(web_ui->GetWebContents()),
350 weak_factory_(this) {
250 web_ui->SetBindings(0); 351 web_ui->SetBindings(0);
251 Profile* profile = Profile::FromWebUI(web_ui); 352 Profile* profile = Profile::FromWebUI(web_ui);
252 content::URLDataSource::Add( 353 content::URLDataSource::Add(
253 profile, 354 profile,
254 new DevToolsDataSource(profile->GetRequestContext())); 355 new DevToolsDataSource(profile->GetRequestContext()));
255 } 356 }
357
358 DevToolsUI::~DevToolsUI() {
359 }
360
361 void DevToolsUI::NavigationEntryCommitted(
362 const content::LoadCommittedDetails& load_details) {
363 content::NavigationEntry* entry = load_details.entry;
364 if (!CommandLine::ForCurrentProcess()->HasSwitch(
365 switches::kEnableDevToolsExperiments)) {
366 return;
367 }
368
369 if (entry->GetVirtualURL() == remote_frontend_loading_url_) {
370 remote_frontend_loading_url_ = GURL();
371 return;
372 }
373
374 std::string path = entry->GetVirtualURL().path().substr(1);
375 if (!StartsWithASCII(path, kRemoteOpenPrefix, false))
376 return;
377
378 bindings_.Detach();
379 remote_page_opening_url_ = entry->GetVirtualURL();
380 new OpenRemotePageRequest(Profile::FromWebUI(web_ui()),
381 entry->GetVirtualURL().query(),
382 base::Bind(&DevToolsUI::RemotePageOpened,
383 weak_factory_.GetWeakPtr(),
384 entry->GetVirtualURL()));
385 }
386
387 void DevToolsUI::RemotePageOpened(
388 const GURL& virtual_url, DevToolsAndroidBridge::RemotePage* page) {
389 // Already navigated away while connecting to remote device.
390 if (remote_page_opening_url_ != virtual_url)
391 return;
392
393 scoped_ptr<DevToolsAndroidBridge::RemotePage> my_page(page);
394 remote_page_opening_url_ = GURL();
395
396 Profile* profile = Profile::FromWebUI(web_ui());
397 GURL url = DevToolsUIBindings::ApplyThemeToURL(profile,
398 DevToolsUI::GetProxyURL(page->GetFrontendURL()));
399
400 content::NavigationController& navigation_controller =
401 web_ui()->GetWebContents()->GetController();
402 content::NavigationController::LoadURLParams params(url);
403 params.should_replace_current_entry = true;
404 remote_frontend_loading_url_ = virtual_url;
405 navigation_controller.LoadURLWithParams(params);
406 navigation_controller.GetPendingEntry()->SetVirtualURL(virtual_url);
407
408 bindings_.AttachTo(page->GetTarget()->GetAgentHost());
409 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/devtools_ui.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698