 Chromium Code Reviews
 Chromium Code Reviews 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
    
  
    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| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/renderer/extensions/webstore_bindings.h" | 5 #include "chrome/renderer/extensions/webstore_bindings.h" | 
| 6 | 6 | 
| 7 #include "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" | 
| 8 #include "chrome/common/extensions/api/webstore/webstore_api_constants.h" | |
| 8 #include "chrome/common/extensions/extension_constants.h" | 9 #include "chrome/common/extensions/extension_constants.h" | 
| 9 #include "chrome/common/extensions/extension_messages.h" | 10 #include "chrome/common/extensions/extension_messages.h" | 
| 10 #include "chrome/renderer/extensions/chrome_v8_context.h" | 11 #include "chrome/renderer/extensions/chrome_v8_context.h" | 
| 11 #include "content/public/renderer/render_view.h" | 12 #include "content/public/renderer/render_view.h" | 
| 12 #include "extensions/common/extension.h" | 13 #include "extensions/common/extension.h" | 
| 13 #include "grit/renderer_resources.h" | 14 #include "grit/renderer_resources.h" | 
| 14 #include "third_party/WebKit/public/web/WebDocument.h" | 15 #include "third_party/WebKit/public/web/WebDocument.h" | 
| 15 #include "third_party/WebKit/public/web/WebElement.h" | 16 #include "third_party/WebKit/public/web/WebElement.h" | 
| 16 #include "third_party/WebKit/public/web/WebNode.h" | 17 #include "third_party/WebKit/public/web/WebNode.h" | 
| 17 #include "third_party/WebKit/public/web/WebNodeList.h" | 18 #include "third_party/WebKit/public/web/WebNodeList.h" | 
| 18 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 19 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 
| 19 #include "url/gurl.h" | 20 #include "url/gurl.h" | 
| 20 #include "v8/include/v8.h" | 21 #include "v8/include/v8.h" | 
| 21 | 22 | 
| 22 using blink::WebDocument; | 23 using blink::WebDocument; | 
| 23 using blink::WebElement; | 24 using blink::WebElement; | 
| 24 using blink::WebFrame; | 25 using blink::WebFrame; | 
| 25 using blink::WebNode; | 26 using blink::WebNode; | 
| 26 using blink::WebNodeList; | 27 using blink::WebNodeList; | 
| 27 using blink::WebUserGestureIndicator; | 28 using blink::WebUserGestureIndicator; | 
| 28 | 29 | 
| 29 namespace extensions { | 30 namespace extensions { | 
| 30 | 31 | 
| 31 namespace { | 32 namespace { | 
| 32 | 33 | 
| 33 const char kWebstoreLinkRelation[] = "chrome-webstore-item"; | 34 const char kWebstoreLinkRelation[] = "chrome-webstore-item"; | 
| 34 | 35 | 
| 35 const char kPreferredStoreLinkUrlNotAString[] = | |
| 36 "The Chrome Web Store item link URL parameter must be a string."; | |
| 37 const char kSuccessCallbackNotAFunctionError[] = | |
| 38 "The success callback parameter must be a function."; | |
| 39 const char kFailureCallbackNotAFunctionError[] = | |
| 40 "The failure callback parameter must be a function."; | |
| 41 const char kNotInTopFrameError[] = | 36 const char kNotInTopFrameError[] = | 
| 42 "Chrome Web Store installations can only be started by the top frame."; | 37 "Chrome Web Store installations can only be started by the top frame."; | 
| 43 const char kNotUserGestureError[] = | 38 const char kNotUserGestureError[] = | 
| 44 "Chrome Web Store installations can only be initated by a user gesture."; | 39 "Chrome Web Store installations can only be initated by a user gesture."; | 
| 45 const char kNoWebstoreItemLinkFoundError[] = | 40 const char kNoWebstoreItemLinkFoundError[] = | 
| 46 "No Chrome Web Store item link found."; | 41 "No Chrome Web Store item link found."; | 
| 47 const char kInvalidWebstoreItemUrlError[] = | 42 const char kInvalidWebstoreItemUrlError[] = | 
| 48 "Invalid Chrome Web Store item URL."; | 43 "Invalid Chrome Web Store item URL."; | 
| 49 | 44 | 
| 50 // chrome.webstore.install() calls generate an install ID so that the install's | 45 // chrome.webstore.install() calls generate an install ID so that the install's | 
| 51 // callbacks may be fired when the browser notifies us of install completion | 46 // callbacks may be fired when the browser notifies us of install completion | 
| 52 // (successful or not) via OnInlineWebstoreInstallResponse. | 47 // (successful or not) via OnInlineWebstoreInstallResponse. | 
| 53 int g_next_install_id = 0; | 48 int g_next_install_id = 0; | 
| 54 | 49 | 
| 55 } // anonymous namespace | 50 } // anonymous namespace | 
| 56 | 51 | 
| 57 WebstoreBindings::WebstoreBindings(Dispatcher* dispatcher, | 52 WebstoreBindings::WebstoreBindings(Dispatcher* dispatcher, | 
| 58 ChromeV8Context* context) | 53 ChromeV8Context* context) | 
| 59 : ChromeV8Extension(dispatcher, context), | 54 : ChromeV8Extension(dispatcher, context), | 
| 60 ChromeV8ExtensionHandler(context) { | 55 ChromeV8ExtensionHandler(context) { | 
| 61 RouteFunction("Install", | 56 RouteFunction("Install", | 
| 62 base::Bind(&WebstoreBindings::Install, base::Unretained(this))); | 57 base::Bind(&WebstoreBindings::Install, base::Unretained(this))); | 
| 63 } | 58 } | 
| 64 | 59 | 
| 65 void WebstoreBindings::Install( | 60 void WebstoreBindings::Install( | 
| 66 const v8::FunctionCallbackInfo<v8::Value>& args) { | 61 const v8::FunctionCallbackInfo<v8::Value>& args) { | 
| 67 WebFrame* frame = WebFrame::frameForContext(context()->v8_context()); | 62 content::RenderView* render_view = GetRenderView(); | 
| 68 if (!frame || !frame->view()) | |
| 69 return; | |
| 70 | |
| 71 content::RenderView* render_view = | |
| 72 content::RenderView::FromWebView(frame->view()); | |
| 73 if (!render_view) | 63 if (!render_view) | 
| 74 return; | 64 return; | 
| 75 | 65 | 
| 66 // The first two arguments indicate whether or not there are install stage | |
| 67 // or download progress listeners. | |
| 68 int listener_mask = 0; | |
| 69 CHECK(args[0]->IsBoolean()); | |
| 70 if (args[0]->BooleanValue()) | |
| 71 listener_mask |= api::webstore::INSTALL_STAGE_LISTENER; | |
| 72 CHECK(args[1]->IsBoolean()); | |
| 73 if (args[1]->BooleanValue()) | |
| 74 listener_mask |= api::webstore::DOWNLOAD_PROGRESS_LISTENER; | |
| 75 | |
| 76 std::string preferred_store_link_url; | 76 std::string preferred_store_link_url; | 
| 77 if (!args[0]->IsUndefined()) { | 77 if (!args[2]->IsUndefined()) { | 
| 78 if (args[0]->IsString()) { | 78 CHECK(args[2]->IsString()); | 
| 79 preferred_store_link_url = std::string(*v8::String::Utf8Value(args[0])); | 79 preferred_store_link_url = std::string(*v8::String::Utf8Value(args[2])); | 
| 80 } else { | |
| 81 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8( | |
| 82 args.GetIsolate(), kPreferredStoreLinkUrlNotAString)); | |
| 83 return; | |
| 84 } | |
| 85 } | 80 } | 
| 86 | 81 | 
| 87 std::string webstore_item_id; | 82 std::string webstore_item_id; | 
| 88 std::string error; | 83 std::string error; | 
| 84 WebFrame* frame = WebFrame::frameForContext(context()->v8_context()); | |
| 
not at google - send to devlin
2014/03/01 01:42:07
you can use context()->web_frame().
 
Devlin
2014/03/03 17:44:59
Done.
 | |
| 85 | |
| 89 if (!GetWebstoreItemIdFromFrame( | 86 if (!GetWebstoreItemIdFromFrame( | 
| 90 frame, preferred_store_link_url, &webstore_item_id, &error)) { | 87 frame, preferred_store_link_url, &webstore_item_id, &error)) { | 
| 91 args.GetIsolate()->ThrowException( | 88 args.GetIsolate()->ThrowException( | 
| 92 v8::String::NewFromUtf8(args.GetIsolate(), error.c_str())); | 89 v8::String::NewFromUtf8(args.GetIsolate(), error.c_str())); | 
| 93 return; | 90 return; | 
| 94 } | 91 } | 
| 95 | 92 | 
| 96 int install_id = g_next_install_id++; | 93 int install_id = g_next_install_id++; | 
| 97 if (!args[1]->IsUndefined() && !args[1]->IsFunction()) { | |
| 98 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8( | |
| 99 args.GetIsolate(), kSuccessCallbackNotAFunctionError)); | |
| 100 return; | |
| 101 } | |
| 102 | 94 | 
| 103 if (!args[2]->IsUndefined() && !args[2]->IsFunction()) { | 95 Send(new ExtensionHostMsg_InlineWebstoreInstall(render_view->GetRoutingID(), | 
| 104 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8( | 96 install_id, | 
| 105 args.GetIsolate(), kFailureCallbackNotAFunctionError)); | 97 GetRoutingID(), | 
| 106 return; | 98 webstore_item_id, | 
| 107 } | 99 frame->document().url(), | 
| 108 | 100 listener_mask)); | 
| 109 Send(new ExtensionHostMsg_InlineWebstoreInstall( | |
| 110 render_view->GetRoutingID(), | |
| 111 install_id, | |
| 112 GetRoutingID(), | |
| 113 webstore_item_id, | |
| 114 frame->document().url())); | |
| 115 | 101 | 
| 116 args.GetReturnValue().Set(static_cast<int32_t>(install_id)); | 102 args.GetReturnValue().Set(static_cast<int32_t>(install_id)); | 
| 117 } | 103 } | 
| 118 | 104 | 
| 119 // static | 105 // static | 
| 120 bool WebstoreBindings::GetWebstoreItemIdFromFrame( | 106 bool WebstoreBindings::GetWebstoreItemIdFromFrame( | 
| 121 WebFrame* frame, const std::string& preferred_store_link_url, | 107 WebFrame* frame, const std::string& preferred_store_link_url, | 
| 122 std::string* webstore_item_id, std::string* error) { | 108 std::string* webstore_item_id, std::string* error) { | 
| 123 if (frame != frame->top()) { | 109 if (frame != frame->top()) { | 
| 124 *error = kNotInTopFrameError; | 110 *error = kNotInTopFrameError; | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } | 186 } | 
| 201 | 187 | 
| 202 *error = kNoWebstoreItemLinkFoundError; | 188 *error = kNoWebstoreItemLinkFoundError; | 
| 203 return false; | 189 return false; | 
| 204 } | 190 } | 
| 205 | 191 | 
| 206 bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) { | 192 bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) { | 
| 207 IPC_BEGIN_MESSAGE_MAP(WebstoreBindings, message) | 193 IPC_BEGIN_MESSAGE_MAP(WebstoreBindings, message) | 
| 208 IPC_MESSAGE_HANDLER(ExtensionMsg_InlineWebstoreInstallResponse, | 194 IPC_MESSAGE_HANDLER(ExtensionMsg_InlineWebstoreInstallResponse, | 
| 209 OnInlineWebstoreInstallResponse) | 195 OnInlineWebstoreInstallResponse) | 
| 196 IPC_MESSAGE_HANDLER(ExtensionMsg_InlineInstallStageChanged, | |
| 197 OnInlineInstallStageChanged) | |
| 198 IPC_MESSAGE_HANDLER(ExtensionMsg_InlineInstallDownloadProgress, | |
| 199 OnInlineInstallDownloadProgress) | |
| 210 IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") | 200 IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") | 
| 211 IPC_END_MESSAGE_MAP() | 201 IPC_END_MESSAGE_MAP() | 
| 212 return true; | 202 return true; | 
| 213 } | 203 } | 
| 214 | 204 | 
| 215 void WebstoreBindings::OnInlineWebstoreInstallResponse( | 205 void WebstoreBindings::OnInlineWebstoreInstallResponse( | 
| 216 int install_id, | 206 int install_id, | 
| 217 bool success, | 207 bool success, | 
| 218 const std::string& error) { | 208 const std::string& error) { | 
| 219 v8::Isolate* isolate = context()->isolate(); | 209 v8::Isolate* isolate = context()->isolate(); | 
| 220 v8::HandleScope handle_scope(isolate); | 210 v8::HandleScope handle_scope(isolate); | 
| 221 v8::Context::Scope context_scope(context()->v8_context()); | 211 v8::Context::Scope context_scope(context()->v8_context()); | 
| 222 v8::Handle<v8::Value> argv[] = { | 212 v8::Handle<v8::Value> argv[] = { | 
| 223 v8::Integer::New(isolate, install_id), | 213 v8::Integer::New(isolate, install_id), | 
| 224 v8::Boolean::New(isolate, success), | 214 v8::Boolean::New(isolate, success), | 
| 225 v8::String::NewFromUtf8(isolate, error.c_str()) | 215 v8::String::NewFromUtf8(isolate, error.c_str()) | 
| 226 }; | 216 }; | 
| 227 context()->module_system()->CallModuleMethod( | 217 context()->module_system()->CallModuleMethod( | 
| 228 "webstore", "onInstallResponse", arraysize(argv), argv); | 218 "webstore", "onInstallResponse", arraysize(argv), argv); | 
| 229 } | 219 } | 
| 230 | 220 | 
| 221 void WebstoreBindings::OnInlineInstallStageChanged(const std::string& stage) { | |
| 222 v8::Isolate* isolate = context()->isolate(); | |
| 223 v8::HandleScope handle_scope(isolate); | |
| 224 v8::Context::Scope context_scope(context()->v8_context()); | |
| 225 v8::Handle<v8::Value> argv[] = { | |
| 226 v8::String::NewFromUtf8(isolate, stage.c_str())}; | |
| 227 context()->module_system()->CallModuleMethod( | |
| 228 "webstore", "onInstallStageChanged", arraysize(argv), argv); | |
| 229 } | |
| 230 | |
| 231 void WebstoreBindings::OnInlineInstallDownloadProgress(int percent_downloaded) { | |
| 232 v8::Isolate* isolate = context()->isolate(); | |
| 233 v8::HandleScope handle_scope(isolate); | |
| 234 v8::Context::Scope context_scope(context()->v8_context()); | |
| 235 v8::Handle<v8::Value> argv[] = { | |
| 236 v8::Number::New(isolate, percent_downloaded / 100.0)}; | |
| 237 context()->module_system()->CallModuleMethod( | |
| 238 "webstore", "onDownloadProgress", arraysize(argv), argv); | |
| 239 } | |
| 240 | |
| 231 } // namespace extensions | 241 } // namespace extensions | 
| OLD | NEW |