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