OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/browser/devtools/renderer_overrides_handler.h" | 5 #include "content/browser/devtools/renderer_overrides_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/message_loop/message_loop_proxy.h" | |
13 #include "base/strings/string16.h" | 14 #include "base/strings/string16.h" |
14 #include "base/values.h" | 15 #include "base/values.h" |
15 #include "content/browser/child_process_security_policy_impl.h" | 16 #include "content/browser/child_process_security_policy_impl.h" |
16 #include "content/browser/devtools/devtools_protocol_constants.h" | 17 #include "content/browser/devtools/devtools_protocol_constants.h" |
17 #include "content/browser/devtools/devtools_tracing_handler.h" | 18 #include "content/browser/devtools/devtools_tracing_handler.h" |
18 #include "content/browser/renderer_host/dip_util.h" | 19 #include "content/browser/renderer_host/dip_util.h" |
19 #include "content/browser/renderer_host/render_view_host_delegate.h" | 20 #include "content/browser/renderer_host/render_view_host_delegate.h" |
20 #include "content/port/browser/render_widget_host_view_port.h" | 21 #include "content/port/browser/render_widget_host_view_port.h" |
21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
22 #include "content/public/browser/devtools_agent_host.h" | 23 #include "content/public/browser/devtools_agent_host.h" |
23 #include "content/public/browser/javascript_dialog_manager.h" | 24 #include "content/public/browser/javascript_dialog_manager.h" |
24 #include "content/public/browser/navigation_controller.h" | 25 #include "content/public/browser/navigation_controller.h" |
25 #include "content/public/browser/render_process_host.h" | 26 #include "content/public/browser/render_process_host.h" |
26 #include "content/public/browser/render_view_host.h" | 27 #include "content/public/browser/render_view_host.h" |
27 #include "content/public/browser/render_widget_host_view.h" | 28 #include "content/public/browser/render_widget_host_view.h" |
29 #include "content/public/browser/storage_partition.h" | |
28 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
29 #include "content/public/browser/web_contents_delegate.h" | 31 #include "content/public/browser/web_contents_delegate.h" |
30 #include "content/public/common/page_transition_types.h" | 32 #include "content/public/common/page_transition_types.h" |
31 #include "content/public/common/referrer.h" | 33 #include "content/public/common/referrer.h" |
34 #include "net/base/net_util.h" | |
32 #include "third_party/WebKit/public/web/WebInputEvent.h" | 35 #include "third_party/WebKit/public/web/WebInputEvent.h" |
33 #include "ui/gfx/codec/jpeg_codec.h" | 36 #include "ui/gfx/codec/jpeg_codec.h" |
34 #include "ui/gfx/codec/png_codec.h" | 37 #include "ui/gfx/codec/png_codec.h" |
35 #include "ui/gfx/size_conversions.h" | 38 #include "ui/gfx/size_conversions.h" |
36 #include "ui/snapshot/snapshot.h" | 39 #include "ui/snapshot/snapshot.h" |
37 #include "url/gurl.h" | 40 #include "url/gurl.h" |
41 #include "webkit/browser/quota/quota_manager.h" | |
38 | 42 |
39 using WebKit::WebGestureEvent; | 43 using WebKit::WebGestureEvent; |
40 using WebKit::WebInputEvent; | 44 using WebKit::WebInputEvent; |
41 using WebKit::WebMouseEvent; | 45 using WebKit::WebMouseEvent; |
42 | 46 |
43 namespace content { | 47 namespace content { |
44 | 48 |
45 namespace { | 49 namespace { |
46 | 50 |
47 static const char kPng[] = "png"; | 51 static const char kPng[] = "png"; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 devtools::Page::startScreencast::kName, | 127 devtools::Page::startScreencast::kName, |
124 base::Bind( | 128 base::Bind( |
125 &RendererOverridesHandler::PageStartScreencast, | 129 &RendererOverridesHandler::PageStartScreencast, |
126 base::Unretained(this))); | 130 base::Unretained(this))); |
127 RegisterCommandHandler( | 131 RegisterCommandHandler( |
128 devtools::Page::stopScreencast::kName, | 132 devtools::Page::stopScreencast::kName, |
129 base::Bind( | 133 base::Bind( |
130 &RendererOverridesHandler::PageStopScreencast, | 134 &RendererOverridesHandler::PageStopScreencast, |
131 base::Unretained(this))); | 135 base::Unretained(this))); |
132 RegisterCommandHandler( | 136 RegisterCommandHandler( |
137 devtools::Quota::queryUsageAndQuota::kName, | |
138 base::Bind( | |
139 &RendererOverridesHandler::QuotaQueryUsageAndQuota, | |
140 base::Unretained(this))); | |
141 RegisterCommandHandler( | |
133 devtools::Input::dispatchMouseEvent::kName, | 142 devtools::Input::dispatchMouseEvent::kName, |
134 base::Bind( | 143 base::Bind( |
135 &RendererOverridesHandler::InputDispatchMouseEvent, | 144 &RendererOverridesHandler::InputDispatchMouseEvent, |
136 base::Unretained(this))); | 145 base::Unretained(this))); |
137 } | 146 } |
138 | 147 |
139 RendererOverridesHandler::~RendererOverridesHandler() {} | 148 RendererOverridesHandler::~RendererOverridesHandler() {} |
140 | 149 |
141 void RendererOverridesHandler::OnClientDetached() { | 150 void RendererOverridesHandler::OnClientDetached() { |
142 screencast_command_ = NULL; | 151 screencast_command_ = NULL; |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 response->SetString( | 388 response->SetString( |
380 devtools::Page::captureScreenshot::kResponseData, base_64_data); | 389 devtools::Page::captureScreenshot::kResponseData, base_64_data); |
381 SendAsyncResponse(command->SuccessResponse(response)); | 390 SendAsyncResponse(command->SuccessResponse(response)); |
382 } else { | 391 } else { |
383 response->SetString( | 392 response->SetString( |
384 devtools::Page::screencastFrame::kResponseData, base_64_data); | 393 devtools::Page::screencastFrame::kResponseData, base_64_data); |
385 SendNotification(devtools::Page::screencastFrame::kName, response); | 394 SendNotification(devtools::Page::screencastFrame::kName, response); |
386 } | 395 } |
387 } | 396 } |
388 | 397 |
398 namespace { | |
Vladislav Kaznacheev
2013/08/28 10:46:14
This namespace is 200 lines of very task-specific
SeRya
2013/08/29 14:24:16
Only 60 likes are quite generic (QuotaTask), 120 l
| |
399 | |
400 typedef base::Callback<void (DevToolsProtocol::Response*)> RespondCallback; | |
401 | |
402 class QuotaTask { | |
403 public: | |
404 virtual ~QuotaTask() {} | |
405 | |
406 static void Run(scoped_ptr<QuotaTask> task) { | |
407 // Will be deleted when done. | |
408 BrowserThread::PostTask( | |
409 BrowserThread::IO, FROM_HERE, | |
410 base::Bind(&QuotaTask::Start, base::Unretained(task.release()))); | |
411 } | |
412 | |
413 protected: | |
414 QuotaTask(scoped_refptr<DevToolsProtocol::Command> command, | |
415 const RespondCallback& callback, | |
416 RenderViewHost* render_vew_host, | |
417 const std::string& security_origin) | |
418 : command_(command), | |
419 callback_(callback), | |
420 host_(net::GetHostOrSpecFromURL(GURL(security_origin))), | |
421 quota_manager_(render_vew_host->GetProcess()-> | |
422 GetStoragePartition()->GetQuotaManager()), | |
423 response_loop_proxy_(base::MessageLoopProxy::current()) { | |
Vladislav Kaznacheev
2013/08/28 10:46:14
Looks a bit over-engineered. I assume that the cal
SeRya
2013/08/29 14:24:16
I'm a bit hesitate to introduce first thread depen
| |
424 | |
425 } | |
426 | |
427 // Called on IO thread. | |
428 virtual void Start() = 0; | |
429 | |
430 void Done(scoped_ptr<base::DictionaryValue> responseData) { | |
431 base::MessageLoopProxy* loop = response_loop_proxy_.get(); | |
432 loop->PostTask(FROM_HERE, base::Bind( | |
433 &QuotaTask::ResponseOnCallerThreadAndDelete, | |
434 this, base::Passed(&responseData))); | |
435 } | |
436 | |
437 quota::QuotaManager* GetQuotaManager() { return quota_manager_.get(); } | |
438 const std::string& host() const { return host_; } | |
439 | |
440 private: | |
441 scoped_refptr<DevToolsProtocol::Command> command_; | |
442 RespondCallback callback_; | |
443 | |
444 std::string host_; | |
445 scoped_refptr<quota::QuotaManager> quota_manager_; | |
446 | |
447 scoped_refptr<base::MessageLoopProxy> response_loop_proxy_; | |
448 | |
449 void ResponseOnCallerThread(scoped_ptr<base::DictionaryValue> response) { | |
Vladislav Kaznacheev
2013/08/28 10:46:14
RespondOnCallerThread is better English
SeRya
2013/08/29 14:24:16
Done.
| |
450 callback_.Run(command_->SuccessResponse(response.release()).get()); | |
451 } | |
452 | |
453 static void ResponseOnCallerThreadAndDelete(QuotaTask* task, | |
Vladislav Kaznacheev
2013/08/28 10:46:14
RespondOnCallerThreadAndDelete is better English
SeRya
2013/08/29 14:24:16
Done.
| |
454 scoped_ptr<base::DictionaryValue> responseData) { | |
455 task->ResponseOnCallerThread(responseData.Pass()); | |
456 delete task; | |
457 } | |
458 }; | |
459 | |
460 class GetUsageAndQuotaTask : public QuotaTask { | |
461 public: | |
462 GetUsageAndQuotaTask(scoped_refptr<DevToolsProtocol::Command> command, | |
463 const RespondCallback& callback, | |
464 RenderViewHost* render_vew_host, | |
465 const std::string& security_origin) | |
466 : QuotaTask(command, callback, render_vew_host, security_origin), | |
467 quota_(new base::DictionaryValue), | |
468 usage_(new base::DictionaryValue) { | |
469 } | |
470 | |
471 protected: | |
472 virtual void Start() OVERRIDE { | |
473 step_ = 0; | |
474 readyToNextStep_ = true; | |
Vladislav Kaznacheev
2013/08/28 10:46:14
readyForNextStep
SeRya
2013/08/29 14:24:16
Done.
| |
475 stepDone_ = true; | |
476 DoStep(); | |
477 } | |
478 | |
479 private: | |
480 scoped_ptr<base::DictionaryValue> quota_; | |
481 scoped_ptr<base::DictionaryValue> usage_; | |
482 bool readyToNextStep_; | |
483 bool stepDone_; | |
484 int step_; | |
485 | |
486 void DoStep() { | |
487 DCHECK(readyToNextStep_); | |
488 DCHECK(stepDone_); | |
489 readyToNextStep_ = false; | |
490 stepDone_ = false; | |
491 int startStep = step_; | |
492 | |
493 switch (step_) { | |
Vladislav Kaznacheev
2013/08/28 10:46:14
This switch makes me sad. Please consider replacin
SeRya
2013/08/29 14:24:16
Done.
| |
494 case 0: | |
495 GetQuotaManager()->GetAvailableSpace( | |
496 MakeQuotaCallback("availableSpace")); | |
497 break; | |
498 | |
499 case 1: | |
500 GetQuotaManager()->GetTemporaryGlobalQuota( | |
501 MakeQuotaCallback("temporaryGlobalQuota")); | |
502 break; | |
503 | |
504 case 2: | |
505 GetQuotaManager()->GetPersistentHostQuota(host(), | |
506 MakeQuotaCallback("persistentHostQuota")); | |
507 break; | |
508 | |
509 case 3: | |
510 GetQuotaManager()->GetHostUsage(host(), | |
511 quota::kStorageTypeTemporary, | |
512 quota::QuotaClient::kFileSystem, | |
513 MakeUsageCallback("temporaryFileSystemUsage")); | |
514 break; | |
515 | |
516 case 4: | |
517 GetQuotaManager()->GetHostUsage(host(), | |
518 quota::kStorageTypePersistent, | |
519 quota::QuotaClient::kFileSystem, | |
520 MakeUsageCallback("persistentFileSystemUsage")); | |
521 break; | |
522 | |
523 case 5: | |
524 GetQuotaManager()->GetHostUsage(host(), | |
525 quota::kStorageTypeSyncable, | |
526 quota::QuotaClient::kFileSystem, | |
527 MakeUsageCallback("syncableFileSystemUsage")); | |
528 break; | |
529 | |
530 case 6: | |
531 GetQuotaManager()->GetHostUsage(host(), | |
532 quota::kStorageTypeTemporary, | |
533 quota::QuotaClient::kDatabase, | |
534 MakeUsageCallback("databaseUsage")); | |
535 break; | |
536 | |
537 case 7: | |
538 GetQuotaManager()->GetHostUsage(host(), | |
539 quota::kStorageTypeTemporary, | |
540 quota::QuotaClient::kAppcache, | |
541 MakeUsageCallback("appcacheUsage")); | |
542 break; | |
543 | |
544 case 8: | |
545 GetQuotaManager()->GetHostUsage(host(), | |
546 quota::kStorageTypeTemporary, | |
547 quota::QuotaClient::kIndexedDatabase, | |
548 MakeUsageCallback("indexedDatabaseUsage")); | |
549 break; | |
550 | |
551 case 9: { | |
552 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); | |
553 result->Set("quota", quota_.release()); | |
554 result->Set("usage", usage_.release()); | |
555 Done(result.Pass()); | |
556 } | |
557 } | |
558 | |
559 readyToNextStep_ = true; | |
560 if (stepDone_) { | |
561 DCHECK(step_ == startStep + 1); | |
562 DoStep(); | |
563 } | |
564 } | |
565 | |
566 void StepDone() { | |
567 DCHECK(!stepDone_); | |
568 step_++; | |
569 stepDone_ = true; | |
570 if (readyToNextStep_) | |
571 DoStep(); | |
572 } | |
573 | |
574 void DidGetQuota(const char* name, | |
575 quota::QuotaStatusCode status, | |
576 int64 space) { | |
577 if (status == quota::kQuotaStatusOk) | |
578 quota_->SetDouble(name, space); | |
579 StepDone(); | |
580 } | |
581 | |
582 quota::QuotaCallback MakeQuotaCallback(const char* name) { | |
583 return base::Bind(&GetUsageAndQuotaTask::DidGetQuota, | |
584 base::Unretained(this), name); | |
585 } | |
586 | |
587 void DidGetUsage(const char* name, int64 usage_value) { | |
588 usage_->SetDouble(name, usage_value); | |
589 StepDone(); | |
590 } | |
591 | |
592 quota::UsageCallback MakeUsageCallback(const char* name) { | |
593 return base::Bind(&GetUsageAndQuotaTask::DidGetUsage, | |
594 base::Unretained(this), name); | |
595 } | |
596 }; | |
597 | |
598 } // namespace | |
599 | |
600 scoped_refptr<DevToolsProtocol::Response> | |
601 RendererOverridesHandler::QuotaQueryUsageAndQuota( | |
602 scoped_refptr<DevToolsProtocol::Command> command) { | |
603 base::DictionaryValue* params = command->params(); | |
604 std::string security_origin; | |
605 if (!params || !params->GetString( | |
606 devtools::Quota::queryUsageAndQuota::kParamSecurityOrigin, | |
607 &security_origin)) { | |
608 return command->InvalidParamResponse( | |
609 devtools::Quota::queryUsageAndQuota::kParamSecurityOrigin); | |
610 } | |
611 | |
612 RespondCallback callback = base::Bind( | |
613 &RendererOverridesHandler::AsyncTaskDone, base::Unretained(this)); | |
Vladislav Kaznacheev
2013/08/28 10:46:14
base::Unretained allows this to be deleted before
SeRya
2013/08/29 14:24:16
Good catch. Thanks.
| |
614 QuotaTask::Run(scoped_ptr<QuotaTask>(new GetUsageAndQuotaTask(command, | |
615 callback, agent_->GetRenderViewHost(), security_origin))); | |
616 return command->AsyncResponsePromise(); | |
617 } | |
618 | |
619 void RendererOverridesHandler::AsyncTaskDone( | |
620 DevToolsProtocol::Response* response) { | |
621 SendRawMessage(response->Serialize()); | |
622 } | |
389 | 623 |
390 // Input agent handlers ------------------------------------------------------ | 624 // Input agent handlers ------------------------------------------------------ |
391 | 625 |
392 scoped_refptr<DevToolsProtocol::Response> | 626 scoped_refptr<DevToolsProtocol::Response> |
393 RendererOverridesHandler::InputDispatchMouseEvent( | 627 RendererOverridesHandler::InputDispatchMouseEvent( |
394 scoped_refptr<DevToolsProtocol::Command> command) { | 628 scoped_refptr<DevToolsProtocol::Command> command) { |
395 base::DictionaryValue* params = command->params(); | 629 base::DictionaryValue* params = command->params(); |
396 if (!params) | 630 if (!params) |
397 return NULL; | 631 return NULL; |
398 | 632 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 } else { | 695 } else { |
462 return NULL; | 696 return NULL; |
463 } | 697 } |
464 | 698 |
465 host->ForwardMouseEvent(mouse_event); | 699 host->ForwardMouseEvent(mouse_event); |
466 | 700 |
467 return command->SuccessResponse(NULL); | 701 return command->SuccessResponse(NULL); |
468 } | 702 } |
469 | 703 |
470 } // namespace content | 704 } // namespace content |
OLD | NEW |