Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_ui_bindings.cc
blobafe5a5aaa7f671b09fb8959d566fbf5f7f5023ef
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.
5 #include "chrome/browser/devtools/devtools_ui_bindings.h"
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/chrome_page_zoom.h"
16 #include "chrome/browser/devtools/devtools_target_impl.h"
17 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/themes/theme_properties.h"
23 #include "chrome/browser/themes/theme_service.h"
24 #include "chrome/browser/themes/theme_service_factory.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_iterator.h"
27 #include "chrome/browser/ui/browser_list.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/extensions/manifest_url_handler.h"
32 #include "chrome/common/url_constants.h"
33 #include "components/infobars/core/infobar.h"
34 #include "content/public/browser/devtools_client_host.h"
35 #include "content/public/browser/devtools_manager.h"
36 #include "content/public/browser/favicon_status.h"
37 #include "content/public/browser/navigation_controller.h"
38 #include "content/public/browser/navigation_entry.h"
39 #include "content/public/browser/notification_source.h"
40 #include "content/public/browser/render_frame_host.h"
41 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/user_metrics.h"
43 #include "content/public/browser/web_contents.h"
44 #include "content/public/browser/web_contents_observer.h"
45 #include "content/public/common/page_transition_types.h"
46 #include "content/public/common/renderer_preferences.h"
47 #include "content/public/common/url_constants.h"
48 #include "extensions/browser/extension_system.h"
49 #include "extensions/common/extension_set.h"
50 #include "grit/generated_resources.h"
51 #include "ui/base/l10n/l10n_util.h"
53 using base::DictionaryValue;
54 using content::BrowserThread;
56 namespace {
58 typedef std::vector<DevToolsUIBindings*> DevToolsUIBindingsList;
59 base::LazyInstance<DevToolsUIBindingsList>::Leaky g_instances =
60 LAZY_INSTANCE_INITIALIZER;
62 static const char kFrontendHostId[] = "id";
63 static const char kFrontendHostMethod[] = "method";
64 static const char kFrontendHostParams[] = "params";
66 std::string SkColorToRGBAString(SkColor color) {
67 // We avoid StringPrintf because it will use locale specific formatters for
68 // the double (e.g. ',' instead of '.' in German).
69 return "rgba(" + base::IntToString(SkColorGetR(color)) + "," +
70 base::IntToString(SkColorGetG(color)) + "," +
71 base::IntToString(SkColorGetB(color)) + "," +
72 base::DoubleToString(SkColorGetA(color) / 255.0) + ")";
75 base::DictionaryValue* CreateFileSystemValue(
76 DevToolsFileHelper::FileSystem file_system) {
77 base::DictionaryValue* file_system_value = new base::DictionaryValue();
78 file_system_value->SetString("fileSystemName", file_system.file_system_name);
79 file_system_value->SetString("rootURL", file_system.root_url);
80 file_system_value->SetString("fileSystemPath", file_system.file_system_path);
81 return file_system_value;
84 Browser* FindBrowser(content::WebContents* web_contents) {
85 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
86 int tab_index = it->tab_strip_model()->GetIndexOfWebContents(
87 web_contents);
88 if (tab_index != TabStripModel::kNoTab)
89 return *it;
91 return NULL;
94 // DevToolsConfirmInfoBarDelegate ---------------------------------------------
96 typedef base::Callback<void(bool)> InfoBarCallback;
98 class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
99 public:
100 // If |infobar_service| is NULL, runs |callback| with a single argument with
101 // value "false". Otherwise, creates a dev tools confirm infobar and delegate
102 // and adds the infobar to |infobar_service|.
103 static void Create(InfoBarService* infobar_service,
104 const InfoBarCallback& callback,
105 const base::string16& message);
107 private:
108 DevToolsConfirmInfoBarDelegate(
109 const InfoBarCallback& callback,
110 const base::string16& message);
111 virtual ~DevToolsConfirmInfoBarDelegate();
113 virtual base::string16 GetMessageText() const OVERRIDE;
114 virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
115 virtual bool Accept() OVERRIDE;
116 virtual bool Cancel() OVERRIDE;
118 InfoBarCallback callback_;
119 const base::string16 message_;
121 DISALLOW_COPY_AND_ASSIGN(DevToolsConfirmInfoBarDelegate);
124 void DevToolsConfirmInfoBarDelegate::Create(
125 InfoBarService* infobar_service,
126 const InfoBarCallback& callback,
127 const base::string16& message) {
128 if (!infobar_service) {
129 callback.Run(false);
130 return;
133 infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
134 scoped_ptr<ConfirmInfoBarDelegate>(
135 new DevToolsConfirmInfoBarDelegate(callback, message))));
138 DevToolsConfirmInfoBarDelegate::DevToolsConfirmInfoBarDelegate(
139 const InfoBarCallback& callback,
140 const base::string16& message)
141 : ConfirmInfoBarDelegate(),
142 callback_(callback),
143 message_(message) {
146 DevToolsConfirmInfoBarDelegate::~DevToolsConfirmInfoBarDelegate() {
147 if (!callback_.is_null())
148 callback_.Run(false);
151 base::string16 DevToolsConfirmInfoBarDelegate::GetMessageText() const {
152 return message_;
155 base::string16 DevToolsConfirmInfoBarDelegate::GetButtonLabel(
156 InfoBarButton button) const {
157 return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
158 IDS_DEV_TOOLS_CONFIRM_ALLOW_BUTTON : IDS_DEV_TOOLS_CONFIRM_DENY_BUTTON);
161 bool DevToolsConfirmInfoBarDelegate::Accept() {
162 callback_.Run(true);
163 callback_.Reset();
164 return true;
167 bool DevToolsConfirmInfoBarDelegate::Cancel() {
168 callback_.Run(false);
169 callback_.Reset();
170 return true;
173 // DevToolsUIDefaultDelegate --------------------------------------------------
175 class DefaultBindingsDelegate : public DevToolsUIBindings::Delegate {
176 public:
177 explicit DefaultBindingsDelegate(content::WebContents* web_contents)
178 : web_contents_(web_contents) {}
180 private:
181 virtual ~DefaultBindingsDelegate() {}
183 virtual void ActivateWindow() OVERRIDE;
184 virtual void CloseWindow() OVERRIDE {}
185 virtual void SetContentsInsets(
186 int left, int top, int right, int bottom) OVERRIDE {}
187 virtual void SetContentsResizingStrategy(
188 const gfx::Insets& insets, const gfx::Size& min_size) OVERRIDE {}
189 virtual void InspectElementCompleted() OVERRIDE {}
190 virtual void MoveWindow(int x, int y) OVERRIDE {}
191 virtual void SetIsDocked(bool is_docked) OVERRIDE {}
192 virtual void OpenInNewTab(const std::string& url) OVERRIDE;
193 virtual void SetWhitelistedShortcuts(const std::string& message) OVERRIDE {}
195 virtual void InspectedContentsClosing() OVERRIDE;
196 virtual void OnLoadCompleted() OVERRIDE {}
197 virtual InfoBarService* GetInfoBarService() OVERRIDE;
199 content::WebContents* web_contents_;
200 DISALLOW_COPY_AND_ASSIGN(DefaultBindingsDelegate);
203 void DefaultBindingsDelegate::ActivateWindow() {
204 web_contents_->GetDelegate()->ActivateContents(web_contents_);
205 web_contents_->Focus();
208 void DefaultBindingsDelegate::OpenInNewTab(const std::string& url) {
209 content::OpenURLParams params(
210 GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
211 content::PAGE_TRANSITION_LINK, false);
212 Browser* browser = FindBrowser(web_contents_);
213 browser->OpenURL(params);
216 void DefaultBindingsDelegate::InspectedContentsClosing() {
217 web_contents_->GetRenderViewHost()->ClosePage();
220 InfoBarService* DefaultBindingsDelegate::GetInfoBarService() {
221 return InfoBarService::FromWebContents(web_contents_);
224 } // namespace
226 // DevToolsUIBindings::FrontendWebContentsObserver ----------------------------
228 class DevToolsUIBindings::FrontendWebContentsObserver
229 : public content::WebContentsObserver {
230 public:
231 explicit FrontendWebContentsObserver(DevToolsUIBindings* window);
232 virtual ~FrontendWebContentsObserver();
234 private:
235 // contents::WebContentsObserver:
236 virtual void AboutToNavigateRenderView(
237 content::RenderViewHost* render_view_host) OVERRIDE;
238 virtual void DocumentOnLoadCompletedInMainFrame() OVERRIDE;
240 DevToolsUIBindings* devtools_bindings_;
241 DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
244 DevToolsUIBindings::FrontendWebContentsObserver::FrontendWebContentsObserver(
245 DevToolsUIBindings* devtools_window)
246 : WebContentsObserver(devtools_window->web_contents()),
247 devtools_bindings_(devtools_window) {
250 DevToolsUIBindings::FrontendWebContentsObserver::
251 ~FrontendWebContentsObserver() {
254 void DevToolsUIBindings::FrontendWebContentsObserver::AboutToNavigateRenderView(
255 content::RenderViewHost* render_view_host) {
256 content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
259 void DevToolsUIBindings::FrontendWebContentsObserver::
260 DocumentOnLoadCompletedInMainFrame() {
261 devtools_bindings_->DocumentOnLoadCompletedInMainFrame();
264 // DevToolsUIBindings ---------------------------------------------------------
266 // static
267 DevToolsUIBindings* DevToolsUIBindings::ForWebContents(
268 content::WebContents* web_contents) {
269 DevToolsUIBindingsList* instances = g_instances.Pointer();
270 for (DevToolsUIBindingsList::iterator it(instances->begin());
271 it != instances->end(); ++it) {
272 if ((*it)->web_contents() == web_contents)
273 return *it;
275 return NULL;
278 // static
279 GURL DevToolsUIBindings::ApplyThemeToURL(Profile* profile,
280 const GURL& base_url) {
281 std::string frontend_url = base_url.spec();
282 ThemeService* tp = ThemeServiceFactory::GetForProfile(profile);
283 DCHECK(tp);
284 std::string url_string(
285 frontend_url +
286 ((frontend_url.find("?") == std::string::npos) ? "?" : "&") +
287 "dockSide=undocked" + // TODO(dgozman): remove this support in M38.
288 "&toolbarColor=" +
289 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
290 "&textColor=" +
291 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)));
292 if (CommandLine::ForCurrentProcess()->HasSwitch(
293 switches::kEnableDevToolsExperiments))
294 url_string += "&experiments=true";
295 return GURL(url_string);
298 DevToolsUIBindings::DevToolsUIBindings(content::WebContents* web_contents)
299 : profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
300 web_contents_(web_contents),
301 delegate_(new DefaultBindingsDelegate(web_contents_)),
302 device_listener_enabled_(false),
303 weak_factory_(this) {
304 g_instances.Get().push_back(this);
305 frontend_contents_observer_.reset(new FrontendWebContentsObserver(this));
306 web_contents_->GetMutableRendererPrefs()->can_accept_load_drops = false;
308 frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost(
309 web_contents_, this));
310 file_helper_.reset(new DevToolsFileHelper(web_contents_, profile_));
311 file_system_indexer_ = new DevToolsFileSystemIndexer();
312 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
313 web_contents_);
315 // Wipe out page icon so that the default application icon is used.
316 content::NavigationEntry* entry =
317 web_contents_->GetController().GetActiveEntry();
318 entry->GetFavicon().image = gfx::Image();
319 entry->GetFavicon().valid = true;
321 // Register on-load actions.
322 registrar_.Add(
323 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
324 content::Source<ThemeService>(
325 ThemeServiceFactory::GetForProfile(profile_)));
327 embedder_message_dispatcher_.reset(
328 DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this));
331 DevToolsUIBindings::~DevToolsUIBindings() {
332 content::DevToolsManager::GetInstance()->ClientHostClosing(
333 frontend_host_.get());
335 for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin());
336 jobs_it != indexing_jobs_.end(); ++jobs_it) {
337 jobs_it->second->Stop();
339 indexing_jobs_.clear();
340 if (device_listener_enabled_)
341 EnableRemoteDeviceCounter(false);
343 // Remove self from global list.
344 DevToolsUIBindingsList* instances = g_instances.Pointer();
345 DevToolsUIBindingsList::iterator it(
346 std::find(instances->begin(), instances->end(), this));
347 DCHECK(it != instances->end());
348 instances->erase(it);
351 void DevToolsUIBindings::InspectedContentsClosing() {
352 delegate_->InspectedContentsClosing();
355 void DevToolsUIBindings::Observe(int type,
356 const content::NotificationSource& source,
357 const content::NotificationDetails& details) {
358 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
359 UpdateTheme();
362 void DevToolsUIBindings::DispatchOnEmbedder(const std::string& message) {
363 std::string method;
364 base::ListValue empty_params;
365 base::ListValue* params = &empty_params;
367 base::DictionaryValue* dict = NULL;
368 scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
369 if (!parsed_message ||
370 !parsed_message->GetAsDictionary(&dict) ||
371 !dict->GetString(kFrontendHostMethod, &method) ||
372 (dict->HasKey(kFrontendHostParams) &&
373 !dict->GetList(kFrontendHostParams, &params))) {
374 LOG(ERROR) << "Invalid message was sent to embedder: " << message;
375 return;
378 int id = 0;
379 dict->GetInteger(kFrontendHostId, &id);
381 std::string error;
382 embedder_message_dispatcher_->Dispatch(method, params, &error);
383 if (id) {
384 scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id));
385 scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error));
386 CallClientFunction("InspectorFrontendAPI.embedderMessageAck",
387 id_value.get(), error_value.get(), NULL);
391 void DevToolsUIBindings::ActivateWindow() {
392 delegate_->ActivateWindow();
395 void DevToolsUIBindings::CloseWindow() {
396 delegate_->CloseWindow();
399 void DevToolsUIBindings::SetContentsInsets(
400 int top, int left, int bottom, int right) {
401 delegate_->SetContentsInsets(top, left, bottom, right);
404 void DevToolsUIBindings::SetContentsResizingStrategy(
405 const gfx::Insets& insets, const gfx::Size& min_size) {
406 delegate_->SetContentsResizingStrategy(insets, min_size);
409 void DevToolsUIBindings::MoveWindow(int x, int y) {
410 delegate_->MoveWindow(x, y);
413 void DevToolsUIBindings::SetIsDocked(bool dock_requested) {
414 delegate_->SetIsDocked(dock_requested);
417 void DevToolsUIBindings::InspectElementCompleted() {
418 delegate_->InspectElementCompleted();
421 void DevToolsUIBindings::OpenInNewTab(const std::string& url) {
422 delegate_->OpenInNewTab(url);
425 void DevToolsUIBindings::SaveToFile(const std::string& url,
426 const std::string& content,
427 bool save_as) {
428 file_helper_->Save(url, content, save_as,
429 base::Bind(&DevToolsUIBindings::FileSavedAs,
430 weak_factory_.GetWeakPtr(), url),
431 base::Bind(&DevToolsUIBindings::CanceledFileSaveAs,
432 weak_factory_.GetWeakPtr(), url));
435 void DevToolsUIBindings::AppendToFile(const std::string& url,
436 const std::string& content) {
437 file_helper_->Append(url, content,
438 base::Bind(&DevToolsUIBindings::AppendedTo,
439 weak_factory_.GetWeakPtr(), url));
442 void DevToolsUIBindings::RequestFileSystems() {
443 CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
444 file_helper_->RequestFileSystems(base::Bind(
445 &DevToolsUIBindings::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
448 void DevToolsUIBindings::AddFileSystem() {
449 CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
450 file_helper_->AddFileSystem(
451 base::Bind(&DevToolsUIBindings::FileSystemAdded,
452 weak_factory_.GetWeakPtr()),
453 base::Bind(&DevToolsUIBindings::ShowDevToolsConfirmInfoBar,
454 weak_factory_.GetWeakPtr()));
457 void DevToolsUIBindings::RemoveFileSystem(
458 const std::string& file_system_path) {
459 CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
460 file_helper_->RemoveFileSystem(file_system_path);
461 base::StringValue file_system_path_value(file_system_path);
462 CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
463 &file_system_path_value, NULL, NULL);
466 void DevToolsUIBindings::UpgradeDraggedFileSystemPermissions(
467 const std::string& file_system_url) {
468 CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
469 file_helper_->UpgradeDraggedFileSystemPermissions(
470 file_system_url,
471 base::Bind(&DevToolsUIBindings::FileSystemAdded,
472 weak_factory_.GetWeakPtr()),
473 base::Bind(&DevToolsUIBindings::ShowDevToolsConfirmInfoBar,
474 weak_factory_.GetWeakPtr()));
477 void DevToolsUIBindings::IndexPath(int request_id,
478 const std::string& file_system_path) {
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
480 CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
481 if (!file_helper_->IsFileSystemAdded(file_system_path)) {
482 IndexingDone(request_id, file_system_path);
483 return;
485 indexing_jobs_[request_id] =
486 scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
487 file_system_indexer_->IndexPath(
488 file_system_path,
489 Bind(&DevToolsUIBindings::IndexingTotalWorkCalculated,
490 weak_factory_.GetWeakPtr(),
491 request_id,
492 file_system_path),
493 Bind(&DevToolsUIBindings::IndexingWorked,
494 weak_factory_.GetWeakPtr(),
495 request_id,
496 file_system_path),
497 Bind(&DevToolsUIBindings::IndexingDone,
498 weak_factory_.GetWeakPtr(),
499 request_id,
500 file_system_path)));
503 void DevToolsUIBindings::StopIndexing(int request_id) {
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
505 IndexingJobsMap::iterator it = indexing_jobs_.find(request_id);
506 if (it == indexing_jobs_.end())
507 return;
508 it->second->Stop();
509 indexing_jobs_.erase(it);
512 void DevToolsUIBindings::SearchInPath(int request_id,
513 const std::string& file_system_path,
514 const std::string& query) {
515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
516 CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
517 if (!file_helper_->IsFileSystemAdded(file_system_path)) {
518 SearchCompleted(request_id, file_system_path, std::vector<std::string>());
519 return;
521 file_system_indexer_->SearchInPath(file_system_path,
522 query,
523 Bind(&DevToolsUIBindings::SearchCompleted,
524 weak_factory_.GetWeakPtr(),
525 request_id,
526 file_system_path));
529 void DevToolsUIBindings::SetWhitelistedShortcuts(
530 const std::string& message) {
533 void DevToolsUIBindings::ZoomIn() {
534 chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_IN);
537 void DevToolsUIBindings::ZoomOut() {
538 chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT);
541 void DevToolsUIBindings::ResetZoom() {
542 chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET);
545 static void InspectTarget(Profile* profile, DevToolsTargetImpl* target) {
546 if (target)
547 target->Inspect(profile);
550 void DevToolsUIBindings::OpenUrlOnRemoteDeviceAndInspect(
551 const std::string& browser_id,
552 const std::string& url) {
553 if (remote_targets_handler_) {
554 remote_targets_handler_->Open(browser_id, url,
555 base::Bind(&InspectTarget, profile_));
559 void DevToolsUIBindings::StartRemoteDevicesListener() {
560 remote_targets_handler_ = DevToolsTargetsUIHandler::CreateForAdb(
561 base::Bind(&DevToolsUIBindings::PopulateRemoteDevices,
562 base::Unretained(this)),
563 profile_);
566 void DevToolsUIBindings::StopRemoteDevicesListener() {
567 remote_targets_handler_.reset();
570 void DevToolsUIBindings::EnableRemoteDeviceCounter(bool enable) {
571 DevToolsAndroidBridge* adb_bridge =
572 DevToolsAndroidBridge::Factory::GetForProfile(profile_);
573 if (!adb_bridge)
574 return;
576 DCHECK(device_listener_enabled_ != enable);
577 device_listener_enabled_ = enable;
578 if (enable)
579 adb_bridge->AddDeviceCountListener(this);
580 else
581 adb_bridge->RemoveDeviceCountListener(this);
584 void DevToolsUIBindings::DeviceCountChanged(int count) {
585 base::FundamentalValue value(count);
586 CallClientFunction(
587 "InspectorFrontendAPI.setRemoteDeviceCount", &value, NULL, NULL);
590 void DevToolsUIBindings::PopulateRemoteDevices(
591 const std::string& source,
592 scoped_ptr<base::ListValue> targets) {
593 CallClientFunction(
594 "InspectorFrontendAPI.populateRemoteDevices", targets.get(), NULL, NULL);
597 void DevToolsUIBindings::FileSavedAs(const std::string& url) {
598 base::StringValue url_value(url);
599 CallClientFunction("InspectorFrontendAPI.savedURL", &url_value, NULL, NULL);
602 void DevToolsUIBindings::CanceledFileSaveAs(const std::string& url) {
603 base::StringValue url_value(url);
604 CallClientFunction("InspectorFrontendAPI.canceledSaveURL",
605 &url_value, NULL, NULL);
608 void DevToolsUIBindings::AppendedTo(const std::string& url) {
609 base::StringValue url_value(url);
610 CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value, NULL,
611 NULL);
614 void DevToolsUIBindings::FileSystemsLoaded(
615 const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
616 base::ListValue file_systems_value;
617 for (size_t i = 0; i < file_systems.size(); ++i)
618 file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
619 CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
620 &file_systems_value, NULL, NULL);
623 void DevToolsUIBindings::FileSystemAdded(
624 const DevToolsFileHelper::FileSystem& file_system) {
625 scoped_ptr<base::StringValue> error_string_value(
626 new base::StringValue(std::string()));
627 scoped_ptr<base::DictionaryValue> file_system_value;
628 if (!file_system.file_system_path.empty())
629 file_system_value.reset(CreateFileSystemValue(file_system));
630 CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
631 error_string_value.get(), file_system_value.get(), NULL);
634 void DevToolsUIBindings::IndexingTotalWorkCalculated(
635 int request_id,
636 const std::string& file_system_path,
637 int total_work) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
639 base::FundamentalValue request_id_value(request_id);
640 base::StringValue file_system_path_value(file_system_path);
641 base::FundamentalValue total_work_value(total_work);
642 CallClientFunction("InspectorFrontendAPI.indexingTotalWorkCalculated",
643 &request_id_value, &file_system_path_value,
644 &total_work_value);
647 void DevToolsUIBindings::IndexingWorked(int request_id,
648 const std::string& file_system_path,
649 int worked) {
650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
651 base::FundamentalValue request_id_value(request_id);
652 base::StringValue file_system_path_value(file_system_path);
653 base::FundamentalValue worked_value(worked);
654 CallClientFunction("InspectorFrontendAPI.indexingWorked", &request_id_value,
655 &file_system_path_value, &worked_value);
658 void DevToolsUIBindings::IndexingDone(int request_id,
659 const std::string& file_system_path) {
660 indexing_jobs_.erase(request_id);
661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
662 base::FundamentalValue request_id_value(request_id);
663 base::StringValue file_system_path_value(file_system_path);
664 CallClientFunction("InspectorFrontendAPI.indexingDone", &request_id_value,
665 &file_system_path_value, NULL);
668 void DevToolsUIBindings::SearchCompleted(
669 int request_id,
670 const std::string& file_system_path,
671 const std::vector<std::string>& file_paths) {
672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
673 base::ListValue file_paths_value;
674 for (std::vector<std::string>::const_iterator it(file_paths.begin());
675 it != file_paths.end(); ++it) {
676 file_paths_value.AppendString(*it);
678 base::FundamentalValue request_id_value(request_id);
679 base::StringValue file_system_path_value(file_system_path);
680 CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value,
681 &file_system_path_value, &file_paths_value);
684 void DevToolsUIBindings::ShowDevToolsConfirmInfoBar(
685 const base::string16& message,
686 const InfoBarCallback& callback) {
687 DevToolsConfirmInfoBarDelegate::Create(delegate_->GetInfoBarService(),
688 callback, message);
691 void DevToolsUIBindings::UpdateTheme() {
692 ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
693 DCHECK(tp);
695 std::string command("InspectorFrontendAPI.setToolbarColors(\"" +
696 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
697 "\", \"" +
698 SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) +
699 "\")");
700 web_contents_->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16(command));
703 void DevToolsUIBindings::AddDevToolsExtensionsToClient() {
704 const ExtensionService* extension_service = extensions::ExtensionSystem::Get(
705 profile_->GetOriginalProfile())->extension_service();
706 if (!extension_service)
707 return;
708 const extensions::ExtensionSet* extensions = extension_service->extensions();
710 base::ListValue results;
711 for (extensions::ExtensionSet::const_iterator extension(extensions->begin());
712 extension != extensions->end(); ++extension) {
713 if (extensions::ManifestURL::GetDevToolsPage(extension->get()).is_empty())
714 continue;
715 base::DictionaryValue* extension_info = new base::DictionaryValue();
716 extension_info->Set(
717 "startPage",
718 new base::StringValue(
719 extensions::ManifestURL::GetDevToolsPage(
720 extension->get()).spec()));
721 extension_info->Set("name", new base::StringValue((*extension)->name()));
722 extension_info->Set(
723 "exposeExperimentalAPIs",
724 new base::FundamentalValue((*extension)->HasAPIPermission(
725 extensions::APIPermission::kExperimental)));
726 results.Append(extension_info);
728 CallClientFunction("WebInspector.addExtensions", &results, NULL, NULL);
731 void DevToolsUIBindings::SetDelegate(Delegate* delegate) {
732 delegate_.reset(delegate);
735 void DevToolsUIBindings::CallClientFunction(const std::string& function_name,
736 const base::Value* arg1,
737 const base::Value* arg2,
738 const base::Value* arg3) {
739 std::string params;
740 if (arg1) {
741 std::string json;
742 base::JSONWriter::Write(arg1, &json);
743 params.append(json);
744 if (arg2) {
745 base::JSONWriter::Write(arg2, &json);
746 params.append(", " + json);
747 if (arg3) {
748 base::JSONWriter::Write(arg3, &json);
749 params.append(", " + json);
753 base::string16 javascript =
754 base::UTF8ToUTF16(function_name + "(" + params + ");");
755 web_contents_->GetMainFrame()->ExecuteJavaScript(javascript);
758 void DevToolsUIBindings::DocumentOnLoadCompletedInMainFrame() {
759 // Call delegate first - it seeds importants bit of information.
760 delegate_->OnLoadCompleted();
762 UpdateTheme();
763 AddDevToolsExtensionsToClient();