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

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: fixed comment, guard by experiment 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 if (!CommandLine::ForCurrentProcess()->HasSwitch(
194 switches::kEnableDevToolsExperiments)) {
195 callback.Run(NULL);
196 return;
197 }
198 std::string response = "Connecting to the device...";
199 callback.Run(base::RefCountedString::TakeString(&response));
200 return;
201 }
202
178 // Serve request from remote location. 203 // Serve request from remote location.
179 std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath); 204 std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath);
180 remote_path_prefix += "/"; 205 remote_path_prefix += "/";
181 if (StartsWithASCII(path, remote_path_prefix, false)) { 206 if (StartsWithASCII(path, remote_path_prefix, false)) {
182 StartRemoteDataRequest(path.substr(remote_path_prefix.length()), 207 StartRemoteDataRequest(path.substr(remote_path_prefix.length()),
183 render_process_id, render_frame_id, callback); 208 render_process_id, render_frame_id, callback);
184 return; 209 return;
185 } 210 }
186 211
187 callback.Run(NULL); 212 callback.Run(NULL);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 void DevToolsDataSource::StartRemoteDataRequest( 246 void DevToolsDataSource::StartRemoteDataRequest(
222 const std::string& path, 247 const std::string& path,
223 int render_process_id, 248 int render_process_id,
224 int render_frame_id, 249 int render_frame_id,
225 const content::URLDataSource::GotDataCallback& callback) { 250 const content::URLDataSource::GotDataCallback& callback) {
226 GURL url = GURL(kRemoteFrontendBase + path); 251 GURL url = GURL(kRemoteFrontendBase + path);
227 CHECK_EQ(url.host(), kRemoteFrontendDomain); 252 CHECK_EQ(url.host(), kRemoteFrontendDomain);
228 new FetchRequest(request_context_, url, callback); 253 new FetchRequest(request_context_, url, callback);
229 } 254 }
230 255
256 // OpenRemotePageRequest ------------------------------------------------------
257
258 class OpenRemotePageRequest : public DevToolsAndroidBridge::DeviceListListener {
259 public:
260 OpenRemotePageRequest(
261 Profile* profile,
262 const std::string url,
263 const DevToolsAndroidBridge::RemotePageCallback& callback);
264 virtual ~OpenRemotePageRequest() {}
265
266 private:
267 // DevToolsAndroidBridge::Listener overrides.
268 virtual void DeviceListChanged(
269 const DevToolsAndroidBridge::RemoteDevices& devices) OVERRIDE;
270
271 bool OpenInBrowser(DevToolsAndroidBridge::RemoteBrowser* browser);
272 void RemotePageOpened(DevToolsAndroidBridge::RemotePage* page);
273
274 std::string url_;
275 DevToolsAndroidBridge::RemotePageCallback callback_;
276 bool opening_;
277 scoped_refptr<DevToolsAndroidBridge> android_bridge_;
278
279 DISALLOW_COPY_AND_ASSIGN(OpenRemotePageRequest);
280 };
281
282 OpenRemotePageRequest::OpenRemotePageRequest(
283 Profile* profile,
284 const std::string url,
285 const DevToolsAndroidBridge::RemotePageCallback& callback)
286 : url_(url),
287 callback_(callback),
288 opening_(false),
289 android_bridge_(
290 DevToolsAndroidBridge::Factory::GetForProfile(profile)) {
291 android_bridge_->AddDeviceListListener(this);
292 }
293
294 void OpenRemotePageRequest::DeviceListChanged(
295 const DevToolsAndroidBridge::RemoteDevices& devices) {
296 if (opening_)
297 return;
298
299 for (DevToolsAndroidBridge::RemoteDevices::const_iterator dit =
300 devices.begin(); dit != devices.end(); ++dit) {
301 DevToolsAndroidBridge::RemoteDevice* device = dit->get();
302 if (!device->is_connected())
303 continue;
304
305 DevToolsAndroidBridge::RemoteBrowsers& browsers = device->browsers();
306 for (DevToolsAndroidBridge::RemoteBrowsers::iterator bit =
307 browsers.begin(); bit != browsers.end(); ++bit) {
308 if (OpenInBrowser(bit->get())) {
309 opening_ = true;
310 return;
311 }
312 }
313 }
314 }
315
316 bool OpenRemotePageRequest::OpenInBrowser(
317 DevToolsAndroidBridge::RemoteBrowser* browser) {
318 if (!browser->IsChrome())
319 return false;
320 #if defined(DEBUG_DEVTOOLS)
321 if (browser->serial() == kLocalSerial)
322 return false;
323 #endif // defined(DEBUG_DEVTOOLS)
324 browser->Open(url_, base::Bind(&OpenRemotePageRequest::RemotePageOpened,
325 base::Unretained(this)));
326 return true;
327 }
328
329 void OpenRemotePageRequest::RemotePageOpened(
330 DevToolsAndroidBridge::RemotePage* page) {
331 callback_.Run(page);
332 android_bridge_->RemoveDeviceListListener(this);
333 delete this;
334 }
335
231 } // namespace 336 } // namespace
232 337
233 // DevToolsUI ----------------------------------------------------------------- 338 // DevToolsUI -----------------------------------------------------------------
234 339
235 // static 340 // static
236 GURL DevToolsUI::GetProxyURL(const std::string& frontend_url) { 341 GURL DevToolsUI::GetProxyURL(const std::string& frontend_url) {
237 GURL url(frontend_url); 342 GURL url(frontend_url);
238 if (!url.is_valid() || url.host() != kRemoteFrontendDomain) 343 if (!url.is_valid() || url.host() != kRemoteFrontendDomain)
239 return GURL(kFallbackFrontendURL); 344 return GURL(kFallbackFrontendURL);
240 return GURL(base::StringPrintf("%s://%s/%s/%s", 345 return GURL(base::StringPrintf("%s://%s/%s/%s",
241 content::kChromeDevToolsScheme, 346 content::kChromeDevToolsScheme,
242 chrome::kChromeUIDevToolsHost, 347 chrome::kChromeUIDevToolsHost,
243 chrome::kChromeUIDevToolsRemotePath, 348 chrome::kChromeUIDevToolsRemotePath,
244 url.path().substr(1).c_str())); 349 url.path().substr(1).c_str()));
245 } 350 }
246 351
247 DevToolsUI::DevToolsUI(content::WebUI* web_ui) 352 DevToolsUI::DevToolsUI(content::WebUI* web_ui)
248 : WebUIController(web_ui), 353 : WebUIController(web_ui),
249 bindings_(web_ui->GetWebContents()) { 354 content::WebContentsObserver(web_ui->GetWebContents()),
355 bindings_(web_ui->GetWebContents()),
356 weak_factory_(this) {
250 web_ui->SetBindings(0); 357 web_ui->SetBindings(0);
251 Profile* profile = Profile::FromWebUI(web_ui); 358 Profile* profile = Profile::FromWebUI(web_ui);
252 content::URLDataSource::Add( 359 content::URLDataSource::Add(
253 profile, 360 profile,
254 new DevToolsDataSource(profile->GetRequestContext())); 361 new DevToolsDataSource(profile->GetRequestContext()));
255 } 362 }
363
364 DevToolsUI::~DevToolsUI() {
365 }
366
367 void DevToolsUI::NavigationEntryCommitted(
368 const content::LoadCommittedDetails& load_details) {
369 content::NavigationEntry* entry = load_details.entry;
370 if (!CommandLine::ForCurrentProcess()->HasSwitch(
371 switches::kEnableDevToolsExperiments)) {
372 return;
373 }
374
375 if (entry->GetVirtualURL() == remote_frontend_loading_url_) {
376 remote_frontend_loading_url_ = GURL();
377 return;
378 }
379
380 std::string path = entry->GetVirtualURL().path().substr(1);
381 if (!StartsWithASCII(path, kRemoteOpenPrefix, false))
382 return;
383
384 bindings_.Detach();
385 remote_page_opening_url_ = entry->GetVirtualURL();
386 new OpenRemotePageRequest(Profile::FromWebUI(web_ui()),
387 entry->GetVirtualURL().query(),
388 base::Bind(&DevToolsUI::RemotePageOpened,
389 weak_factory_.GetWeakPtr(),
390 entry->GetVirtualURL()));
391 }
392
393 void DevToolsUI::RemotePageOpened(
394 const GURL& virtual_url, DevToolsAndroidBridge::RemotePage* page) {
395 // Already navigated away while connecting to remote device.
396 if (remote_page_opening_url_ != virtual_url)
397 return;
398
399 scoped_ptr<DevToolsAndroidBridge::RemotePage> my_page(page);
400 remote_page_opening_url_ = GURL();
401
402 Profile* profile = Profile::FromWebUI(web_ui());
403 GURL url = DevToolsUIBindings::ApplyThemeToURL(profile,
404 DevToolsUI::GetProxyURL(page->GetFrontendURL()));
405
406 content::NavigationController& navigation_controller =
407 web_ui()->GetWebContents()->GetController();
408 content::NavigationController::LoadURLParams params(url);
409 params.should_replace_current_entry = true;
410 remote_frontend_loading_url_ = virtual_url;
411 navigation_controller.LoadURLWithParams(params);
412 navigation_controller.GetPendingEntry()->SetVirtualURL(virtual_url);
413
414 bindings_.AttachTo(page->GetTarget()->GetAgentHost());
415 }
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