OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/app_bindings.h" | 5 #include "chrome/renderer/extensions/app_bindings.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/string16.h" | 8 #include "base/string16.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 return false; | 46 return false; |
47 } | 47 } |
48 | 48 |
49 return true; | 49 return true; |
50 } | 50 } |
51 | 51 |
52 const char* kMissingClientIdError = "Missing clientId parameter"; | 52 const char* kMissingClientIdError = "Missing clientId parameter"; |
53 const char* kInvalidClientIdError = "Invalid clientId"; | 53 const char* kInvalidClientIdError = "Invalid clientId"; |
54 const char* kInvalidCallbackIdError = "Invalid callbackId"; | 54 const char* kInvalidCallbackIdError = "Invalid callbackId"; |
55 | 55 |
56 | |
57 class AppBindingsHandler : public ChromeV8ExtensionHandler { | |
58 public: | |
59 AppBindingsHandler(ExtensionDispatcher* dispatcher, ChromeV8Context* context); | |
60 | |
61 // ChromeV8ExtensionHandler | |
62 virtual v8::Handle<v8::Value> HandleNativeFunction( | |
63 const std::string& name, | |
64 const v8::Arguments& arguments) OVERRIDE; | |
65 | |
66 // IPC::Channel::Listener | |
67 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | |
68 | |
69 private: | |
70 v8::Handle<v8::Value> GetIsInstalled(const v8::Arguments& args); | |
71 v8::Handle<v8::Value> Install(const v8::Arguments& args); | |
72 v8::Handle<v8::Value> GetDetails(const v8::Arguments& args); | |
73 v8::Handle<v8::Value> GetDetailsForFrame(const v8::Arguments& args); | |
74 v8::Handle<v8::Value> GetAppNotifyChannel(const v8::Arguments& args); | |
75 | |
76 v8::Handle<v8::Value> GetDetailsForFrameImpl(WebKit::WebFrame* frame); | |
77 | |
78 void OnGetAppNotifyChannelResponse(const std::string& channel_id, | |
79 const std::string& error, | |
80 int callback_id); | |
81 | |
82 ExtensionDispatcher* dispatcher_; | |
83 DISALLOW_COPY_AND_ASSIGN(AppBindingsHandler); | |
84 }; | |
85 | |
86 } // namespace | 56 } // namespace |
87 | 57 |
88 | 58 |
89 AppBindings::AppBindings(ExtensionDispatcher* dispatcher) | 59 AppBindings::AppBindings(ExtensionDispatcher* dispatcher, |
60 ChromeV8Context* context) | |
90 : ChromeV8Extension("extensions/app.js", IDR_APP_BINDINGS_JS, | 61 : ChromeV8Extension("extensions/app.js", IDR_APP_BINDINGS_JS, |
91 dispatcher) { | 62 dispatcher), |
63 ChromeV8ExtensionHandler(context) { | |
92 } | 64 } |
93 | 65 |
94 ChromeV8ExtensionHandler* AppBindings::CreateHandler( | 66 AppBindings::~AppBindings() { |
95 ChromeV8Context* context) { | |
96 return new AppBindingsHandler(extension_dispatcher(), context); | |
97 } | 67 } |
98 | 68 |
99 | 69 void AppBindings::SetNativeFunctions(v8::Handle<v8::Object> object) { |
100 | 70 RouteFunctionHere("GetIsInstalled", object); |
101 AppBindingsHandler::AppBindingsHandler(ExtensionDispatcher* dispatcher, | 71 RouteFunctionHere("Install", object); |
102 ChromeV8Context* context) | 72 RouteFunctionHere("GetDetails", object); |
103 : ChromeV8ExtensionHandler(context), | 73 RouteFunctionHere("GetDetailsForFrame", object); |
104 dispatcher_(dispatcher) { | 74 RouteFunctionHere("GetAppNotifyChannel", object); |
105 } | 75 } |
106 | 76 |
107 v8::Handle<v8::Value> AppBindingsHandler::HandleNativeFunction( | 77 v8::Handle<v8::Value> AppBindings::HandleNativeFunction( |
108 const std::string& name, const v8::Arguments& args) { | 78 const std::string& name, const v8::Arguments& args) { |
109 // TODO(aa): Create a helper map of callback that can be used in either | 79 // TODO(aa): Create a helper map of callback that can be used in either |
110 // extensions or handlers. | 80 // extensions or handlers. |
111 if (name == "GetIsInstalled") { | 81 if (name == "GetIsInstalled") { |
Aaron Boodman
2012/02/16 01:54:42
It would be really nice to avoid this dance in eve
koz (OOO until 15th September)
2012/02/27 01:06:14
The new ModuleSystem handles this.
| |
112 return GetIsInstalled(args); | 82 return GetIsInstalled(args); |
113 } else if (name == "Install") { | 83 } else if (name == "Install") { |
114 return Install(args); | 84 return Install(args); |
115 } else if (name == "GetDetails") { | 85 } else if (name == "GetDetails") { |
116 return GetDetails(args); | 86 return GetDetails(args); |
117 } else if (name == "GetDetailsForFrame") { | 87 } else if (name == "GetDetailsForFrame") { |
118 return GetDetailsForFrame(args); | 88 return GetDetailsForFrame(args); |
119 } else if (name == "GetAppNotifyChannel") { | 89 } else if (name == "GetAppNotifyChannel") { |
120 return GetAppNotifyChannel(args); | 90 return GetAppNotifyChannel(args); |
121 } else { | 91 } else { |
122 CHECK(false) << "Unknown native function: " << name; | 92 CHECK(false) << "Unknown native function: " << name; |
123 } | 93 } |
124 | 94 |
125 return v8::Undefined(); | 95 return v8::Undefined(); |
126 } | 96 } |
127 | 97 |
128 v8::Handle<v8::Value> AppBindingsHandler::GetIsInstalled( | 98 v8::Handle<v8::Value> AppBindings::GetIsInstalled( |
129 const v8::Arguments& args) { | 99 const v8::Arguments& args) { |
130 // TODO(aa): Hm, maybe ExtensionBindingsContext should have GetExtension() | 100 // TODO(aa): Hm, maybe ExtensionBindingsContext should have GetExtension() |
131 // afterall? | 101 // afterall? |
132 const ::Extension* extension = | 102 const ::Extension* extension = |
133 dispatcher_->extensions()->GetByID(context_->extension_id()); | 103 extension_dispatcher_->extensions()->GetByID(context_->extension_id()); |
134 | 104 |
135 // TODO(aa): Why only hosted app? | 105 // TODO(aa): Why only hosted app? |
136 // TODO(aa): GARRR - why is there IsExtensionActive and IsApplicationActive!? | 106 // TODO(aa): GARRR - why is there IsExtensionActive and IsApplicationActive!? |
137 bool result = extension && extension->is_hosted_app() && | 107 bool result = extension && extension->is_hosted_app() && |
138 dispatcher_->IsApplicationActive(extension->id()); | 108 extension_dispatcher_->IsApplicationActive(extension->id()); |
139 return v8::Boolean::New(result); | 109 return v8::Boolean::New(result); |
140 } | 110 } |
141 | 111 |
142 v8::Handle<v8::Value> AppBindingsHandler::Install(const v8::Arguments& args) { | 112 v8::Handle<v8::Value> AppBindings::Install(const v8::Arguments& args) { |
143 content::RenderView* render_view = context_->GetRenderView(); | 113 content::RenderView* render_view = context_->GetRenderView(); |
144 CHECK(render_view); | 114 CHECK(render_view); |
145 | 115 |
146 string16 error; | 116 string16 error; |
147 ExtensionHelper* helper = ExtensionHelper::Get(render_view); | 117 ExtensionHelper* helper = ExtensionHelper::Get(render_view); |
148 if (!helper->InstallWebApplicationUsingDefinitionFile( | 118 if (!helper->InstallWebApplicationUsingDefinitionFile( |
149 context_->web_frame(), &error)) { | 119 context_->web_frame(), &error)) { |
150 v8::ThrowException(v8::String::New(UTF16ToUTF8(error).c_str())); | 120 v8::ThrowException(v8::String::New(UTF16ToUTF8(error).c_str())); |
151 } | 121 } |
152 | 122 |
153 return v8::Undefined(); | 123 return v8::Undefined(); |
154 } | 124 } |
155 | 125 |
156 v8::Handle<v8::Value> AppBindingsHandler::GetDetails( | 126 v8::Handle<v8::Value> AppBindings::GetDetails( |
157 const v8::Arguments& args) { | 127 const v8::Arguments& args) { |
158 CHECK(context_->web_frame()); | 128 CHECK(context_->web_frame()); |
159 return GetDetailsForFrameImpl(context_->web_frame()); | 129 return GetDetailsForFrameImpl(context_->web_frame()); |
160 } | 130 } |
161 | 131 |
162 v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrame( | 132 v8::Handle<v8::Value> AppBindings::GetDetailsForFrame( |
163 const v8::Arguments& args) { | 133 const v8::Arguments& args) { |
164 CHECK(context_->web_frame()); | 134 CHECK(context_->web_frame()); |
165 if (!CheckAccessToAppDetails(context_->web_frame())) | 135 if (!CheckAccessToAppDetails(context_->web_frame())) |
166 return v8::Undefined(); | 136 return v8::Undefined(); |
167 | 137 |
168 if (args.Length() < 0) | 138 if (args.Length() < 0) |
169 return v8::ThrowException(v8::String::New("Not enough arguments.")); | 139 return v8::ThrowException(v8::String::New("Not enough arguments.")); |
170 | 140 |
171 if (!args[0]->IsObject()) { | 141 if (!args[0]->IsObject()) { |
172 return v8::ThrowException( | 142 return v8::ThrowException( |
173 v8::String::New("Argument 0 must be an object.")); | 143 v8::String::New("Argument 0 must be an object.")); |
174 } | 144 } |
175 | 145 |
176 v8::Local<v8::Context> context = | 146 v8::Local<v8::Context> context = |
177 v8::Local<v8::Object>::Cast(args[0])->CreationContext(); | 147 v8::Local<v8::Object>::Cast(args[0])->CreationContext(); |
178 CHECK(!context.IsEmpty()); | 148 CHECK(!context.IsEmpty()); |
179 | 149 |
180 WebFrame* target_frame = WebFrame::frameForContext(context); | 150 WebFrame* target_frame = WebFrame::frameForContext(context); |
181 if (!target_frame) { | 151 if (!target_frame) { |
182 return v8::ThrowException( | 152 return v8::ThrowException( |
183 v8::String::New("Could not find frame for specified object.")); | 153 v8::String::New("Could not find frame for specified object.")); |
184 } | 154 } |
185 | 155 |
186 return GetDetailsForFrameImpl(target_frame); | 156 return GetDetailsForFrameImpl(target_frame); |
187 } | 157 } |
188 | 158 |
189 v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl( | 159 v8::Handle<v8::Value> AppBindings::GetDetailsForFrameImpl( |
190 WebFrame* frame) { | 160 WebFrame* frame) { |
191 const ::Extension* extension = | 161 const ::Extension* extension = |
192 dispatcher_->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo( | 162 extension_dispatcher_->extensions()->GetExtensionOrAppByURL( |
193 frame->document().securityOrigin(), | 163 ExtensionURLInfo(frame->document().securityOrigin(), |
194 frame->document().url())); | 164 frame->document().url())); |
195 if (!extension) | 165 if (!extension) |
196 return v8::Null(); | 166 return v8::Null(); |
197 | 167 |
198 scoped_ptr<DictionaryValue> manifest_copy( | 168 scoped_ptr<DictionaryValue> manifest_copy( |
199 extension->manifest()->value()->DeepCopy()); | 169 extension->manifest()->value()->DeepCopy()); |
200 manifest_copy->SetString("id", extension->id()); | 170 manifest_copy->SetString("id", extension->id()); |
201 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); | 171 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
202 return converter->ToV8Value(manifest_copy.get(), | 172 return converter->ToV8Value(manifest_copy.get(), |
203 frame->mainWorldScriptContext()); | 173 frame->mainWorldScriptContext()); |
204 } | 174 } |
205 | 175 |
206 v8::Handle<v8::Value> AppBindingsHandler::GetAppNotifyChannel( | 176 v8::Handle<v8::Value> AppBindings::GetAppNotifyChannel( |
207 const v8::Arguments& args) { | 177 const v8::Arguments& args) { |
208 // Read the required 'clientId' value out of the object at args[0]. | 178 // Read the required 'clientId' value out of the object at args[0]. |
209 std::string client_id; | 179 std::string client_id; |
210 if (args.Length() < 1 || !args[0]->IsObject()) { | 180 if (args.Length() < 1 || !args[0]->IsObject()) { |
211 v8::ThrowException(v8::String::New(kMissingClientIdError)); | 181 v8::ThrowException(v8::String::New(kMissingClientIdError)); |
212 return v8::Undefined(); | 182 return v8::Undefined(); |
213 } | 183 } |
214 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(args[0]); | 184 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(args[0]); |
215 v8::Local<v8::String> client_id_key = v8::String::New("clientId"); | 185 v8::Local<v8::String> client_id_key = v8::String::New("clientId"); |
216 if (obj->Has(client_id_key)) { | 186 if (obj->Has(client_id_key)) { |
(...skipping 18 matching lines...) Expand all Loading... | |
235 | 205 |
236 content::RenderView* render_view = context_->GetRenderView(); | 206 content::RenderView* render_view = context_->GetRenderView(); |
237 CHECK(render_view); | 207 CHECK(render_view); |
238 | 208 |
239 Send(new ExtensionHostMsg_GetAppNotifyChannel( | 209 Send(new ExtensionHostMsg_GetAppNotifyChannel( |
240 render_view->GetRoutingId(), context_->web_frame()->document().url(), | 210 render_view->GetRoutingId(), context_->web_frame()->document().url(), |
241 client_id, GetRoutingId(), callback_id)); | 211 client_id, GetRoutingId(), callback_id)); |
242 return v8::Undefined(); | 212 return v8::Undefined(); |
243 } | 213 } |
244 | 214 |
245 bool AppBindingsHandler::OnMessageReceived(const IPC::Message& message) { | 215 bool AppBindings::OnMessageReceived(const IPC::Message& message) { |
246 IPC_BEGIN_MESSAGE_MAP(AppBindingsHandler, message) | 216 IPC_BEGIN_MESSAGE_MAP(AppBindings, message) |
247 IPC_MESSAGE_HANDLER(ExtensionMsg_GetAppNotifyChannelResponse, | 217 IPC_MESSAGE_HANDLER(ExtensionMsg_GetAppNotifyChannelResponse, |
248 OnGetAppNotifyChannelResponse) | 218 OnGetAppNotifyChannelResponse) |
249 IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") | 219 IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") |
250 IPC_END_MESSAGE_MAP() | 220 IPC_END_MESSAGE_MAP() |
251 return true; | 221 return true; |
252 } | 222 } |
253 | 223 |
254 void AppBindingsHandler::OnGetAppNotifyChannelResponse( | 224 void AppBindings::OnGetAppNotifyChannelResponse( |
255 const std::string& channel_id, const std::string& error, int callback_id) { | 225 const std::string& channel_id, const std::string& error, int callback_id) { |
256 v8::HandleScope handle_scope; | 226 v8::HandleScope handle_scope; |
257 v8::Context::Scope context_scope(context_->v8_context()); | 227 v8::Context::Scope context_scope(context_->v8_context()); |
258 v8::Handle<v8::Value> argv[3]; | 228 v8::Handle<v8::Value> argv[3]; |
259 argv[0] = v8::String::New(channel_id.c_str()); | 229 argv[0] = v8::String::New(channel_id.c_str()); |
260 argv[1] = v8::String::New(error.c_str()); | 230 argv[1] = v8::String::New(error.c_str()); |
261 argv[2] = v8::Integer::New(callback_id); | 231 argv[2] = v8::Integer::New(callback_id); |
262 CHECK(context_->CallChromeHiddenMethod("app.onGetAppNotifyChannelResponse", | 232 CHECK(context_->CallChromeHiddenMethod("app.onGetAppNotifyChannelResponse", |
263 arraysize(argv), argv, NULL)); | 233 arraysize(argv), argv, NULL)); |
264 } | 234 } |
OLD | NEW |