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 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
712 CHECK(value->IsObject()); | 712 CHECK(value->IsObject()); |
713 return handle_scope.Close(v8::Handle<v8::Object>::Cast(value)); | 713 return handle_scope.Close(v8::Handle<v8::Object>::Cast(value)); |
714 } | 714 } |
715 | 715 |
716 v8::Handle<v8::Object> new_object = v8::Object::New(); | 716 v8::Handle<v8::Object> new_object = v8::Object::New(); |
717 object->Set(key, new_object); | 717 object->Set(key, new_object); |
718 return handle_scope.Close(new_object); | 718 return handle_scope.Close(new_object); |
719 } | 719 } |
720 | 720 |
721 void Dispatcher::RegisterSchemaGeneratedBindings( | 721 void Dispatcher::RegisterSchemaGeneratedBindings( |
722 ModuleSystem* module_system, | 722 ModuleSystem* module_system, |
not at google - send to devlin
2013/05/31 16:35:00
actually module_system on here isn't necessary bec
cduvall
2013/06/05 03:05:56
Done.
| |
723 ChromeV8Context* context) { | 723 ChromeV8Context* context) { |
724 std::set<std::string> apis = | 724 std::set<std::string> apis = |
725 ExtensionAPI::GetSharedInstance()->GetAllAPINames(); | 725 ExtensionAPI::GetSharedInstance()->GetAllAPINames(); |
726 for (std::set<std::string>::iterator it = apis.begin(); | 726 for (std::set<std::string>::iterator it = apis.begin(); |
727 it != apis.end(); ++it) { | 727 it != apis.end(); ++it) { |
728 const std::string& api_name = *it; | 728 const std::string& api_name = *it; |
729 if (!context->IsAnyFeatureAvailableToContext(api_name)) | 729 if (!context->IsAnyFeatureAvailableToContext(api_name)) { |
730 RemoveAPIBindingIfPresent(api_name, context); | |
730 continue; | 731 continue; |
732 } | |
731 | 733 |
732 Feature* feature = | 734 Feature* feature = |
733 BaseFeatureProvider::GetByName("api")->GetFeature(api_name); | 735 BaseFeatureProvider::GetByName("api")->GetFeature(api_name); |
734 if (feature && feature->IsInternal()) | 736 if (feature && feature->IsInternal()) |
735 continue; | 737 continue; |
736 | 738 |
737 std::vector<std::string> split; | 739 RegisterBinding(api_name, module_system, context); |
738 base::SplitString(api_name, '.', &split); | |
739 | |
740 v8::Handle<v8::Object> bind_object = | |
741 GetOrCreateChrome(context->v8_context()); | |
742 | |
743 // Check if this API has an ancestor. If the API's ancestor is available and | |
744 // the API is not available, don't install the bindings for this API. If | |
745 // the API is available and its ancestor is not, delete the ancestor and | |
746 // install the bindings for the API. This is to prevent loading the ancestor | |
747 // API schema if it will not be needed. | |
748 // | |
749 // For example: | |
750 // If app is available and app.window is not, just install app. | |
751 // If app.window is available and app is not, delete app and install | |
752 // app.window on a new object so app does not have to be loaded. | |
753 std::string ancestor_name; | |
754 bool only_ancestor_available = false; | |
755 for (size_t i = 0; i < split.size() - 1; ++i) { | |
756 ancestor_name += (i ? ".": "") + split[i]; | |
757 if (!ancestor_name.empty() && | |
758 context->GetAvailability(ancestor_name).is_available() && | |
759 !context->GetAvailability(api_name).is_available()) { | |
760 only_ancestor_available = true; | |
761 break; | |
762 } | |
763 bind_object = GetOrCreateObject(bind_object, split[i]); | |
764 } | |
765 if (only_ancestor_available) | |
766 continue; | |
767 | |
768 if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) { | |
769 InstallBindings(module_system, context->v8_context(), api_name); | |
770 } else if (!source_map_.Contains(api_name)) { | |
771 module_system->RegisterNativeHandler( | |
772 api_name, | |
773 scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler( | |
774 module_system, | |
775 api_name, | |
776 "binding"))); | |
777 module_system->SetNativeLazyField(bind_object, | |
778 split.back(), | |
779 api_name, | |
780 "binding"); | |
781 } else { | |
782 module_system->SetLazyField(bind_object, | |
783 split.back(), | |
784 api_name, | |
785 "binding"); | |
786 } | |
787 } | 740 } |
788 } | 741 } |
789 | 742 |
743 void Dispatcher::RemoveAPIBindingIfPresent(const std::string& api_name, | |
not at google - send to devlin
2013/05/31 16:35:00
Maybe DeregisterBinding as a parallel to RegisterB
cduvall
2013/06/05 03:05:56
Done.
| |
744 ChromeV8Context* context) { | |
745 std::string bind_name; | |
746 v8::Handle<v8::Object> bind_object = | |
747 GetBindObject(api_name, &bind_name, context); | |
748 if (bind_object->HasRealNamedProperty(v8::String::New(bind_name.c_str()))) { | |
749 bind_object->Delete(v8::String::New(bind_name.c_str())); | |
not at google - send to devlin
2013/05/31 16:35:00
save a reference to the v8::String::New here.
cduvall
2013/06/05 03:05:56
Done.
| |
750 } | |
not at google - send to devlin
2013/05/31 16:35:00
no {}
cduvall
2013/06/05 03:05:56
Done.
| |
751 } | |
752 | |
753 v8::Handle<v8::Object> Dispatcher::GetBindObject(const std::string& api_name, | |
754 std::string* bind_name, | |
not at google - send to devlin
2013/05/31 16:35:00
this is really GetOrCreateBindObject, though maybe
cduvall
2013/06/05 03:05:56
Done.
| |
755 ChromeV8Context* context) { | |
756 v8::HandleScope handle_scope; | |
757 std::vector<std::string> split; | |
758 base::SplitString(api_name, '.', &split); | |
759 | |
760 v8::Handle<v8::Object> bind_object = GetOrCreateChrome(context->v8_context()); | |
not at google - send to devlin
2013/05/31 16:35:00
I think you'll need to move this to after the avai
cduvall
2013/06/05 03:05:56
Done.
| |
761 | |
762 // Check if this API has an ancestor. If the API's ancestor is available and | |
763 // the API is not available, don't install the bindings for this API. If | |
764 // the API is available and its ancestor is not, delete the ancestor and | |
765 // install the bindings for the API. This is to prevent loading the ancestor | |
766 // API schema if it will not be needed. | |
767 // | |
768 // For example: | |
769 // If app is available and app.window is not, just install app. | |
770 // If app.window is available and app is not, delete app and install | |
771 // app.window on a new object so app does not have to be loaded. | |
772 std::string ancestor_name; | |
773 bool only_ancestor_available = false; | |
774 for (size_t i = 0; i < split.size() - 1; ++i) { | |
775 ancestor_name += (i ? ".": "") + split[i]; | |
776 if (!ancestor_name.empty() && | |
777 context->GetAvailability(ancestor_name).is_available() && | |
778 !context->GetAvailability(api_name).is_available()) { | |
779 only_ancestor_available = true; | |
780 break; | |
781 } | |
782 bind_object = GetOrCreateObject(bind_object, split[i]); | |
783 } | |
784 if (only_ancestor_available) | |
785 return handle_scope.Close(v8::Handle<v8::Object>()); | |
786 if (bind_name) | |
787 *bind_name = split.back(); | |
788 return handle_scope.Close(bind_object); | |
789 } | |
790 | |
791 void Dispatcher::RegisterBinding(const std::string& api_name, | |
792 ModuleSystem* module_system, | |
793 ChromeV8Context* context) { | |
794 std::string bind_name; | |
795 v8::Handle<v8::Object> bind_object = | |
796 GetBindObject(api_name, &bind_name, context); | |
797 if (bind_object.IsEmpty()) | |
798 return; | |
799 | |
800 if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) { | |
801 InstallBindings(module_system, context->v8_context(), api_name); | |
802 } else if (!source_map_.Contains(api_name)) { | |
803 module_system->RegisterNativeHandler( | |
804 api_name, | |
805 scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler( | |
806 module_system, | |
807 api_name, | |
808 "binding"))); | |
809 module_system->SetNativeLazyField(bind_object, | |
810 bind_name, | |
811 api_name, | |
812 "binding"); | |
813 } else { | |
814 module_system->SetLazyField(bind_object, | |
815 bind_name, | |
816 api_name, | |
817 "binding"); | |
818 } | |
819 } | |
820 | |
790 void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, | 821 void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, |
791 ChromeV8Context* context) { | 822 ChromeV8Context* context) { |
792 v8::Handle<v8::Context> v8_context = context->v8_context(); | 823 v8::Handle<v8::Context> v8_context = context->v8_context(); |
793 | 824 |
794 module_system->RegisterNativeHandler("event_bindings", | 825 module_system->RegisterNativeHandler("event_bindings", |
795 scoped_ptr<NativeHandler>(EventBindings::Create(this, v8_context))); | 826 scoped_ptr<NativeHandler>(EventBindings::Create(this, v8_context))); |
796 module_system->RegisterNativeHandler("miscellaneous_bindings", | 827 module_system->RegisterNativeHandler("miscellaneous_bindings", |
797 scoped_ptr<NativeHandler>(MiscellaneousBindings::Get(this, v8_context))); | 828 scoped_ptr<NativeHandler>(MiscellaneousBindings::Get(this, v8_context))); |
798 module_system->RegisterNativeHandler("apiDefinitions", | 829 module_system->RegisterNativeHandler("apiDefinitions", |
799 scoped_ptr<NativeHandler>(new ApiDefinitionsNatives(this, context))); | 830 scoped_ptr<NativeHandler>(new ApiDefinitionsNatives(this, context))); |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1246 WebSecurityPolicy::addOriginAccessWhitelistEntry)( | 1277 WebSecurityPolicy::addOriginAccessWhitelistEntry)( |
1247 extension->url(), | 1278 extension->url(), |
1248 WebString::fromUTF8(schemes[j]), | 1279 WebString::fromUTF8(schemes[j]), |
1249 WebString::fromUTF8(i->host()), | 1280 WebString::fromUTF8(i->host()), |
1250 i->match_subdomains()); | 1281 i->match_subdomains()); |
1251 } | 1282 } |
1252 } | 1283 } |
1253 } | 1284 } |
1254 } | 1285 } |
1255 | 1286 |
1287 void Dispatcher::RefreshSchemaGeneratedBindings() { | |
1288 v8::HandleScope handle_scope; | |
1289 CHECK(v8_context_set().size()); | |
1290 // TODO(cduvall): This is wrong. Not sure what to do. | |
cduvall
2013/05/31 03:06:34
I'm not sure how to get the right context to regis
not at google - send to devlin
2013/05/31 16:35:00
Ah right, yeah. So what you want is this:
https:/
cduvall
2013/06/05 03:05:56
So I added in the v8_context_set_.ForEach(), but I
not at google - send to devlin
2013/06/05 19:03:44
It may be the lack of an is_valid check in ChromeV
cduvall
2013/06/05 23:27:59
Looks like the is_valid() check didn't fix the pro
| |
1291 ChromeV8Context* context = *v8_context_set().GetAll().begin(); | |
1292 context->v8_context()->Enter(); | |
1293 RegisterSchemaGeneratedBindings(context->module_system(), context); | |
1294 context->v8_context()->Exit(); | |
not at google - send to devlin
2013/05/31 16:35:00
use v8::Context::Scope here, and move into Registe
cduvall
2013/06/05 03:05:56
Done.
| |
1295 } | |
1296 | |
1256 void Dispatcher::OnUpdatePermissions(int reason_id, | 1297 void Dispatcher::OnUpdatePermissions(int reason_id, |
1257 const std::string& extension_id, | 1298 const std::string& extension_id, |
1258 const APIPermissionSet& apis, | 1299 const APIPermissionSet& apis, |
1259 const URLPatternSet& explicit_hosts, | 1300 const URLPatternSet& explicit_hosts, |
1260 const URLPatternSet& scriptable_hosts) { | 1301 const URLPatternSet& scriptable_hosts) { |
1261 const Extension* extension = extensions_.GetByID(extension_id); | 1302 const Extension* extension = extensions_.GetByID(extension_id); |
1262 if (!extension) | 1303 if (!extension) |
1263 return; | 1304 return; |
1264 | 1305 |
1265 scoped_refptr<const PermissionSet> delta = | 1306 scoped_refptr<const PermissionSet> delta = |
1266 new PermissionSet(apis, explicit_hosts, scriptable_hosts); | 1307 new PermissionSet(apis, explicit_hosts, scriptable_hosts); |
1267 scoped_refptr<const PermissionSet> old_active = | 1308 scoped_refptr<const PermissionSet> old_active = |
1268 extension->GetActivePermissions(); | 1309 extension->GetActivePermissions(); |
1269 UpdatedExtensionPermissionsInfo::Reason reason = | 1310 UpdatedExtensionPermissionsInfo::Reason reason = |
1270 static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id); | 1311 static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id); |
1271 | 1312 |
1272 const PermissionSet* new_active = NULL; | 1313 const PermissionSet* new_active = NULL; |
1273 switch (reason) { | 1314 switch (reason) { |
1274 case UpdatedExtensionPermissionsInfo::ADDED: | 1315 case UpdatedExtensionPermissionsInfo::ADDED: |
1275 new_active = PermissionSet::CreateUnion(old_active, delta); | 1316 new_active = PermissionSet::CreateUnion(old_active, delta); |
1276 break; | 1317 break; |
1277 case UpdatedExtensionPermissionsInfo::REMOVED: | 1318 case UpdatedExtensionPermissionsInfo::REMOVED: |
1278 new_active = PermissionSet::CreateDifference(old_active, delta); | 1319 new_active = PermissionSet::CreateDifference(old_active, delta); |
1279 break; | 1320 break; |
1280 } | 1321 } |
1281 | 1322 |
1282 PermissionsData::SetActivePermissions(extension, new_active); | 1323 PermissionsData::SetActivePermissions(extension, new_active); |
1283 AddOrRemoveOriginPermissions(reason, extension, explicit_hosts); | 1324 AddOrRemoveOriginPermissions(reason, extension, explicit_hosts); |
1325 RefreshSchemaGeneratedBindings(); | |
1284 } | 1326 } |
1285 | 1327 |
1286 void Dispatcher::OnUpdateTabSpecificPermissions( | 1328 void Dispatcher::OnUpdateTabSpecificPermissions( |
1287 int page_id, | 1329 int page_id, |
1288 int tab_id, | 1330 int tab_id, |
1289 const std::string& extension_id, | 1331 const std::string& extension_id, |
1290 const URLPatternSet& origin_set) { | 1332 const URLPatternSet& origin_set) { |
1291 RenderView* view = TabFinder::Find(tab_id); | 1333 RenderView* view = TabFinder::Find(tab_id); |
1292 | 1334 |
1293 // For now, the message should only be sent to the render view that contains | 1335 // For now, the message should only be sent to the render view that contains |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1458 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | 1500 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); |
1459 v8::ThrowException( | 1501 v8::ThrowException( |
1460 v8::Exception::Error(v8::String::New(error_msg.c_str()))); | 1502 v8::Exception::Error(v8::String::New(error_msg.c_str()))); |
1461 return false; | 1503 return false; |
1462 } | 1504 } |
1463 | 1505 |
1464 return true; | 1506 return true; |
1465 } | 1507 } |
1466 | 1508 |
1467 } // namespace extensions | 1509 } // namespace extensions |
OLD | NEW |