Chromium Code Reviews| Index: content/browser/devtools/renderer_overrides_handler.cc |
| diff --git a/content/browser/devtools/renderer_overrides_handler.cc b/content/browser/devtools/renderer_overrides_handler.cc |
| index f3970385490f42d0e89544b3327153de684e05e6..2229b632e8a5933e4b987c4d2b57b79b0388b2fc 100644 |
| --- a/content/browser/devtools/renderer_overrides_handler.cc |
| +++ b/content/browser/devtools/renderer_overrides_handler.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/files/file_path.h" |
| +#include "base/message_loop/message_loop_proxy.h" |
| #include "base/strings/string16.h" |
| #include "base/values.h" |
| #include "content/browser/child_process_security_policy_impl.h" |
| @@ -27,17 +28,20 @@ |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/render_widget_host_view.h" |
| +#include "content/public/browser/storage_partition.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_delegate.h" |
| #include "content/public/common/page_transition_types.h" |
| #include "content/public/common/referrer.h" |
| #include "ipc/ipc_sender.h" |
| +#include "net/base/net_util.h" |
| #include "third_party/WebKit/public/web/WebInputEvent.h" |
| #include "ui/gfx/codec/jpeg_codec.h" |
| #include "ui/gfx/codec/png_codec.h" |
| #include "ui/gfx/size_conversions.h" |
| #include "ui/snapshot/snapshot.h" |
| #include "url/gurl.h" |
| +#include "webkit/browser/quota/quota_manager.h" |
| using WebKit::WebGestureEvent; |
| using WebKit::WebInputEvent; |
| @@ -111,6 +115,11 @@ RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent) |
| &RendererOverridesHandler::PageStopScreencast, |
| base::Unretained(this))); |
| RegisterCommandHandler( |
| + devtools::Quota::queryUsageAndQuota::kName, |
| + base::Bind( |
| + &RendererOverridesHandler::QuotaQueryUsageAndQuota, |
| + base::Unretained(this))); |
| + RegisterCommandHandler( |
| devtools::Input::dispatchMouseEvent::kName, |
| base::Bind( |
| &RendererOverridesHandler::InputDispatchMouseEvent, |
| @@ -446,6 +455,233 @@ void RendererOverridesHandler::ScreenshotCaptured( |
| } |
| } |
| +namespace { |
| + |
| +typedef base::Callback<void (DevToolsProtocol::Response*)> RespondCallback; |
| + |
| +class QuotaTask { |
| + public: |
| + virtual ~QuotaTask() {} |
| + |
| + static void Run(scoped_ptr<QuotaTask> task) { |
| + // Will be deleted when done. |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&QuotaTask::Start, base::Unretained(task.release()))); |
| + } |
| + |
| + protected: |
| + QuotaTask(scoped_refptr<DevToolsProtocol::Command> command, |
| + const RespondCallback& callback, |
| + RenderViewHost* render_vew_host, |
| + const std::string& security_origin) |
| + : command_(command), |
| + callback_(callback), |
| + host_(net::GetHostOrSpecFromURL(GURL(security_origin))), |
| + quota_manager_(render_vew_host->GetProcess()-> |
| + GetStoragePartition()->GetQuotaManager()), |
| + response_loop_proxy_(base::MessageLoopProxy::current()) { |
| + |
| + } |
| + |
| + // Called on IO thread. |
| + virtual void Start() = 0; |
| + |
| + void Done(scoped_ptr<base::DictionaryValue> responseData) { |
| + base::MessageLoopProxy* loop = response_loop_proxy_.get(); |
| + loop->PostTask(FROM_HERE, base::Bind( |
| + &QuotaTask::RespondOnCallerThreadAndDelete, |
| + this, base::Passed(&responseData))); |
| + } |
| + |
| + scoped_refptr<quota::QuotaManager> GetQuotaManager() { |
| + return quota_manager_.get(); |
| + } |
| + |
| + const std::string& host() const { return host_; } |
| + |
| + private: |
| + scoped_refptr<DevToolsProtocol::Command> command_; |
| + RespondCallback callback_; |
| + |
| + std::string host_; |
| + scoped_refptr<quota::QuotaManager> quota_manager_; |
| + |
| + scoped_refptr<base::MessageLoopProxy> response_loop_proxy_; |
| + |
| + void RespondOnCallerThread(scoped_ptr<base::DictionaryValue> response) { |
| + callback_.Run(command_->SuccessResponse(response.release()).get()); |
| + } |
| + |
| + static void RespondOnCallerThreadAndDelete(QuotaTask* task, |
| + scoped_ptr<base::DictionaryValue> responseData) { |
| + task->RespondOnCallerThread(responseData.Pass()); |
| + delete task; |
| + } |
| +}; |
| + |
| +class GetUsageAndQuotaTask : public QuotaTask { |
| + public: |
| + GetUsageAndQuotaTask(scoped_refptr<DevToolsProtocol::Command> command, |
| + const RespondCallback& callback, |
| + RenderViewHost* render_vew_host, |
| + const std::string& security_origin) |
| + : QuotaTask(command, callback, render_vew_host, security_origin), |
| + quota_(new base::DictionaryValue), |
| + usage_(new base::DictionaryValue) { |
| + steps_.push_back(base::Bind("a::QuotaManager::GetAvailableSpace, |
| + GetQuotaManager(), |
| + MakeQuotaCallback("availableSpace"))); |
| + |
| + steps_.push_back(base::Bind("a::QuotaManager::GetTemporaryGlobalQuota, |
| + GetQuotaManager(), |
| + MakeQuotaCallback("temporaryGlobalQuota"))); |
|
kinuko
2013/09/09 12:36:35
The real per-site temporary quota we give to each
SeRya
2013/09/10 09:37:04
Done.
|
| + |
| + steps_.push_back(base::Bind("a::QuotaManager::GetPersistentHostQuota, |
| + GetQuotaManager(), |
| + host(), |
| + MakeQuotaCallback("persistentHostQuota"))); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::GetHostUsage, |
| + base::Unretained(this), |
| + quota::kStorageTypeTemporary, |
| + quota::QuotaClient::kFileSystem, |
| + "temporaryFileSystemUsage")); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::GetHostUsage, |
| + base::Unretained(this), |
| + quota::kStorageTypePersistent, |
| + quota::QuotaClient::kFileSystem, |
| + "persistentFileSystemUsage")); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::GetHostUsage, |
| + base::Unretained(this), |
| + quota::kStorageTypeSyncable, |
| + quota::QuotaClient::kFileSystem, |
| + "syncableFileSystemUsage")); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::GetHostUsage, |
| + base::Unretained(this), |
| + quota::kStorageTypeTemporary, |
| + quota::QuotaClient::kDatabase, |
| + "databaseUsage")); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::GetHostUsage, |
| + base::Unretained(this), |
| + quota::kStorageTypeTemporary, |
| + quota::QuotaClient::kAppcache, |
| + "appcacheUsage")); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::GetHostUsage, |
| + base::Unretained(this), |
| + quota::kStorageTypeTemporary, |
| + quota::QuotaClient::kIndexedDatabase, |
| + "indexedDatabaseUsage")); |
| + |
| + steps_.push_back(base::Bind(&GetUsageAndQuotaTask::Finish, |
| + base::Unretained(this))); |
| + } |
| + |
| + protected: |
| + virtual void Start() OVERRIDE { |
| + currentStep_ = 0; |
| + readyForNextStep_ = true; |
| + stepDone_ = true; |
| + DoStep(); |
| + } |
| + |
| + private: |
| + scoped_ptr<base::DictionaryValue> quota_; |
| + scoped_ptr<base::DictionaryValue> usage_; |
| + std::vector<base::Callback<void (void)> > steps_; |
| + bool readyForNextStep_; |
| + bool stepDone_; |
| + int currentStep_; |
| + |
| + void GetHostUsage(quota::StorageType type, |
| + quota::QuotaClient::ID client_id, |
| + const char* name) { |
| + quota::UsageCallback callback = |
| + base::Bind(&GetUsageAndQuotaTask::DidGetUsage, |
| + base::Unretained(this), name); |
| + GetQuotaManager()->GetHostUsage(host(), type, client_id, callback); |
| + } |
| + |
| + void Finish() { |
| + scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); |
| + result->Set("quota", quota_.release()); |
| + result->Set("usage", usage_.release()); |
| + Done(result.Pass()); |
| + } |
| + |
| + void DoStep() { |
| + DCHECK(readyForNextStep_); |
| + DCHECK(stepDone_); |
| + readyForNextStep_ = false; |
| + stepDone_ = false; |
| + int startStep = currentStep_; |
| + |
| + steps_[currentStep_].Run(); |
| + |
| + readyForNextStep_ = true; |
| + if (stepDone_) { |
| + DCHECK(currentStep_ == startStep + 1); |
| + DoStep(); |
| + } |
| + } |
| + |
| + void StepDone() { |
| + DCHECK(!stepDone_); |
| + currentStep_++; |
| + stepDone_ = true; |
| + if (readyForNextStep_) |
| + DoStep(); |
| + } |
| + |
| + void DidGetQuota(const char* name, |
| + quota::QuotaStatusCode status, |
| + int64 space) { |
| + if (status == quota::kQuotaStatusOk) |
| + quota_->SetDouble(name, space); |
| + StepDone(); |
| + } |
| + |
| + quota::QuotaCallback MakeQuotaCallback(const char* name) { |
| + return base::Bind(&GetUsageAndQuotaTask::DidGetQuota, |
| + base::Unretained(this), name); |
| + } |
| + |
| + void DidGetUsage(const char* name, int64 usage_value) { |
| + usage_->SetDouble(name, usage_value); |
| + StepDone(); |
| + } |
| +}; |
| + |
| +} // namespace |
| + |
| +scoped_refptr<DevToolsProtocol::Response> |
| +RendererOverridesHandler::QuotaQueryUsageAndQuota( |
| + scoped_refptr<DevToolsProtocol::Command> command) { |
| + base::DictionaryValue* params = command->params(); |
| + std::string security_origin; |
| + if (!params || !params->GetString( |
| + devtools::Quota::queryUsageAndQuota::kParamSecurityOrigin, |
| + &security_origin)) { |
| + return command->InvalidParamResponse( |
| + devtools::Quota::queryUsageAndQuota::kParamSecurityOrigin); |
| + } |
| + |
| + RespondCallback callback = base::Bind( |
| + &RendererOverridesHandler::AsyncTaskDone, weak_factory_.GetWeakPtr()); |
| + QuotaTask::Run(scoped_ptr<QuotaTask>(new GetUsageAndQuotaTask(command, |
| + callback, agent_->GetRenderViewHost(), security_origin))); |
| + return command->AsyncResponsePromise(); |
| +} |
| + |
| +void RendererOverridesHandler::AsyncTaskDone( |
| + DevToolsProtocol::Response* response) { |
| + SendRawMessage(response->Serialize()); |
| +} |
| // Input agent handlers ------------------------------------------------------ |