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

Unified Diff: chrome/renderer/extensions/webstore_bindings.cc

Issue 175263003: Add chrome.webstore API methods to allow sites to see progress of installation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: separate pure-virtual change Created 6 years, 10 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: chrome/renderer/extensions/webstore_bindings.cc
diff --git a/chrome/renderer/extensions/webstore_bindings.cc b/chrome/renderer/extensions/webstore_bindings.cc
index 85ecbf21a4ad205b3c787f008ffa8f669348d232..2009b43a17ac69bd2faec6b94042eb91a878d611 100644
--- a/chrome/renderer/extensions/webstore_bindings.cc
+++ b/chrome/renderer/extensions/webstore_bindings.cc
@@ -5,6 +5,7 @@
#include "chrome/renderer/extensions/webstore_bindings.h"
#include "base/strings/string_util.h"
+#include "chrome/common/extensions/api/webstore/webstore_api_constants.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/renderer/extensions/chrome_v8_context.h"
@@ -46,12 +47,36 @@ const char kNoWebstoreItemLinkFoundError[] =
"No Chrome Web Store item link found.";
const char kInvalidWebstoreItemUrlError[] =
"Invalid Chrome Web Store item URL.";
+const char kInstallStageListenerCallbackNotAFunctionError[] =
+ "The listener callback for install stage change must be a function.";
+const char kDownloadProgressListenerCallbackNotAFunctionError[] =
+ "The listener callback for download progress must be a function.";
not at google - send to devlin 2014/02/27 21:49:56 these sort of checks can be handled by the Event o
Devlin 2014/02/28 18:04:51 Done.
// chrome.webstore.install() calls generate an install ID so that the install's
// callbacks may be fired when the browser notifies us of install completion
// (successful or not) via OnInlineWebstoreInstallResponse.
int g_next_install_id = 0;
+// Parses the given |args| to determine if a valid listener function argument
+// was passed. NULL is considered valid, since it is used to unset the current
+// listener.
+// Returns true on success, false on failure. If successful,
+// populates |is_listener_set| with whether or not the listener should be set.
+bool GetIsListenerSet(const v8::FunctionCallbackInfo<v8::Value>& args,
+ bool* is_listener_set) {
+ if (args[0]->IsNull()) {
+ *is_listener_set = false;
+ return true;
+ }
+
+ if (args[0]->IsFunction()) {
+ *is_listener_set = true;
+ return true;
+ }
+
+ return false;
+}
+
} // anonymous namespace
WebstoreBindings::WebstoreBindings(Dispatcher* dispatcher,
@@ -60,23 +85,52 @@ WebstoreBindings::WebstoreBindings(Dispatcher* dispatcher,
ChromeV8ExtensionHandler(context) {
RouteFunction("Install",
base::Bind(&WebstoreBindings::Install, base::Unretained(this)));
+ RouteFunction("ValidateInstallStageListener",
+ base::Bind(&WebstoreBindings::ValidateInstallStageListener,
+ base::Unretained(this)));
+ RouteFunction("ValidateDownloadProgressListener",
+ base::Bind(&WebstoreBindings::ValidateDownloadProgressListener,
+ base::Unretained(this)));
}
-void WebstoreBindings::Install(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
+content::RenderView* WebstoreBindings::GetRenderView() {
WebFrame* frame = WebFrame::frameForContext(context()->v8_context());
if (!frame || !frame->view())
- return;
-
+ return NULL;
content::RenderView* render_view =
content::RenderView::FromWebView(frame->view());
+ return render_view;
+}
+
+void WebstoreBindings::Install(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ content::RenderView* render_view = GetRenderView();
if (!render_view)
return;
+ // The first two arguments, which indicate whether or not there are install
+ // stage and download progress listeners, are provided directly by the
+ // custom bindings, so should always be valid.
+ int listener_mask = 0;
+ if (args[0]->IsBoolean()) {
not at google - send to devlin 2014/02/27 21:49:56 so - *you* are calling the Install method. Rather
Devlin 2014/02/28 18:04:51 Done!
+ if (args[0]->BooleanValue())
+ listener_mask |= api::webstore::INSTALL_STAGE_LISTENER;
+ } else {
+ NOTREACHED();
+ return;
+ }
+ if (args[1]->IsBoolean()) {
+ if (args[1]->BooleanValue())
+ listener_mask |= api::webstore::DOWNLOAD_PROGRESS_LISTENER;
+ } else {
+ NOTREACHED();
+ return;
+ }
+
std::string preferred_store_link_url;
- if (!args[0]->IsUndefined()) {
- if (args[0]->IsString()) {
- preferred_store_link_url = std::string(*v8::String::Utf8Value(args[0]));
+ if (!args[2]->IsUndefined()) {
+ if (args[2]->IsString()) {
+ preferred_store_link_url = std::string(*v8::String::Utf8Value(args[2]));
} else {
args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
args.GetIsolate(), kPreferredStoreLinkUrlNotAString));
@@ -86,6 +140,8 @@ void WebstoreBindings::Install(
std::string webstore_item_id;
std::string error;
+ WebFrame* frame = WebFrame::frameForContext(context()->v8_context());
+
if (!GetWebstoreItemIdFromFrame(
frame, preferred_store_link_url, &webstore_item_id, &error)) {
args.GetIsolate()->ThrowException(
@@ -94,28 +150,58 @@ void WebstoreBindings::Install(
}
int install_id = g_next_install_id++;
- if (!args[1]->IsUndefined() && !args[1]->IsFunction()) {
+ if (!args[3]->IsUndefined() && !args[3]->IsFunction()) {
args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
args.GetIsolate(), kSuccessCallbackNotAFunctionError));
return;
}
- if (!args[2]->IsUndefined() && !args[2]->IsFunction()) {
+ if (!args[4]->IsUndefined() && !args[4]->IsFunction()) {
args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
args.GetIsolate(), kFailureCallbackNotAFunctionError));
return;
}
- Send(new ExtensionHostMsg_InlineWebstoreInstall(
- render_view->GetRoutingID(),
- install_id,
- GetRoutingID(),
- webstore_item_id,
- frame->document().url()));
+ Send(new ExtensionHostMsg_InlineWebstoreInstall(render_view->GetRoutingID(),
+ install_id,
+ GetRoutingID(),
+ webstore_item_id,
+ frame->document().url(),
+ listener_mask));
args.GetReturnValue().Set(static_cast<int32_t>(install_id));
}
+void WebstoreBindings::ValidateInstallStageListener(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ content::RenderView* render_view = GetRenderView();
+ if (!render_view)
+ return;
+
+ bool is_listener_set = false;
+ if (!GetIsListenerSet(args, &is_listener_set)) {
+ args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
+ args.GetIsolate(), kInstallStageListenerCallbackNotAFunctionError));
+ args.GetReturnValue().Set(false);
+ }
+ args.GetReturnValue().Set(true);
+}
+
+void WebstoreBindings::ValidateDownloadProgressListener(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ content::RenderView* render_view = GetRenderView();
+ if (!render_view)
+ return;
+
+ bool is_listener_set = false;
+ if (!GetIsListenerSet(args, &is_listener_set)) {
+ args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
+ args.GetIsolate(), kDownloadProgressListenerCallbackNotAFunctionError));
+ args.GetReturnValue().Set(false);
+ }
+ args.GetReturnValue().Set(true);
+}
+
// static
bool WebstoreBindings::GetWebstoreItemIdFromFrame(
WebFrame* frame, const std::string& preferred_store_link_url,
@@ -207,6 +293,10 @@ bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(WebstoreBindings, message)
IPC_MESSAGE_HANDLER(ExtensionMsg_InlineWebstoreInstallResponse,
OnInlineWebstoreInstallResponse)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_InlineInstallStageChanged,
+ OnInlineInstallStageChanged)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_InlineInstallDownloadProgress,
+ OnInlineInstallDownloadProgress)
IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message")
IPC_END_MESSAGE_MAP()
return true;
@@ -228,4 +318,24 @@ void WebstoreBindings::OnInlineWebstoreInstallResponse(
"webstore", "onInstallResponse", arraysize(argv), argv);
}
+void WebstoreBindings::OnInlineInstallStageChanged(const std::string& stage) {
+ v8::Isolate* isolate = context()->isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Context::Scope context_scope(context()->v8_context());
+ v8::Handle<v8::Value> argv[] = {
+ v8::String::NewFromUtf8(isolate, stage.c_str())};
+ context()->module_system()->CallModuleMethod(
+ "webstore", "onInstallStageChanged", arraysize(argv), argv);
+}
+
+void WebstoreBindings::OnInlineInstallDownloadProgress(int percent_downloaded) {
+ v8::Isolate* isolate = context()->isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Context::Scope context_scope(context()->v8_context());
+ v8::Handle<v8::Value> argv[] = {
+ v8::Number::New(isolate, percent_downloaded / 100.0)};
+ context()->module_system()->CallModuleMethod(
+ "webstore", "onDownloadProgress", arraysize(argv), argv);
+}
+
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698