| 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/dispatcher.h" | 5 #include "chrome/renderer/extensions/dispatcher.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/alias.h" | 9 #include "base/debug/alias.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 #include "chrome/renderer/resource_bundle_source_map.h" | 76 #include "chrome/renderer/resource_bundle_source_map.h" |
| 77 #include "content/public/renderer/render_thread.h" | 77 #include "content/public/renderer/render_thread.h" |
| 78 #include "content/public/renderer/render_view.h" | 78 #include "content/public/renderer/render_view.h" |
| 79 #include "content/public/renderer/v8_value_converter.h" | 79 #include "content/public/renderer/v8_value_converter.h" |
| 80 #include "extensions/common/constants.h" | 80 #include "extensions/common/constants.h" |
| 81 #include "extensions/common/view_type.h" | 81 #include "extensions/common/view_type.h" |
| 82 #include "grit/common_resources.h" | 82 #include "grit/common_resources.h" |
| 83 #include "grit/renderer_resources.h" | 83 #include "grit/renderer_resources.h" |
| 84 #include "third_party/WebKit/public/platform/WebString.h" | 84 #include "third_party/WebKit/public/platform/WebString.h" |
| 85 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 85 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| 86 #include "third_party/WebKit/public/web/WebCustomElement.h" |
| 86 #include "third_party/WebKit/public/web/WebDataSource.h" | 87 #include "third_party/WebKit/public/web/WebDataSource.h" |
| 87 #include "third_party/WebKit/public/web/WebDocument.h" | 88 #include "third_party/WebKit/public/web/WebDocument.h" |
| 88 #include "third_party/WebKit/public/web/WebFrame.h" | 89 #include "third_party/WebKit/public/web/WebFrame.h" |
| 90 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
| 89 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" | 91 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" |
| 90 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" | 92 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" |
| 91 #include "third_party/WebKit/public/web/WebView.h" | 93 #include "third_party/WebKit/public/web/WebView.h" |
| 92 #include "ui/base/layout.h" | 94 #include "ui/base/layout.h" |
| 93 #include "ui/base/resource/resource_bundle.h" | 95 #include "ui/base/resource/resource_bundle.h" |
| 94 #include "v8/include/v8.h" | 96 #include "v8/include/v8.h" |
| 95 | 97 |
| 96 using WebKit::WebDataSource; | 98 using WebKit::WebDataSource; |
| 97 using WebKit::WebDocument; | 99 using WebKit::WebDocument; |
| 98 using WebKit::WebFrame; | 100 using WebKit::WebFrame; |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 | 467 |
| 466 // Initialize host permissions for any extensions that were activated before | 468 // Initialize host permissions for any extensions that were activated before |
| 467 // WebKit was initialized. | 469 // WebKit was initialized. |
| 468 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); | 470 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); |
| 469 iter != active_extension_ids_.end(); ++iter) { | 471 iter != active_extension_ids_.end(); ++iter) { |
| 470 const Extension* extension = extensions_.GetByID(*iter); | 472 const Extension* extension = extensions_.GetByID(*iter); |
| 471 CHECK(extension); | 473 CHECK(extension); |
| 472 InitOriginPermissions(extension); | 474 InitOriginPermissions(extension); |
| 473 } | 475 } |
| 474 | 476 |
| 477 if (IsWithinPlatformApp()) |
| 478 EnableCustomElementWhiteList(); |
| 479 |
| 475 is_webkit_initialized_ = true; | 480 is_webkit_initialized_ = true; |
| 476 } | 481 } |
| 477 | 482 |
| 478 void Dispatcher::IdleNotification() { | 483 void Dispatcher::IdleNotification() { |
| 479 if (is_extension_process_) { | 484 if (is_extension_process_) { |
| 480 // Dampen the forced delay as well if the extension stays idle for long | 485 // Dampen the forced delay as well if the extension stays idle for long |
| 481 // periods of time. | 486 // periods of time. |
| 482 int64 forced_delay_ms = std::max( | 487 int64 forced_delay_ms = std::max( |
| 483 RenderThread::Get()->GetIdleNotificationDelayInMs(), | 488 RenderThread::Get()->GetIdleNotificationDelayInMs(), |
| 484 kMaxExtensionIdleHandlerDelayMs); | 489 kMaxExtensionIdleHandlerDelayMs); |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 // lazily evalulate to Event from event_bindings.js. For extensions only | 1074 // lazily evalulate to Event from event_bindings.js. For extensions only |
| 1070 // though, not all webpages! | 1075 // though, not all webpages! |
| 1071 if (context->extension()) { | 1076 if (context->extension()) { |
| 1072 v8::Handle<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); | 1077 v8::Handle<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); |
| 1073 if (!chrome.IsEmpty()) | 1078 if (!chrome.IsEmpty()) |
| 1074 module_system->SetLazyField(chrome, "Event", kEventModule, "Event"); | 1079 module_system->SetLazyField(chrome, "Event", kEventModule, "Event"); |
| 1075 } | 1080 } |
| 1076 | 1081 |
| 1077 AddOrRemoveBindingsForContext(context); | 1082 AddOrRemoveBindingsForContext(context); |
| 1078 | 1083 |
| 1079 bool is_within_platform_app = IsWithinPlatformApp(frame); | 1084 bool is_within_platform_app = IsWithinPlatformApp(); |
| 1080 // Inject custom JS into the platform app context. | 1085 // Inject custom JS into the platform app context. |
| 1081 if (is_within_platform_app) { | 1086 if (is_within_platform_app) { |
| 1082 module_system->Require("platformApp"); | 1087 module_system->Require("platformApp"); |
| 1083 } | 1088 } |
| 1084 | 1089 |
| 1085 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT && | 1090 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT && |
| 1086 is_within_platform_app && | 1091 is_within_platform_app && |
| 1087 Feature::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV && | 1092 Feature::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV && |
| 1088 CommandLine::ForCurrentProcess()->HasSwitch( | 1093 CommandLine::ForCurrentProcess()->HasSwitch( |
| 1089 switches::kEnableAppWindowControls)) { | 1094 switches::kEnableAppWindowControls)) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 | 1147 |
| 1143 // TODO(kalman): Delete this check. | 1148 // TODO(kalman): Delete this check. |
| 1144 if (frame->document().securityOrigin().isUnique()) | 1149 if (frame->document().securityOrigin().isUnique()) |
| 1145 return std::string(); | 1150 return std::string(); |
| 1146 | 1151 |
| 1147 // Extension pages (chrome-extension:// URLs). | 1152 // Extension pages (chrome-extension:// URLs). |
| 1148 GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame); | 1153 GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame); |
| 1149 return extensions_.GetExtensionOrAppIDByURL(frame_url); | 1154 return extensions_.GetExtensionOrAppIDByURL(frame_url); |
| 1150 } | 1155 } |
| 1151 | 1156 |
| 1152 bool Dispatcher::IsWithinPlatformApp(const WebFrame* frame) { | 1157 bool Dispatcher::IsWithinPlatformApp() { |
| 1153 GURL url(UserScriptSlave::GetDataSourceURLForFrame(frame->top())); | 1158 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); |
| 1154 const Extension* extension = extensions_.GetExtensionOrAppByURL(url); | 1159 iter != active_extension_ids_.end(); ++iter) { |
| 1155 | 1160 const Extension* extension = extensions_.GetByID(*iter); |
| 1156 return extension && extension->is_platform_app(); | 1161 if (extension && extension->is_platform_app()) |
| 1162 return true; |
| 1163 } |
| 1164 return false; |
| 1157 } | 1165 } |
| 1158 | 1166 |
| 1159 void Dispatcher::WillReleaseScriptContext( | 1167 void Dispatcher::WillReleaseScriptContext( |
| 1160 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { | 1168 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { |
| 1161 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); | 1169 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); |
| 1162 if (!context) | 1170 if (!context) |
| 1163 return; | 1171 return; |
| 1164 | 1172 |
| 1165 context->DispatchOnUnloadEvent(); | 1173 context->DispatchOnUnloadEvent(); |
| 1166 // TODO(kalman): add an invalidation observer interface to ChromeV8Context. | 1174 // TODO(kalman): add an invalidation observer interface to ChromeV8Context. |
| 1167 request_sender_->InvalidateSource(context); | 1175 request_sender_->InvalidateSource(context); |
| 1168 | 1176 |
| 1169 v8_context_set_.Remove(context); | 1177 v8_context_set_.Remove(context); |
| 1170 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); | 1178 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); |
| 1171 } | 1179 } |
| 1172 | 1180 |
| 1173 void Dispatcher::DidCreateDocumentElement(WebKit::WebFrame* frame) { | 1181 void Dispatcher::DidCreateDocumentElement(WebKit::WebFrame* frame) { |
| 1174 if (IsWithinPlatformApp(frame)) { | 1182 if (IsWithinPlatformApp()) { |
| 1175 // WebKit doesn't let us define an additional user agent stylesheet, so we | 1183 // WebKit doesn't let us define an additional user agent stylesheet, so we |
| 1176 // insert the default platform app stylesheet into all documents that are | 1184 // insert the default platform app stylesheet into all documents that are |
| 1177 // loaded in each app. | 1185 // loaded in each app. |
| 1178 std::string stylesheet = | 1186 std::string stylesheet = |
| 1179 ResourceBundle::GetSharedInstance(). | 1187 ResourceBundle::GetSharedInstance(). |
| 1180 GetRawDataResource(IDR_PLATFORM_APP_CSS).as_string(); | 1188 GetRawDataResource(IDR_PLATFORM_APP_CSS).as_string(); |
| 1181 ReplaceFirstSubstringAfterOffset(&stylesheet, 0, | 1189 ReplaceFirstSubstringAfterOffset(&stylesheet, 0, |
| 1182 "$FONTFAMILY", system_font_family_); | 1190 "$FONTFAMILY", system_font_family_); |
| 1183 ReplaceFirstSubstringAfterOffset(&stylesheet, 0, | 1191 ReplaceFirstSubstringAfterOffset(&stylesheet, 0, |
| 1184 "$FONTSIZE", system_font_size_); | 1192 "$FONTSIZE", system_font_size_); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1215 | 1223 |
| 1216 if (is_webkit_initialized_) { | 1224 if (is_webkit_initialized_) { |
| 1217 InitOriginPermissions(extension); | 1225 InitOriginPermissions(extension); |
| 1218 // DOMActivity logger for a main world controlled by an extension (as in | 1226 // DOMActivity logger for a main world controlled by an extension (as in |
| 1219 // the case of an extension background page, options page, popup etc.) | 1227 // the case of an extension background page, options page, popup etc.) |
| 1220 // gets an empty title. | 1228 // gets an empty title. |
| 1221 DOMActivityLogger::AttachToWorld(DOMActivityLogger::kMainWorldId, | 1229 DOMActivityLogger::AttachToWorld(DOMActivityLogger::kMainWorldId, |
| 1222 extension_id, | 1230 extension_id, |
| 1223 extension->url(), | 1231 extension->url(), |
| 1224 string16()); | 1232 string16()); |
| 1233 |
| 1234 if (IsWithinPlatformApp()) |
| 1235 EnableCustomElementWhiteList(); |
| 1225 } | 1236 } |
| 1226 } | 1237 } |
| 1227 | 1238 |
| 1228 void Dispatcher::InitOriginPermissions(const Extension* extension) { | 1239 void Dispatcher::InitOriginPermissions(const Extension* extension) { |
| 1229 // TODO(jstritar): We should try to remove this special case. Also, these | 1240 // TODO(jstritar): We should try to remove this special case. Also, these |
| 1230 // whitelist entries need to be updated when the kManagement permission | 1241 // whitelist entries need to be updated when the kManagement permission |
| 1231 // changes. | 1242 // changes. |
| 1232 if (extension->HasAPIPermission(APIPermission::kManagement)) { | 1243 if (extension->HasAPIPermission(APIPermission::kManagement)) { |
| 1233 WebSecurityPolicy::addOriginAccessWhitelistEntry( | 1244 WebSecurityPolicy::addOriginAccessWhitelistEntry( |
| 1234 extension->url(), | 1245 extension->url(), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1262 WebSecurityPolicy::addOriginAccessWhitelistEntry)( | 1273 WebSecurityPolicy::addOriginAccessWhitelistEntry)( |
| 1263 extension->url(), | 1274 extension->url(), |
| 1264 WebString::fromUTF8(schemes[j]), | 1275 WebString::fromUTF8(schemes[j]), |
| 1265 WebString::fromUTF8(i->host()), | 1276 WebString::fromUTF8(i->host()), |
| 1266 i->match_subdomains()); | 1277 i->match_subdomains()); |
| 1267 } | 1278 } |
| 1268 } | 1279 } |
| 1269 } | 1280 } |
| 1270 } | 1281 } |
| 1271 | 1282 |
| 1283 void Dispatcher::EnableCustomElementWhiteList() { |
| 1284 WebKit::WebRuntimeFeatures::enableCustomElements(true); |
| 1285 WebKit::WebCustomElement::allowTagName("webview"); |
| 1286 // TODO(fsamuel): Add <adview> to the whitelist once it has been converted |
| 1287 // into a custom element. |
| 1288 WebKit::WebCustomElement::allowTagName("browser-plugin"); |
| 1289 } |
| 1290 |
| 1272 void Dispatcher::AddOrRemoveBindings(const std::string& extension_id) { | 1291 void Dispatcher::AddOrRemoveBindings(const std::string& extension_id) { |
| 1273 v8_context_set().ForEach( | 1292 v8_context_set().ForEach( |
| 1274 extension_id, | 1293 extension_id, |
| 1275 NULL, // all render views | 1294 NULL, // all render views |
| 1276 base::Bind(&Dispatcher::AddOrRemoveBindingsForContext, | 1295 base::Bind(&Dispatcher::AddOrRemoveBindingsForContext, |
| 1277 base::Unretained(this))); | 1296 base::Unretained(this))); |
| 1278 } | 1297 } |
| 1279 | 1298 |
| 1280 void Dispatcher::OnUpdatePermissions(int reason_id, | 1299 void Dispatcher::OnUpdatePermissions(int reason_id, |
| 1281 const std::string& extension_id, | 1300 const std::string& extension_id, |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 RenderView* background_view = | 1549 RenderView* background_view = |
| 1531 ExtensionHelper::GetBackgroundPage(extension_id); | 1550 ExtensionHelper::GetBackgroundPage(extension_id); |
| 1532 if (background_view) { | 1551 if (background_view) { |
| 1533 background_view->Send(new ExtensionHostMsg_EventAck( | 1552 background_view->Send(new ExtensionHostMsg_EventAck( |
| 1534 background_view->GetRoutingID())); | 1553 background_view->GetRoutingID())); |
| 1535 } | 1554 } |
| 1536 } | 1555 } |
| 1537 } | 1556 } |
| 1538 | 1557 |
| 1539 } // namespace extensions | 1558 } // namespace extensions |
| OLD | NEW |