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/extensions/chrome_extension_web_contents_observer.h"
17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/themes/theme_properties.h"
22 #include "chrome/browser/themes/theme_service.h"
23 #include "chrome/browser/themes/theme_service_factory.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_iterator.h"
26 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/extensions/manifest_url_handler.h"
31 #include "chrome/common/url_constants.h"
32 #include "components/infobars/core/infobar.h"
33 #include "content/public/browser/devtools_client_host.h"
34 #include "content/public/browser/devtools_manager.h"
35 #include "content/public/browser/favicon_status.h"
36 #include "content/public/browser/navigation_controller.h"
37 #include "content/public/browser/navigation_entry.h"
38 #include "content/public/browser/notification_source.h"
39 #include "content/public/browser/render_frame_host.h"
40 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/user_metrics.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/browser/web_contents_observer.h"
44 #include "content/public/browser/web_contents_view.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
;
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(
88 if (tab_index
!= TabStripModel::kNoTab
)
94 // DevToolsConfirmInfoBarDelegate ---------------------------------------------
96 typedef base::Callback
<void(bool)> InfoBarCallback
;
98 class DevToolsConfirmInfoBarDelegate
: public ConfirmInfoBarDelegate
{
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
);
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
) {
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(),
146 DevToolsConfirmInfoBarDelegate::~DevToolsConfirmInfoBarDelegate() {
147 if (!callback_
.is_null())
148 callback_
.Run(false);
151 base::string16
DevToolsConfirmInfoBarDelegate::GetMessageText() const {
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() {
167 bool DevToolsConfirmInfoBarDelegate::Cancel() {
168 callback_
.Run(false);
173 // DevToolsUIDefaultDelegate --------------------------------------------------
175 class DefaultBindingsDelegate
: public DevToolsUIBindings::Delegate
{
177 explicit DefaultBindingsDelegate(content::WebContents
* web_contents
)
178 : web_contents_(web_contents
) {}
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
{}
198 content::WebContents
* web_contents_
;
199 DISALLOW_COPY_AND_ASSIGN(DefaultBindingsDelegate
);
202 void DefaultBindingsDelegate::ActivateWindow() {
203 web_contents_
->GetDelegate()->ActivateContents(web_contents_
);
204 web_contents_
->GetView()->Focus();
207 void DefaultBindingsDelegate::OpenInNewTab(const std::string
& url
) {
208 content::OpenURLParams
params(
209 GURL(url
), content::Referrer(), NEW_FOREGROUND_TAB
,
210 content::PAGE_TRANSITION_LINK
, false);
211 Browser
* browser
= FindBrowser(web_contents_
);
212 browser
->OpenURL(params
);
215 void DefaultBindingsDelegate::InspectedContentsClosing() {
216 web_contents_
->GetRenderViewHost()->ClosePage();
221 // DevToolsUIBindings::FrontendWebContentsObserver ----------------------------
223 class DevToolsUIBindings::FrontendWebContentsObserver
224 : public content::WebContentsObserver
{
226 explicit FrontendWebContentsObserver(DevToolsUIBindings
* window
);
227 virtual ~FrontendWebContentsObserver();
230 // contents::WebContentsObserver:
231 virtual void AboutToNavigateRenderView(
232 content::RenderViewHost
* render_view_host
) OVERRIDE
;
233 virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id
) OVERRIDE
;
235 DevToolsUIBindings
* devtools_bindings_
;
236 DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver
);
239 DevToolsUIBindings::FrontendWebContentsObserver::FrontendWebContentsObserver(
240 DevToolsUIBindings
* devtools_window
)
241 : WebContentsObserver(devtools_window
->web_contents()),
242 devtools_bindings_(devtools_window
) {
245 DevToolsUIBindings::FrontendWebContentsObserver::
246 ~FrontendWebContentsObserver() {
249 void DevToolsUIBindings::FrontendWebContentsObserver::AboutToNavigateRenderView(
250 content::RenderViewHost
* render_view_host
) {
251 content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host
);
254 void DevToolsUIBindings::FrontendWebContentsObserver::
255 DocumentOnLoadCompletedInMainFrame(int32 page_id
) {
256 devtools_bindings_
->DocumentOnLoadCompletedInMainFrame();
259 // DevToolsUIBindings ---------------------------------------------------------
262 DevToolsUIBindings
* DevToolsUIBindings::ForWebContents(
263 content::WebContents
* web_contents
) {
264 DevToolsUIBindingsList
* instances
= g_instances
.Pointer();
265 for (DevToolsUIBindingsList::iterator
it(instances
->begin());
266 it
!= instances
->end(); ++it
) {
267 if ((*it
)->web_contents() == web_contents
)
274 GURL
DevToolsUIBindings::ApplyThemeToURL(Profile
* profile
,
275 const GURL
& base_url
) {
276 std::string frontend_url
= base_url
.spec();
277 ThemeService
* tp
= ThemeServiceFactory::GetForProfile(profile
);
279 std::string
url_string(
281 ((frontend_url
.find("?") == std::string::npos
) ? "?" : "&") +
282 "dockSide=undocked" + // TODO(dgozman): remove this support in M38.
284 SkColorToRGBAString(tp
->GetColor(ThemeProperties::COLOR_TOOLBAR
)) +
286 SkColorToRGBAString(tp
->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT
)));
287 if (CommandLine::ForCurrentProcess()->HasSwitch(
288 switches::kEnableDevToolsExperiments
))
289 url_string
+= "&experiments=true";
290 return GURL(url_string
);
293 DevToolsUIBindings::DevToolsUIBindings(content::WebContents
* web_contents
)
294 : profile_(Profile::FromBrowserContext(web_contents
->GetBrowserContext())),
295 web_contents_(web_contents
),
296 delegate_(new DefaultBindingsDelegate(web_contents_
)),
297 device_listener_enabled_(false),
298 weak_factory_(this) {
299 g_instances
.Get().push_back(this);
300 frontend_contents_observer_
.reset(new FrontendWebContentsObserver(this));
301 web_contents_
->GetMutableRendererPrefs()->can_accept_load_drops
= false;
303 frontend_host_
.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost(
304 web_contents_
, this));
305 file_helper_
.reset(new DevToolsFileHelper(web_contents_
, profile_
));
306 file_system_indexer_
= new DevToolsFileSystemIndexer();
307 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
310 // Wipe out page icon so that the default application icon is used.
311 content::NavigationEntry
* entry
=
312 web_contents_
->GetController().GetActiveEntry();
313 entry
->GetFavicon().image
= gfx::Image();
314 entry
->GetFavicon().valid
= true;
316 // Register on-load actions.
318 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED
,
319 content::Source
<ThemeService
>(
320 ThemeServiceFactory::GetForProfile(profile_
)));
322 embedder_message_dispatcher_
.reset(
323 DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this));
326 DevToolsUIBindings::~DevToolsUIBindings() {
327 content::DevToolsManager::GetInstance()->ClientHostClosing(
328 frontend_host_
.get());
330 for (IndexingJobsMap::const_iterator
jobs_it(indexing_jobs_
.begin());
331 jobs_it
!= indexing_jobs_
.end(); ++jobs_it
) {
332 jobs_it
->second
->Stop();
334 indexing_jobs_
.clear();
335 if (device_listener_enabled_
)
336 EnableRemoteDeviceCounter(false);
338 // Remove self from global list.
339 DevToolsUIBindingsList
* instances
= g_instances
.Pointer();
340 DevToolsUIBindingsList::iterator
it(
341 std::find(instances
->begin(), instances
->end(), this));
342 DCHECK(it
!= instances
->end());
343 instances
->erase(it
);
346 void DevToolsUIBindings::InspectedContentsClosing() {
347 delegate_
->InspectedContentsClosing();
350 void DevToolsUIBindings::Observe(int type
,
351 const content::NotificationSource
& source
,
352 const content::NotificationDetails
& details
) {
353 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED
, type
);
357 void DevToolsUIBindings::DispatchOnEmbedder(const std::string
& message
) {
359 base::ListValue empty_params
;
360 base::ListValue
* params
= &empty_params
;
362 base::DictionaryValue
* dict
= NULL
;
363 scoped_ptr
<base::Value
> parsed_message(base::JSONReader::Read(message
));
364 if (!parsed_message
||
365 !parsed_message
->GetAsDictionary(&dict
) ||
366 !dict
->GetString(kFrontendHostMethod
, &method
) ||
367 (dict
->HasKey(kFrontendHostParams
) &&
368 !dict
->GetList(kFrontendHostParams
, ¶ms
))) {
369 LOG(ERROR
) << "Invalid message was sent to embedder: " << message
;
374 dict
->GetInteger(kFrontendHostId
, &id
);
377 embedder_message_dispatcher_
->Dispatch(method
, params
, &error
);
379 scoped_ptr
<base::Value
> id_value(base::Value::CreateIntegerValue(id
));
380 scoped_ptr
<base::Value
> error_value(base::Value::CreateStringValue(error
));
381 CallClientFunction("InspectorFrontendAPI.embedderMessageAck",
382 id_value
.get(), error_value
.get(), NULL
);
386 void DevToolsUIBindings::ActivateWindow() {
387 delegate_
->ActivateWindow();
390 void DevToolsUIBindings::CloseWindow() {
391 delegate_
->ActivateWindow();
394 void DevToolsUIBindings::SetContentsInsets(
395 int top
, int left
, int bottom
, int right
) {
396 delegate_
->SetContentsInsets(top
, left
, bottom
, right
);
399 void DevToolsUIBindings::SetContentsResizingStrategy(
400 const gfx::Insets
& insets
, const gfx::Size
& min_size
) {
401 delegate_
->SetContentsResizingStrategy(insets
, min_size
);
404 void DevToolsUIBindings::MoveWindow(int x
, int y
) {
405 delegate_
->MoveWindow(x
, y
);
408 void DevToolsUIBindings::SetIsDocked(bool dock_requested
) {
409 delegate_
->SetIsDocked(dock_requested
);
412 void DevToolsUIBindings::InspectElementCompleted() {
413 delegate_
->InspectElementCompleted();
416 void DevToolsUIBindings::OpenInNewTab(const std::string
& url
) {
417 delegate_
->OpenInNewTab(url
);
420 void DevToolsUIBindings::SaveToFile(const std::string
& url
,
421 const std::string
& content
,
423 file_helper_
->Save(url
, content
, save_as
,
424 base::Bind(&DevToolsUIBindings::FileSavedAs
,
425 weak_factory_
.GetWeakPtr(), url
),
426 base::Bind(&DevToolsUIBindings::CanceledFileSaveAs
,
427 weak_factory_
.GetWeakPtr(), url
));
430 void DevToolsUIBindings::AppendToFile(const std::string
& url
,
431 const std::string
& content
) {
432 file_helper_
->Append(url
, content
,
433 base::Bind(&DevToolsUIBindings::AppendedTo
,
434 weak_factory_
.GetWeakPtr(), url
));
437 void DevToolsUIBindings::RequestFileSystems() {
438 CHECK(web_contents_
->GetURL().SchemeIs(content::kChromeDevToolsScheme
));
439 file_helper_
->RequestFileSystems(base::Bind(
440 &DevToolsUIBindings::FileSystemsLoaded
, weak_factory_
.GetWeakPtr()));
443 void DevToolsUIBindings::AddFileSystem() {
444 CHECK(web_contents_
->GetURL().SchemeIs(content::kChromeDevToolsScheme
));
445 file_helper_
->AddFileSystem(
446 base::Bind(&DevToolsUIBindings::FileSystemAdded
,
447 weak_factory_
.GetWeakPtr()),
448 base::Bind(&DevToolsUIBindings::ShowDevToolsConfirmInfoBar
,
449 weak_factory_
.GetWeakPtr()));
452 void DevToolsUIBindings::RemoveFileSystem(
453 const std::string
& file_system_path
) {
454 CHECK(web_contents_
->GetURL().SchemeIs(content::kChromeDevToolsScheme
));
455 file_helper_
->RemoveFileSystem(file_system_path
);
456 base::StringValue
file_system_path_value(file_system_path
);
457 CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
458 &file_system_path_value
, NULL
, NULL
);
461 void DevToolsUIBindings::UpgradeDraggedFileSystemPermissions(
462 const std::string
& file_system_url
) {
463 CHECK(web_contents_
->GetURL().SchemeIs(content::kChromeDevToolsScheme
));
464 file_helper_
->UpgradeDraggedFileSystemPermissions(
466 base::Bind(&DevToolsUIBindings::FileSystemAdded
,
467 weak_factory_
.GetWeakPtr()),
468 base::Bind(&DevToolsUIBindings::ShowDevToolsConfirmInfoBar
,
469 weak_factory_
.GetWeakPtr()));
472 void DevToolsUIBindings::IndexPath(int request_id
,
473 const std::string
& file_system_path
) {
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
475 CHECK(web_contents_
->GetURL().SchemeIs(content::kChromeDevToolsScheme
));
476 if (!file_helper_
->IsFileSystemAdded(file_system_path
)) {
477 IndexingDone(request_id
, file_system_path
);
480 indexing_jobs_
[request_id
] =
481 scoped_refptr
<DevToolsFileSystemIndexer::FileSystemIndexingJob
>(
482 file_system_indexer_
->IndexPath(
484 Bind(&DevToolsUIBindings::IndexingTotalWorkCalculated
,
485 weak_factory_
.GetWeakPtr(),
488 Bind(&DevToolsUIBindings::IndexingWorked
,
489 weak_factory_
.GetWeakPtr(),
492 Bind(&DevToolsUIBindings::IndexingDone
,
493 weak_factory_
.GetWeakPtr(),
498 void DevToolsUIBindings::StopIndexing(int request_id
) {
499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
500 IndexingJobsMap::iterator it
= indexing_jobs_
.find(request_id
);
501 if (it
== indexing_jobs_
.end())
504 indexing_jobs_
.erase(it
);
507 void DevToolsUIBindings::SearchInPath(int request_id
,
508 const std::string
& file_system_path
,
509 const std::string
& query
) {
510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
511 CHECK(web_contents_
->GetURL().SchemeIs(content::kChromeDevToolsScheme
));
512 if (!file_helper_
->IsFileSystemAdded(file_system_path
)) {
513 SearchCompleted(request_id
, file_system_path
, std::vector
<std::string
>());
516 file_system_indexer_
->SearchInPath(file_system_path
,
518 Bind(&DevToolsUIBindings::SearchCompleted
,
519 weak_factory_
.GetWeakPtr(),
524 void DevToolsUIBindings::SetWhitelistedShortcuts(
525 const std::string
& message
) {
528 void DevToolsUIBindings::ZoomIn() {
529 chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_IN
);
532 void DevToolsUIBindings::ZoomOut() {
533 chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT
);
536 void DevToolsUIBindings::ResetZoom() {
537 chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET
);
540 void DevToolsUIBindings::OpenUrlOnRemoteDeviceAndInspect(
541 const std::string
& browser_id
,
542 const std::string
& url
) {
543 if (remote_targets_handler_
)
544 remote_targets_handler_
->OpenAndInspect(browser_id
, url
, profile_
);
547 void DevToolsUIBindings::StartRemoteDevicesListener() {
548 remote_targets_handler_
= DevToolsTargetsUIHandler::CreateForAdb(
549 base::Bind(&DevToolsUIBindings::PopulateRemoteDevices
,
550 base::Unretained(this)),
554 void DevToolsUIBindings::StopRemoteDevicesListener() {
555 remote_targets_handler_
.reset();
558 void DevToolsUIBindings::EnableRemoteDeviceCounter(bool enable
) {
559 DevToolsAndroidBridge
* adb_bridge
=
560 DevToolsAndroidBridge::Factory::GetForProfile(profile_
);
564 DCHECK(device_listener_enabled_
!= enable
);
565 device_listener_enabled_
= enable
;
567 adb_bridge
->AddDeviceCountListener(this);
569 adb_bridge
->RemoveDeviceCountListener(this);
572 void DevToolsUIBindings::DeviceCountChanged(int count
) {
573 base::FundamentalValue
value(count
);
575 "InspectorFrontendAPI.setRemoteDeviceCount", &value
, NULL
, NULL
);
578 void DevToolsUIBindings::PopulateRemoteDevices(
579 const std::string
& source
,
580 scoped_ptr
<base::ListValue
> targets
) {
582 "InspectorFrontendAPI.populateRemoteDevices", targets
.get(), NULL
, NULL
);
585 void DevToolsUIBindings::FileSavedAs(const std::string
& url
) {
586 base::StringValue
url_value(url
);
587 CallClientFunction("InspectorFrontendAPI.savedURL", &url_value
, NULL
, NULL
);
590 void DevToolsUIBindings::CanceledFileSaveAs(const std::string
& url
) {
591 base::StringValue
url_value(url
);
592 CallClientFunction("InspectorFrontendAPI.canceledSaveURL",
593 &url_value
, NULL
, NULL
);
596 void DevToolsUIBindings::AppendedTo(const std::string
& url
) {
597 base::StringValue
url_value(url
);
598 CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value
, NULL
,
602 void DevToolsUIBindings::FileSystemsLoaded(
603 const std::vector
<DevToolsFileHelper::FileSystem
>& file_systems
) {
604 base::ListValue file_systems_value
;
605 for (size_t i
= 0; i
< file_systems
.size(); ++i
)
606 file_systems_value
.Append(CreateFileSystemValue(file_systems
[i
]));
607 CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
608 &file_systems_value
, NULL
, NULL
);
611 void DevToolsUIBindings::FileSystemAdded(
612 const DevToolsFileHelper::FileSystem
& file_system
) {
613 scoped_ptr
<base::StringValue
> error_string_value(
614 new base::StringValue(std::string()));
615 scoped_ptr
<base::DictionaryValue
> file_system_value
;
616 if (!file_system
.file_system_path
.empty())
617 file_system_value
.reset(CreateFileSystemValue(file_system
));
618 CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
619 error_string_value
.get(), file_system_value
.get(), NULL
);
622 void DevToolsUIBindings::IndexingTotalWorkCalculated(
624 const std::string
& file_system_path
,
626 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
627 base::FundamentalValue
request_id_value(request_id
);
628 base::StringValue
file_system_path_value(file_system_path
);
629 base::FundamentalValue
total_work_value(total_work
);
630 CallClientFunction("InspectorFrontendAPI.indexingTotalWorkCalculated",
631 &request_id_value
, &file_system_path_value
,
635 void DevToolsUIBindings::IndexingWorked(int request_id
,
636 const std::string
& file_system_path
,
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
worked_value(worked
);
642 CallClientFunction("InspectorFrontendAPI.indexingWorked", &request_id_value
,
643 &file_system_path_value
, &worked_value
);
646 void DevToolsUIBindings::IndexingDone(int request_id
,
647 const std::string
& file_system_path
) {
648 indexing_jobs_
.erase(request_id
);
649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
650 base::FundamentalValue
request_id_value(request_id
);
651 base::StringValue
file_system_path_value(file_system_path
);
652 CallClientFunction("InspectorFrontendAPI.indexingDone", &request_id_value
,
653 &file_system_path_value
, NULL
);
656 void DevToolsUIBindings::SearchCompleted(
658 const std::string
& file_system_path
,
659 const std::vector
<std::string
>& file_paths
) {
660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
661 base::ListValue file_paths_value
;
662 for (std::vector
<std::string
>::const_iterator
it(file_paths
.begin());
663 it
!= file_paths
.end(); ++it
) {
664 file_paths_value
.AppendString(*it
);
666 base::FundamentalValue
request_id_value(request_id
);
667 base::StringValue
file_system_path_value(file_system_path
);
668 CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value
,
669 &file_system_path_value
, &file_paths_value
);
672 void DevToolsUIBindings::ShowDevToolsConfirmInfoBar(
673 const base::string16
& message
,
674 const InfoBarCallback
& callback
) {
675 DevToolsConfirmInfoBarDelegate::Create(
676 InfoBarService::FromWebContents(web_contents_
),
680 void DevToolsUIBindings::UpdateTheme() {
681 ThemeService
* tp
= ThemeServiceFactory::GetForProfile(profile_
);
684 std::string
command("InspectorFrontendAPI.setToolbarColors(\"" +
685 SkColorToRGBAString(tp
->GetColor(ThemeProperties::COLOR_TOOLBAR
)) +
687 SkColorToRGBAString(tp
->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT
)) +
689 web_contents_
->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16(command
));
692 void DevToolsUIBindings::AddDevToolsExtensionsToClient() {
693 const ExtensionService
* extension_service
= extensions::ExtensionSystem::Get(
694 profile_
->GetOriginalProfile())->extension_service();
695 if (!extension_service
)
697 const extensions::ExtensionSet
* extensions
= extension_service
->extensions();
699 base::ListValue results
;
700 for (extensions::ExtensionSet::const_iterator
extension(extensions
->begin());
701 extension
!= extensions
->end(); ++extension
) {
702 if (extensions::ManifestURL::GetDevToolsPage(extension
->get()).is_empty())
704 base::DictionaryValue
* extension_info
= new base::DictionaryValue();
707 new base::StringValue(
708 extensions::ManifestURL::GetDevToolsPage(
709 extension
->get()).spec()));
710 extension_info
->Set("name", new base::StringValue((*extension
)->name()));
712 "exposeExperimentalAPIs",
713 new base::FundamentalValue((*extension
)->HasAPIPermission(
714 extensions::APIPermission::kExperimental
)));
715 results
.Append(extension_info
);
717 CallClientFunction("WebInspector.addExtensions", &results
, NULL
, NULL
);
720 void DevToolsUIBindings::SetDelegate(Delegate
* delegate
) {
721 delegate_
.reset(delegate
);
724 void DevToolsUIBindings::CallClientFunction(const std::string
& function_name
,
725 const base::Value
* arg1
,
726 const base::Value
* arg2
,
727 const base::Value
* arg3
) {
731 base::JSONWriter::Write(arg1
, &json
);
734 base::JSONWriter::Write(arg2
, &json
);
735 params
.append(", " + json
);
737 base::JSONWriter::Write(arg3
, &json
);
738 params
.append(", " + json
);
742 base::string16 javascript
=
743 base::UTF8ToUTF16(function_name
+ "(" + params
+ ");");
744 web_contents_
->GetMainFrame()->ExecuteJavaScript(javascript
);
747 void DevToolsUIBindings::DocumentOnLoadCompletedInMainFrame() {
748 // Call delegate first - it seeds importants bit of information.
749 delegate_
->OnLoadCompleted();
752 AddDevToolsExtensionsToClient();