| 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, |
| 90 : ChromeV8Extension("extensions/app.js", IDR_APP_BINDINGS_JS, | 60 ChromeV8Context* context) |
| 91 dispatcher) { | 61 : ChromeV8Extension(dispatcher), |
| 92 } | 62 ChromeV8ExtensionHandler(context) { |
| 93 | 63 RouteFunction("GetIsInstalled", |
| 94 ChromeV8ExtensionHandler* AppBindings::CreateHandler( | 64 base::Bind(&AppBindings::GetIsInstalled, base::Unretained(this))); |
| 95 ChromeV8Context* context) { | 65 RouteFunction("Install", |
| 96 return new AppBindingsHandler(extension_dispatcher(), context); | 66 base::Bind(&AppBindings::Install, base::Unretained(this))); |
| 67 RouteFunction("GetDetails", |
| 68 base::Bind(&AppBindings::GetDetails, base::Unretained(this))); |
| 69 RouteFunction("GetDetailsForFrame", |
| 70 base::Bind(&AppBindings::GetDetailsForFrame, base::Unretained(this))); |
| 71 RouteFunction("GetAppNotifyChannel", |
| 72 base::Bind(&AppBindings::GetAppNotifyChannel, base::Unretained(this))); |
| 97 } | 73 } |
| 98 | 74 |
| 99 | 75 |
| 100 | 76 v8::Handle<v8::Value> AppBindings::GetIsInstalled( |
| 101 AppBindingsHandler::AppBindingsHandler(ExtensionDispatcher* dispatcher, | |
| 102 ChromeV8Context* context) | |
| 103 : ChromeV8ExtensionHandler(context), | |
| 104 dispatcher_(dispatcher) { | |
| 105 } | |
| 106 | |
| 107 v8::Handle<v8::Value> AppBindingsHandler::HandleNativeFunction( | |
| 108 const std::string& name, const v8::Arguments& args) { | |
| 109 // TODO(aa): Create a helper map of callback that can be used in either | |
| 110 // extensions or handlers. | |
| 111 if (name == "GetIsInstalled") { | |
| 112 return GetIsInstalled(args); | |
| 113 } else if (name == "Install") { | |
| 114 return Install(args); | |
| 115 } else if (name == "GetDetails") { | |
| 116 return GetDetails(args); | |
| 117 } else if (name == "GetDetailsForFrame") { | |
| 118 return GetDetailsForFrame(args); | |
| 119 } else if (name == "GetAppNotifyChannel") { | |
| 120 return GetAppNotifyChannel(args); | |
| 121 } else { | |
| 122 CHECK(false) << "Unknown native function: " << name; | |
| 123 } | |
| 124 | |
| 125 return v8::Undefined(); | |
| 126 } | |
| 127 | |
| 128 v8::Handle<v8::Value> AppBindingsHandler::GetIsInstalled( | |
| 129 const v8::Arguments& args) { | 77 const v8::Arguments& args) { |
| 130 // TODO(aa): Hm, maybe ExtensionBindingsContext should have GetExtension() | 78 // TODO(aa): Hm, maybe ExtensionBindingsContext should have GetExtension() |
| 131 // afterall? | 79 // afterall? |
| 132 const ::Extension* extension = | 80 const ::Extension* extension = |
| 133 dispatcher_->extensions()->GetByID(context_->extension_id()); | 81 extension_dispatcher_->extensions()->GetByID(context_->extension_id()); |
| 134 | 82 |
| 135 // TODO(aa): Why only hosted app? | 83 // TODO(aa): Why only hosted app? |
| 136 // TODO(aa): GARRR - why is there IsExtensionActive and IsApplicationActive!? | 84 // TODO(aa): GARRR - why is there IsExtensionActive and IsApplicationActive!? |
| 137 bool result = extension && extension->is_hosted_app() && | 85 bool result = extension && extension->is_hosted_app() && |
| 138 dispatcher_->IsApplicationActive(extension->id()); | 86 extension_dispatcher_->IsApplicationActive(extension->id()); |
| 139 return v8::Boolean::New(result); | 87 return v8::Boolean::New(result); |
| 140 } | 88 } |
| 141 | 89 |
| 142 v8::Handle<v8::Value> AppBindingsHandler::Install(const v8::Arguments& args) { | 90 v8::Handle<v8::Value> AppBindings::Install(const v8::Arguments& args) { |
| 143 content::RenderView* render_view = context_->GetRenderView(); | 91 content::RenderView* render_view = context_->GetRenderView(); |
| 144 CHECK(render_view); | 92 CHECK(render_view); |
| 145 | 93 |
| 146 string16 error; | 94 string16 error; |
| 147 ExtensionHelper* helper = ExtensionHelper::Get(render_view); | 95 ExtensionHelper* helper = ExtensionHelper::Get(render_view); |
| 148 if (!helper->InstallWebApplicationUsingDefinitionFile( | 96 if (!helper->InstallWebApplicationUsingDefinitionFile( |
| 149 context_->web_frame(), &error)) { | 97 context_->web_frame(), &error)) { |
| 150 v8::ThrowException(v8::String::New(UTF16ToUTF8(error).c_str())); | 98 v8::ThrowException(v8::String::New(UTF16ToUTF8(error).c_str())); |
| 151 } | 99 } |
| 152 | 100 |
| 153 return v8::Undefined(); | 101 return v8::Undefined(); |
| 154 } | 102 } |
| 155 | 103 |
| 156 v8::Handle<v8::Value> AppBindingsHandler::GetDetails( | 104 v8::Handle<v8::Value> AppBindings::GetDetails( |
| 157 const v8::Arguments& args) { | 105 const v8::Arguments& args) { |
| 158 CHECK(context_->web_frame()); | 106 CHECK(context_->web_frame()); |
| 159 return GetDetailsForFrameImpl(context_->web_frame()); | 107 return GetDetailsForFrameImpl(context_->web_frame()); |
| 160 } | 108 } |
| 161 | 109 |
| 162 v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrame( | 110 v8::Handle<v8::Value> AppBindings::GetDetailsForFrame( |
| 163 const v8::Arguments& args) { | 111 const v8::Arguments& args) { |
| 164 CHECK(context_->web_frame()); | 112 CHECK(context_->web_frame()); |
| 165 if (!CheckAccessToAppDetails(context_->web_frame())) | 113 if (!CheckAccessToAppDetails(context_->web_frame())) |
| 166 return v8::Undefined(); | 114 return v8::Undefined(); |
| 167 | 115 |
| 168 if (args.Length() < 0) | 116 if (args.Length() < 0) |
| 169 return v8::ThrowException(v8::String::New("Not enough arguments.")); | 117 return v8::ThrowException(v8::String::New("Not enough arguments.")); |
| 170 | 118 |
| 171 if (!args[0]->IsObject()) { | 119 if (!args[0]->IsObject()) { |
| 172 return v8::ThrowException( | 120 return v8::ThrowException( |
| 173 v8::String::New("Argument 0 must be an object.")); | 121 v8::String::New("Argument 0 must be an object.")); |
| 174 } | 122 } |
| 175 | 123 |
| 176 v8::Local<v8::Context> context = | 124 v8::Local<v8::Context> context = |
| 177 v8::Local<v8::Object>::Cast(args[0])->CreationContext(); | 125 v8::Local<v8::Object>::Cast(args[0])->CreationContext(); |
| 178 CHECK(!context.IsEmpty()); | 126 CHECK(!context.IsEmpty()); |
| 179 | 127 |
| 180 WebFrame* target_frame = WebFrame::frameForContext(context); | 128 WebFrame* target_frame = WebFrame::frameForContext(context); |
| 181 if (!target_frame) { | 129 if (!target_frame) { |
| 182 return v8::ThrowException( | 130 return v8::ThrowException( |
| 183 v8::String::New("Could not find frame for specified object.")); | 131 v8::String::New("Could not find frame for specified object.")); |
| 184 } | 132 } |
| 185 | 133 |
| 186 return GetDetailsForFrameImpl(target_frame); | 134 return GetDetailsForFrameImpl(target_frame); |
| 187 } | 135 } |
| 188 | 136 |
| 189 v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl( | 137 v8::Handle<v8::Value> AppBindings::GetDetailsForFrameImpl( |
| 190 WebFrame* frame) { | 138 WebFrame* frame) { |
| 191 const ::Extension* extension = | 139 const ::Extension* extension = |
| 192 dispatcher_->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo( | 140 extension_dispatcher_->extensions()->GetExtensionOrAppByURL( |
| 193 frame->document().securityOrigin(), | 141 ExtensionURLInfo(frame->document().securityOrigin(), |
| 194 frame->document().url())); | 142 frame->document().url())); |
| 195 if (!extension) | 143 if (!extension) |
| 196 return v8::Null(); | 144 return v8::Null(); |
| 197 | 145 |
| 198 scoped_ptr<DictionaryValue> manifest_copy( | 146 scoped_ptr<DictionaryValue> manifest_copy( |
| 199 extension->manifest()->value()->DeepCopy()); | 147 extension->manifest()->value()->DeepCopy()); |
| 200 manifest_copy->SetString("id", extension->id()); | 148 manifest_copy->SetString("id", extension->id()); |
| 201 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); | 149 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| 202 return converter->ToV8Value(manifest_copy.get(), | 150 return converter->ToV8Value(manifest_copy.get(), |
| 203 frame->mainWorldScriptContext()); | 151 frame->mainWorldScriptContext()); |
| 204 } | 152 } |
| 205 | 153 |
| 206 v8::Handle<v8::Value> AppBindingsHandler::GetAppNotifyChannel( | 154 v8::Handle<v8::Value> AppBindings::GetAppNotifyChannel( |
| 207 const v8::Arguments& args) { | 155 const v8::Arguments& args) { |
| 208 // Read the required 'clientId' value out of the object at args[0]. | 156 // Read the required 'clientId' value out of the object at args[0]. |
| 209 std::string client_id; | 157 std::string client_id; |
| 210 if (args.Length() < 1 || !args[0]->IsObject()) { | 158 if (args.Length() < 1 || !args[0]->IsObject()) { |
| 211 v8::ThrowException(v8::String::New(kMissingClientIdError)); | 159 v8::ThrowException(v8::String::New(kMissingClientIdError)); |
| 212 return v8::Undefined(); | 160 return v8::Undefined(); |
| 213 } | 161 } |
| 214 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(args[0]); | 162 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(args[0]); |
| 215 v8::Local<v8::String> client_id_key = v8::String::New("clientId"); | 163 v8::Local<v8::String> client_id_key = v8::String::New("clientId"); |
| 216 if (obj->Has(client_id_key)) { | 164 if (obj->Has(client_id_key)) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 235 | 183 |
| 236 content::RenderView* render_view = context_->GetRenderView(); | 184 content::RenderView* render_view = context_->GetRenderView(); |
| 237 CHECK(render_view); | 185 CHECK(render_view); |
| 238 | 186 |
| 239 Send(new ExtensionHostMsg_GetAppNotifyChannel( | 187 Send(new ExtensionHostMsg_GetAppNotifyChannel( |
| 240 render_view->GetRoutingId(), context_->web_frame()->document().url(), | 188 render_view->GetRoutingId(), context_->web_frame()->document().url(), |
| 241 client_id, GetRoutingId(), callback_id)); | 189 client_id, GetRoutingId(), callback_id)); |
| 242 return v8::Undefined(); | 190 return v8::Undefined(); |
| 243 } | 191 } |
| 244 | 192 |
| 245 bool AppBindingsHandler::OnMessageReceived(const IPC::Message& message) { | 193 bool AppBindings::OnMessageReceived(const IPC::Message& message) { |
| 246 IPC_BEGIN_MESSAGE_MAP(AppBindingsHandler, message) | 194 IPC_BEGIN_MESSAGE_MAP(AppBindings, message) |
| 247 IPC_MESSAGE_HANDLER(ExtensionMsg_GetAppNotifyChannelResponse, | 195 IPC_MESSAGE_HANDLER(ExtensionMsg_GetAppNotifyChannelResponse, |
| 248 OnGetAppNotifyChannelResponse) | 196 OnGetAppNotifyChannelResponse) |
| 249 IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") | 197 IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") |
| 250 IPC_END_MESSAGE_MAP() | 198 IPC_END_MESSAGE_MAP() |
| 251 return true; | 199 return true; |
| 252 } | 200 } |
| 253 | 201 |
| 254 void AppBindingsHandler::OnGetAppNotifyChannelResponse( | 202 void AppBindings::OnGetAppNotifyChannelResponse( |
| 255 const std::string& channel_id, const std::string& error, int callback_id) { | 203 const std::string& channel_id, const std::string& error, int callback_id) { |
| 256 v8::HandleScope handle_scope; | 204 v8::HandleScope handle_scope; |
| 257 v8::Context::Scope context_scope(context_->v8_context()); | 205 v8::Context::Scope context_scope(context_->v8_context()); |
| 258 v8::Handle<v8::Value> argv[3]; | 206 v8::Handle<v8::Value> argv[3]; |
| 259 argv[0] = v8::String::New(channel_id.c_str()); | 207 argv[0] = v8::String::New(channel_id.c_str()); |
| 260 argv[1] = v8::String::New(error.c_str()); | 208 argv[1] = v8::String::New(error.c_str()); |
| 261 argv[2] = v8::Integer::New(callback_id); | 209 argv[2] = v8::Integer::New(callback_id); |
| 262 CHECK(context_->CallChromeHiddenMethod("app.onGetAppNotifyChannelResponse", | 210 CHECK(context_->CallChromeHiddenMethod("app.onGetAppNotifyChannelResponse", |
| 263 arraysize(argv), argv, NULL)); | 211 arraysize(argv), argv, NULL)); |
| 264 } | 212 } |
| OLD | NEW |