Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: chrome/renderer/extensions/dispatcher.cc

Issue 15961006: Regenerate Extensions API bindings when optional permissions change (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/extensions/dispatcher.cc
diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc
index a1fd9c5d3ef5f6f757ece3a37bf72c679fb7da49..bf6560f8da027476e862aa9a36cb729fbbcd32b2 100644
--- a/chrome/renderer/extensions/dispatcher.cc
+++ b/chrome/renderer/extensions/dispatcher.cc
@@ -726,64 +726,95 @@ void Dispatcher::RegisterSchemaGeneratedBindings(
for (std::set<std::string>::iterator it = apis.begin();
it != apis.end(); ++it) {
const std::string& api_name = *it;
- if (!context->IsAnyFeatureAvailableToContext(api_name))
+ if (!context->IsAnyFeatureAvailableToContext(api_name)) {
+ RemoveAPIBindingIfPresent(api_name, context);
continue;
+ }
Feature* feature =
BaseFeatureProvider::GetByName("api")->GetFeature(api_name);
if (feature && feature->IsInternal())
continue;
- std::vector<std::string> split;
- base::SplitString(api_name, '.', &split);
-
- v8::Handle<v8::Object> bind_object =
- GetOrCreateChrome(context->v8_context());
-
- // Check if this API has an ancestor. If the API's ancestor is available and
- // the API is not available, don't install the bindings for this API. If
- // the API is available and its ancestor is not, delete the ancestor and
- // install the bindings for the API. This is to prevent loading the ancestor
- // API schema if it will not be needed.
- //
- // For example:
- // If app is available and app.window is not, just install app.
- // If app.window is available and app is not, delete app and install
- // app.window on a new object so app does not have to be loaded.
- std::string ancestor_name;
- bool only_ancestor_available = false;
- for (size_t i = 0; i < split.size() - 1; ++i) {
- ancestor_name += (i ? ".": "") + split[i];
- if (!ancestor_name.empty() &&
- context->GetAvailability(ancestor_name).is_available() &&
- !context->GetAvailability(api_name).is_available()) {
- only_ancestor_available = true;
- break;
- }
- bind_object = GetOrCreateObject(bind_object, split[i]);
- }
- if (only_ancestor_available)
- continue;
+ RegisterBinding(api_name, module_system, context);
+ }
+}
- if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) {
- InstallBindings(module_system, context->v8_context(), api_name);
- } else if (!source_map_.Contains(api_name)) {
- module_system->RegisterNativeHandler(
- api_name,
- scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler(
- module_system,
- api_name,
- "binding")));
- module_system->SetNativeLazyField(bind_object,
- split.back(),
- api_name,
- "binding");
- } else {
- module_system->SetLazyField(bind_object,
- split.back(),
- api_name,
- "binding");
+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.
+ ChromeV8Context* context) {
+ std::string bind_name;
+ v8::Handle<v8::Object> bind_object =
+ GetBindObject(api_name, &bind_name, context);
+ if (bind_object->HasRealNamedProperty(v8::String::New(bind_name.c_str()))) {
+ 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.
+ }
not at google - send to devlin 2013/05/31 16:35:00 no {}
cduvall 2013/06/05 03:05:56 Done.
+}
+
+v8::Handle<v8::Object> Dispatcher::GetBindObject(const std::string& api_name,
+ 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.
+ ChromeV8Context* context) {
+ v8::HandleScope handle_scope;
+ std::vector<std::string> split;
+ base::SplitString(api_name, '.', &split);
+
+ 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.
+
+ // Check if this API has an ancestor. If the API's ancestor is available and
+ // the API is not available, don't install the bindings for this API. If
+ // the API is available and its ancestor is not, delete the ancestor and
+ // install the bindings for the API. This is to prevent loading the ancestor
+ // API schema if it will not be needed.
+ //
+ // For example:
+ // If app is available and app.window is not, just install app.
+ // If app.window is available and app is not, delete app and install
+ // app.window on a new object so app does not have to be loaded.
+ std::string ancestor_name;
+ bool only_ancestor_available = false;
+ for (size_t i = 0; i < split.size() - 1; ++i) {
+ ancestor_name += (i ? ".": "") + split[i];
+ if (!ancestor_name.empty() &&
+ context->GetAvailability(ancestor_name).is_available() &&
+ !context->GetAvailability(api_name).is_available()) {
+ only_ancestor_available = true;
+ break;
}
+ bind_object = GetOrCreateObject(bind_object, split[i]);
+ }
+ if (only_ancestor_available)
+ return handle_scope.Close(v8::Handle<v8::Object>());
+ if (bind_name)
+ *bind_name = split.back();
+ return handle_scope.Close(bind_object);
+}
+
+void Dispatcher::RegisterBinding(const std::string& api_name,
+ ModuleSystem* module_system,
+ ChromeV8Context* context) {
+ std::string bind_name;
+ v8::Handle<v8::Object> bind_object =
+ GetBindObject(api_name, &bind_name, context);
+ if (bind_object.IsEmpty())
+ return;
+
+ if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) {
+ InstallBindings(module_system, context->v8_context(), api_name);
+ } else if (!source_map_.Contains(api_name)) {
+ module_system->RegisterNativeHandler(
+ api_name,
+ scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler(
+ module_system,
+ api_name,
+ "binding")));
+ module_system->SetNativeLazyField(bind_object,
+ bind_name,
+ api_name,
+ "binding");
+ } else {
+ module_system->SetLazyField(bind_object,
+ bind_name,
+ api_name,
+ "binding");
}
}
@@ -1253,6 +1284,16 @@ void Dispatcher::AddOrRemoveOriginPermissions(
}
}
+void Dispatcher::RefreshSchemaGeneratedBindings() {
+ v8::HandleScope handle_scope;
+ CHECK(v8_context_set().size());
+ // 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
+ ChromeV8Context* context = *v8_context_set().GetAll().begin();
+ context->v8_context()->Enter();
+ RegisterSchemaGeneratedBindings(context->module_system(), context);
+ 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.
+}
+
void Dispatcher::OnUpdatePermissions(int reason_id,
const std::string& extension_id,
const APIPermissionSet& apis,
@@ -1281,6 +1322,7 @@ void Dispatcher::OnUpdatePermissions(int reason_id,
PermissionsData::SetActivePermissions(extension, new_active);
AddOrRemoveOriginPermissions(reason, extension, explicit_hosts);
+ RefreshSchemaGeneratedBindings();
}
void Dispatcher::OnUpdateTabSpecificPermissions(
« no previous file with comments | « chrome/renderer/extensions/dispatcher.h ('k') | chrome/test/data/extensions/api_test/permissions/optional/background.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698