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

Unified Diff: content/browser/devtools/renderer_overrides_handler.cc

Issue 23240002: Backend for DevTools quota managements. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 side-by-side diff with in-line comments
Download patch
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 fe35d3029b3e7c2a18f55c5248e088b94b4ca38c..540d18340cbd37cc87439f082b1aec1c0db540a3 100644
--- a/content/browser/devtools/renderer_overrides_handler.cc
+++ b/content/browser/devtools/renderer_overrides_handler.cc
@@ -6,10 +6,12 @@
#include <string>
+#include "base/barrier_closure.h"
#include "base/base64.h"
#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"
@@ -28,17 +30,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;
@@ -72,6 +77,80 @@ void ParseGenericInputParams(base::DictionaryValue* params,
&event->timeStampSeconds);
}
+typedef base::Callback<void (DevToolsProtocol::Response*)> RespondCallback;
+
+class QuotaTask {
+ public:
+ virtual ~QuotaTask() {}
+
+ static void Run(scoped_ptr<QuotaTask> task);
+
+ protected:
+ QuotaTask(scoped_refptr<DevToolsProtocol::Command> command,
+ const RespondCallback& callback,
+ RenderViewHost* render_vew_host,
+ const std::string& security_origin);
+
+ scoped_refptr<quota::QuotaManager> GetQuotaManager() {
pfeldman 2013/09/17 15:19:45 These will not be needed.
SeRya 2013/09/17 16:12:13 Done.
+ return quota_manager_;
+ }
+
+ std::string host() const { return net::GetHostOrSpecFromURL(origin_); }
+ const GURL& origin() const { return origin_; }
+
+ void AddStep(base::Closure const& step) { steps_.push_back(step); }
+
+ void StepDone();
+ virtual scoped_ptr<base::DictionaryValue> GetResponseData() = 0;
+
+ private:
+ scoped_refptr<DevToolsProtocol::Command> command_;
+ RespondCallback callback_;
+
+ GURL origin_;
+ scoped_refptr<quota::QuotaManager> quota_manager_;
+
+ scoped_refptr<base::MessageLoopProxy> response_loop_proxy_;
+
+ std::vector<base::Closure> steps_;
+ base::Closure barrier_;
+
+ // Called on IO thread.
+ void TaskStart();
+ void TaskDone();
+
+ void RespondOnCallerThread(scoped_ptr<base::DictionaryValue> response);
+ static void RespondOnCallerThreadAndDelete(
+ QuotaTask* task,
+ scoped_ptr<base::DictionaryValue> responseData);
+};
+
+class GetUsageAndQuotaTask : public QuotaTask {
+ public:
+ GetUsageAndQuotaTask(scoped_refptr<DevToolsProtocol::Command> command,
+ const RespondCallback& callback,
+ RenderViewHost* render_vew_host,
+ const std::string& security_origin);
+
+ private:
+ scoped_ptr<base::DictionaryValue> quota_;
+ scoped_ptr<base::DictionaryValue> usage_;
+
+ virtual scoped_ptr<base::DictionaryValue> GetResponseData() OVERRIDE;
+ void GetHostUsage(quota::StorageType type,
+ quota::QuotaClient::ID client_id, const char* name);
+ void DidGetQuota(
+ const char* name, quota::QuotaStatusCode status, int64 space);
+ quota::QuotaCallback MakeQuotaCallback(const char* name);
+ void DidGetUsage(const char* name, int64 usage_value);
+ void DidGetUsageAndQuotaForWebApps(const char* name,
+ quota::QuotaStatusCode status, int64 usage, int64 quota);
+ void AddGetHostUsageStep(
+ quota::StorageType type,
+ quota::QuotaClient::ID client_id,
+ const char* name);
+};
+
} // namespace
RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent)
@@ -122,6 +201,11 @@ RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent)
&RendererOverridesHandler::PageStopScreencast,
base::Unretained(this)));
RegisterCommandHandler(
+ devtools::Page::queryUsageAndQuota::kName,
+ base::Bind(
+ &RendererOverridesHandler::PageQueryUsageAndQuota,
+ base::Unretained(this)));
+ RegisterCommandHandler(
devtools::Input::dispatchMouseEvent::kName,
base::Bind(
&RendererOverridesHandler::InputDispatchMouseEvent,
@@ -525,6 +609,203 @@ void RendererOverridesHandler::ScreenshotCaptured(
}
}
pfeldman 2013/09/17 15:19:45 } // QuotaTask ---------------------------------
SeRya 2013/09/17 16:12:13 Done.
+// static
+void QuotaTask::Run(scoped_ptr<QuotaTask> task) {
+ // Will be deleted when done.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&QuotaTask::TaskStart, base::Unretained(task.release())));
+}
+
+QuotaTask::QuotaTask(
+ scoped_refptr<DevToolsProtocol::Command> command,
+ const RespondCallback& callback,
+ RenderViewHost* render_vew_host,
+ const std::string& security_origin)
+ : command_(command),
+ callback_(callback),
+ origin_(security_origin),
+ quota_manager_(render_vew_host->GetProcess()->
+ GetStoragePartition()->GetQuotaManager()),
+ response_loop_proxy_(base::MessageLoopProxy::current()) {
+}
+
+void QuotaTask::TaskStart() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ barrier_ = base::BarrierClosure(
+ steps_.size(),
+ base::Bind(&QuotaTask::TaskDone, base::Unretained(this)));
+
+ for (std::vector<base::Closure>::iterator i = steps_.begin();
+ i != steps_.end(); ++i) {
+ i->Run();
+ }
+}
+
+void QuotaTask::StepDone() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ barrier_.Run();
+}
+
+void QuotaTask::TaskDone() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ scoped_ptr<base::DictionaryValue> responseData = GetResponseData();
+
+ base::MessageLoopProxy* loop = response_loop_proxy_.get();
+ loop->PostTask(FROM_HERE, base::Bind(
+ &QuotaTask::RespondOnCallerThreadAndDelete,
+ this, base::Passed(&responseData)));
+}
+
+void QuotaTask::RespondOnCallerThread(
+ scoped_ptr<base::DictionaryValue> response) {
+ callback_.Run(command_->SuccessResponse(response.release()).get());
+}
+
+// static
+void QuotaTask::RespondOnCallerThreadAndDelete(
+ QuotaTask* task,
+ scoped_ptr<base::DictionaryValue> responseData) {
+ task->RespondOnCallerThread(responseData.Pass());
+ delete task;
+}
+
+GetUsageAndQuotaTask::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) {
+ AddStep(base::Bind(&quota::QuotaManager::GetAvailableSpace,
+ GetQuotaManager(),
+ MakeQuotaCallback("availableSpace")));
+
+ AddStep(base::Bind(
+ &quota::QuotaManager::GetUsageAndQuotaForWebApps,
+ GetQuotaManager(),
+ origin(),
+ quota::kStorageTypeTemporary,
+ base::Bind(&GetUsageAndQuotaTask::DidGetUsageAndQuotaForWebApps,
+ base::Unretained(this), "temporaryHostQuota")));
+
+ AddStep(base::Bind(&quota::QuotaManager::GetPersistentHostQuota,
+ GetQuotaManager(),
+ host(),
+ MakeQuotaCallback("persistentHostQuota")));
+
+ AddGetHostUsageStep(
+ quota::kStorageTypeTemporary,
+ quota::QuotaClient::kFileSystem,
+ "temporaryFileSystemUsage");
+
+ AddGetHostUsageStep(
+ quota::kStorageTypePersistent,
+ quota::QuotaClient::kFileSystem,
+ "persistentFileSystemUsage");
+
+ AddGetHostUsageStep(
+ quota::kStorageTypeSyncable,
+ quota::QuotaClient::kFileSystem,
+ "syncableFileSystemUsage");
+
+ AddGetHostUsageStep(
+ quota::kStorageTypeTemporary,
+ quota::QuotaClient::kDatabase,
+ "databaseUsage");
+
+ AddGetHostUsageStep(
+ quota::kStorageTypeTemporary,
+ quota::QuotaClient::kAppcache,
+ "appcacheUsage");
+
+ AddGetHostUsageStep(
+ quota::kStorageTypeTemporary,
+ quota::QuotaClient::kIndexedDatabase,
+ "indexedDatabaseUsage");
+}
+
+void GetUsageAndQuotaTask::AddGetHostUsageStep(
+ quota::StorageType type,
+ quota::QuotaClient::ID client_id,
+ const char* name) {
+ AddStep(base::Bind(&GetUsageAndQuotaTask::GetHostUsage,
pfeldman 2013/09/17 15:19:45 Why do you need to collect steps and not simply ru
SeRya 2013/09/17 16:12:13 BarrierClosure needs to be created before running
+ base::Unretained(this), type, client_id, name));
+}
+
+scoped_ptr<base::DictionaryValue> GetUsageAndQuotaTask::GetResponseData() {
+ scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
+ result->Set("quota", quota_.release());
+ result->Set("usage", usage_.release());
+ return result.Pass();
+}
+
+void GetUsageAndQuotaTask::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 GetUsageAndQuotaTask::DidGetQuota(
+ const char* name,
+ quota::QuotaStatusCode status,
+ int64 space) {
+ if (status == quota::kQuotaStatusOk)
+ quota_->SetDouble(name, space);
+ StepDone();
+}
+
+quota::QuotaCallback GetUsageAndQuotaTask::MakeQuotaCallback(const char* name) {
+ return base::Bind(&GetUsageAndQuotaTask::DidGetQuota,
+ base::Unretained(this), name);
+}
+
+void GetUsageAndQuotaTask::DidGetUsage(const char* name, int64 usage_value) {
+ usage_->SetDouble(name, usage_value);
+ StepDone();
+}
+
+void GetUsageAndQuotaTask::DidGetUsageAndQuotaForWebApps(
+ const char* name,
+ quota::QuotaStatusCode status,
+ int64 usage,
+ int64 quota) {
+ if (status == quota::kQuotaStatusOk)
+ quota_->SetDouble(name, quota);
+ StepDone();
+}
+
+scoped_refptr<DevToolsProtocol::Response>
+RendererOverridesHandler::PageQueryUsageAndQuota(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ base::DictionaryValue* params = command->params();
+ std::string security_origin;
+ if (!params || !params->GetString(
+ devtools::Page::queryUsageAndQuota::kParamSecurityOrigin,
+ &security_origin)) {
+ return command->InvalidParamResponse(
+ devtools::Page::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 ------------------------------------------------------

Powered by Google App Engine
This is Rietveld 408576698