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

Side by Side Diff: content/renderer/web_intents_host.cc

Issue 10412058: Change to use webkit intent delivery. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Get v8 context scope for unserialized/blob delivery Created 8 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/renderer/web_intents_host.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "content/renderer/web_intents_host.h" 5 #include "content/renderer/web_intents_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "content/common/intents_messages.h" 10 #include "content/common/intents_messages.h"
11 #include "content/renderer/render_view_impl.h" 11 #include "content/renderer/render_view_impl.h"
12 #include "ipc/ipc_message.h" 12 #include "ipc/ipc_message.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBlob.h" 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBlob.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDeliveredIntentCli ent.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntent.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntentRequest.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntentRequest.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h " 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h "
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerialize dScriptValue.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerialize dScriptValue.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
20 #include "v8/include/v8.h" 24 #include "v8/include/v8.h"
21 #include "webkit/glue/cpp_bound_class.h" 25 #include "webkit/glue/cpp_bound_class.h"
22 26
23 using WebKit::WebBindings; 27 using WebKit::WebBindings;
24 using WebKit::WebBlob; 28 using WebKit::WebBlob;
25 using WebKit::WebCString; 29 using WebKit::WebCString;
30 using WebKit::WebDeliveredIntentClient;
26 using WebKit::WebFrame; 31 using WebKit::WebFrame;
32 using WebKit::WebIntent;
27 using WebKit::WebIntentRequest; 33 using WebKit::WebIntentRequest;
28 using WebKit::WebString; 34 using WebKit::WebString;
29 using WebKit::WebSerializedScriptValue; 35 using WebKit::WebSerializedScriptValue;
30 using webkit_glue::CppArgumentList;
31 using webkit_glue::CppBoundClass;
32 using webkit_glue::CppVariant;
33 36
34 // This class encapsulates the API the Intent object will expose to Javascript. 37 class DeliveredIntentClientImpl : public WebDeliveredIntentClient {
35 // It is made available to the Javascript runtime in the service page using
36 // NPAPI methods as with plugin/Javascript interaction objects and other
37 // browser-provided Javascript API objects on |window|.
38 class WebIntentsHost::BoundDeliveredIntent : public CppBoundClass {
39 public: 38 public:
40 BoundDeliveredIntent(const webkit_glue::WebIntentData& intent, 39 explicit DeliveredIntentClientImpl(WebIntentsHost* host) : host_(host) {}
41 WebIntentsHost* parent, 40 virtual ~DeliveredIntentClientImpl() {}
42 WebFrame* frame) {
43 action_ = WebString(intent.action).utf8();
44 type_ = WebString(intent.type).utf8();
45 extra_data_ = intent.extra_data;
46 parent_ = parent;
47 41
48 v8::HandleScope scope; 42 virtual void postResult(const WebSerializedScriptValue& data) const OVERRIDE {
darin (slow to review) 2012/06/05 18:22:18 Note: We often do not use OVERRIDE when implementi
Greg Billock 2012/06/05 19:55:45 Took 'em out. On 2012/06/05 18:22:18, darin wrote
49 v8::Local<v8::Context> ctx = frame->mainWorldScriptContext(); 43 host_->OnResult(data.toString());
50 v8::Context::Scope cscope(ctx);
51 v8::Local<v8::Value> data_obj;
52
53 if (intent.data_type == webkit_glue::WebIntentData::SERIALIZED) {
54 WebSerializedScriptValue ssv =
55 WebSerializedScriptValue::fromString(WebString(intent.data));
56 DCHECK(!ssv.isNull());
57 data_obj = v8::Local<v8::Value>::New(ssv.deserialize());
58 } else if (intent.data_type == webkit_glue::WebIntentData::UNSERIALIZED) {
59 data_obj = v8::String::New(
60 reinterpret_cast<const uint16_t*>(intent.unserialized_data.data()),
61 static_cast<int>(intent.unserialized_data.length()));
62 } else {
63 DCHECK(intent.data_type == webkit_glue::WebIntentData::BLOB);
64 web_blob_ = WebBlob::createFromFile(
65 WebString::fromUTF8(intent.blob_file.AsUTF8Unsafe()),
66 intent.blob_length);
67 data_obj = v8::Local<v8::Value>::New(web_blob_.toV8Value());
68 }
69
70 data_val_.reset(new CppVariant);
71 WebBindings::toNPVariant(data_obj, frame->windowObject(), data_val_.get());
72
73 BindGetterCallback("action", base::Bind(&BoundDeliveredIntent::GetAction,
74 base::Unretained(this)));
75 BindGetterCallback("type", base::Bind(&BoundDeliveredIntent::GetType,
76 base::Unretained(this)));
77 BindGetterCallback("data", base::Bind(&BoundDeliveredIntent::GetData,
78 base::Unretained(this)));
79 BindCallback("getExtra", base::Bind(&BoundDeliveredIntent::GetExtra,
80 base::Unretained(this)));
81 BindCallback("postResult", base::Bind(&BoundDeliveredIntent::PostResult,
82 base::Unretained(this)));
83 BindCallback("postFailure", base::Bind(&BoundDeliveredIntent::PostFailure,
84 base::Unretained(this)));
85 } 44 }
86 45
87 virtual ~BoundDeliveredIntent() { 46 virtual void postFailure(const WebSerializedScriptValue& data) const
47 OVERRIDE {
48 host_->OnFailure(data.toString());
88 } 49 }
89 50
90 WebString SerializeCppVariant(const CppVariant& val) { 51 virtual void destroy() OVERRIDE {
91 v8::HandleScope scope;
92 v8::Handle<v8::Value> v8obj = WebBindings::toV8Value(&val);
93
94 WebSerializedScriptValue ssv =
95 WebSerializedScriptValue::serialize(v8obj);
96 if (ssv.isNull())
97 return WebKit::WebString();
98
99 return ssv.toString();
100 }
101
102 void PostResult(const CppArgumentList& args, CppVariant* retval) {
103 if (args.size() != 1) {
104 WebBindings::setException(NULL, "Must pass one argument to postResult");
105 return;
106 }
107
108 WebString str = SerializeCppVariant(args[0]);
109 parent_->OnResult(str);
110 }
111
112 void PostFailure(const CppArgumentList& args, CppVariant* retval) {
113 if (args.size() != 1) {
114 WebBindings::setException(NULL, "Must pass one argument to postFailure");
115 return;
116 }
117
118 WebString str = SerializeCppVariant(args[0]);
119 parent_->OnFailure(str);
120 }
121
122 void GetAction(CppVariant* result) {
123 std::string action;
124 action.assign(action_.data(), action_.length());
125 result->Set(action);
126 }
127
128 void GetType(CppVariant* result) {
129 std::string type;
130 type.assign(type_.data(), type_.length());
131 result->Set(type);
132 }
133
134 void GetData(CppVariant* result) {
135 result->Set(*data_val_.get());
136 }
137
138 void GetExtra(const CppArgumentList& args, CppVariant* result) {
139 if (args.size() != 1) {
140 WebBindings::setException(NULL, "Must pass one argument to getExtra");
141 return;
142 }
143
144 if (!args[0].isString()) {
145 WebBindings::setException(NULL, "Argument to getExtra must be a string");
146 return;
147 }
148
149 std::string str = args[0].ToString();
150 std::map<string16, string16>::const_iterator iter =
151 extra_data_.find(UTF8ToUTF16(str));
152 if (iter == extra_data_.end()) {
153 result->SetNull();
154 return;
155 }
156 std::string val = UTF16ToUTF8(iter->second);
157 result->Set(val);
158 } 52 }
159 53
160 private: 54 private:
161 // Intent data suitable for surfacing to Javascript callers. 55 WebIntentsHost* host_;
162 WebCString action_;
163 WebCString type_;
164 std::map<string16, string16> extra_data_;
165 WebBlob web_blob_;
166 scoped_ptr<CppVariant> data_val_;
167
168 // The dispatcher object, for forwarding postResult/postFailure calls.
169 WebIntentsHost* parent_;
170 }; 56 };
171 57
172 WebIntentsHost::WebIntentsHost(RenderViewImpl* render_view) 58 WebIntentsHost::WebIntentsHost(RenderViewImpl* render_view)
173 : content::RenderViewObserver(render_view), 59 : content::RenderViewObserver(render_view),
174 id_counter_(0) { 60 id_counter_(0) {
175 } 61 }
176 62
177 WebIntentsHost::~WebIntentsHost() { 63 WebIntentsHost::~WebIntentsHost() {
178 } 64 }
179 65
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 routing_id(), webkit_glue::WEB_INTENT_REPLY_SUCCESS, data)); 109 routing_id(), webkit_glue::WEB_INTENT_REPLY_SUCCESS, data));
224 } 110 }
225 111
226 void WebIntentsHost::OnFailure(const WebKit::WebString& data) { 112 void WebIntentsHost::OnFailure(const WebKit::WebString& data) {
227 Send(new IntentsHostMsg_WebIntentReply( 113 Send(new IntentsHostMsg_WebIntentReply(
228 routing_id(), webkit_glue::WEB_INTENT_REPLY_FAILURE, data)); 114 routing_id(), webkit_glue::WEB_INTENT_REPLY_FAILURE, data));
229 } 115 }
230 116
231 // We set the intent payload into all top-level frame window objects. This 117 // We set the intent payload into all top-level frame window objects. This
232 // should persist the data through redirects, and not deliver it to any 118 // should persist the data through redirects, and not deliver it to any
233 // sub-frames. TODO(gbillock): This policy needs to be fine-tuned and 119 // sub-frames.
234 // documented. 120 // TODO(gbillock): match to spec to double-check registration match before
121 // delivery.
235 void WebIntentsHost::DidClearWindowObject(WebFrame* frame) { 122 void WebIntentsHost::DidClearWindowObject(WebFrame* frame) {
236 if (intent_.get() == NULL || frame->top() != frame) 123 if (intent_.get() == NULL || frame->top() != frame)
237 return; 124 return;
238 if (!delivered_intent_.get()) { 125
239 delivered_intent_.reset( 126 if (!delivered_intent_client_.get()) {
240 new BoundDeliveredIntent(*(intent_.get()), this, frame)); 127 delivered_intent_client_.reset(new DeliveredIntentClientImpl(this));
241 } 128 }
242 delivered_intent_->BindToJavascript(frame, "webkitIntent"); 129
130 WebKit::WebVector<WebKit::WebString> extras_keys(
darin (slow to review) 2012/06/05 18:22:18 nit: no WebKit:: in front of WebString
Greg Billock 2012/06/05 19:55:45 Done.
131 intent_->extra_data.size());
132 WebKit::WebVector<WebKit::WebString> extras_values(
133 intent_->extra_data.size());
134 std::map<string16, string16>::iterator iter;
135 int i;
136 for (i = 0, iter = intent_->extra_data.begin();
137 iter != intent_->extra_data.end();
138 ++i, ++iter) {
139 extras_keys[i] = iter->first;
140 extras_values[i] = iter->second;
141 }
142
143 v8::HandleScope scope;
144 v8::Local<v8::Context> ctx = frame->mainWorldScriptContext();
145 v8::Context::Scope cscope(ctx);
146 scoped_ptr<WebIntent> web_intent;
147
148 if (intent_->data_type == webkit_glue::WebIntentData::SERIALIZED) {
149 web_intent.reset(new WebIntent(intent_->action,
darin (slow to review) 2012/06/05 18:22:18 does some of this code need to be updated?
Greg Billock 2012/06/05 19:55:45 Yes. Didn't push the new version. Now done.
150 intent_->type,
151 intent_->data));
152 } else if (intent_->data_type == webkit_glue::WebIntentData::UNSERIALIZED) {
153 web_intent.reset(new WebIntent(intent_->action, intent_->type,
154 intent_->unserialized_data,
155 extras_keys, extras_values));
156 } else {
157 DCHECK(intent_->data_type == webkit_glue::WebIntentData::BLOB);
158 web_blob_ = WebBlob::createFromFile(
159 WebString::fromUTF8(intent_->blob_file.AsUTF8Unsafe()),
160 intent_->blob_length);
161 web_intent.reset(new WebIntent(intent_->action, intent_->type, &web_blob_,
162 extras_keys, extras_values));
163 }
164
165 frame->deliverIntent(*(web_intent.get()), delivered_intent_client_.get());
243 } 166 }
OLDNEW
« no previous file with comments | « content/renderer/web_intents_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698