El lun, 15-12-2014 a las 13:24 +0100, Marcos Chavarría Teijeiro escribió: > Hi, > > I'm working on implementing a new API for block and unblock plugins > [1]. I want to discuss here how we should implement it. > > The current API WebKitPlugin suggests to add new methods get_enabled > and set_enabled but by implementing this methods we could not specify > the unavailabilityDescription and populate the unavailable plugin > button with this information. In addition we don't leave almost any > control to the app, implementing unblock certain plugins for certain > domains could be more difficult using this way for example. > > I have been talking with Carlos García and we believe that we should > implement a PluginLoadPermissionRequest so we can use > "permission-request" signal to block/unblock plugin load. The > information about if a plugin is blocked or not would be stored in the > app.
Well, that's just a possibility, but I'm not sure permission request would work for this particular case for several reasons. First, let's see how WebKit2 works internally, what we want to achieve, and how we could do that. When plugins are not disabled, they are always scanned on demand to keep a list of plugins in the UI process. Fortunately that's no longer a problem with the plugins cache. Every plugin scanned to get its metadata can be filtered out by PluginInfoStore::shouldUsePlugin(). This doesn't have any API client, so it's to disable plugins internally, for example, if a particular version of a plugin is known to be insecure. In this cases the plugins are not added to the list of plugins. When the WebProcess needs to create a plugin, it sends a message to the UI process (FindPlugin) that returns False if the plugin was not found (this includes the plugins disabled since they are not included in the list) or True if the plugin was found. When a plugin is found, API::LoaderClient::pluginLoadPolicy() is called, so that the API layer can decide whether to block the plugin or not, and provide additional information like the reason why the plugin is blocked. This is called everytime a page is loaded and for every plugin that is created. The internal load policy values are currently PluginModuleLoadNormally, PluginModuleLoadUnsandboxed or PluginModuleBlocked. When the API layer blocks a plugin, the plugin process is not spawned and the web process renders a button with the text returned by the API layer with the reasons for blocking the plugin. However, this button might be obscured in the page or not present for plugins without UI for example. When a plugin is blocked, the web process sends a message to the UI process (DidBlockInsecurePluginVersion) to notify that the plugin has been blocked (the UI process already knows that) including whether the plugin button is obscured or not. The WebKit layer is notified about this using API::LoaderClient::didBlockInsecurePluginVersion(). Finally when the user clicks on a blocked plugin button, the API::UIClient::unavailablePluginButtonClicked() is called so that the WebKit layer can react to that. Note also that canShowMIMEType also uses findPlugin, but it doesn't check the load policy, so it will return false for plugins disabled by PluginInfoStore::shouldUsePlugin(), but true for plugins blocked by pluginLoadPolicy(), since those could actually be shown if unblocked by the user. So, there are 3 points to expose in the API, loadPolicy, didBlockPlugin and unavailablePluginButtonClicked. We could use the current permission request API for the loadPolicy as Marcos said, but it's probably too limited for this particular case. The permission request API only allows for allow/deny results, but even if we currently don't PluginModuleLoadUnsandboxed policy, we might support that eventually, or new policies might be added. Also, we need a way to provide additional information, like the blocked reason, but permission-request signal only expects allow/deny from the user. And even more important, prmission-request allows to handle requests asynchronously, but FindPlugin message is synchronous, so we can't handle this asynchronously. So, for the load plugin policy I propose to use a dedicated signal that returns the policy as an enum. WebKitPluginLoadPolicy (* load_plugin) (WebKitWebView *web_view, WebKitPluginLoadRequest *request); WebKitPluginLoadPolicy would have WEBKIT_PLUGIN_LOAD_NORMALLY and WEBKIT_PLUGIN_LOAD_BLOCK for now. The default implementation returns WEBKIT_PLUGIN_LOAD_NORMALLY. WebKitPluginLoadRequest would be a boxed type, alive during the signal emission, since this can't be handled asynchronously. This way we could provide additional information in the future without breaking the API, for now it could have this API: WebKitPlugin *webkit_plugin_load_request_get_plugin (WebKitPluginLoadRequest *request); const char *webkit_plugin_load_request_get_page_uri (WebKitPluginLoadRequest *request); void webkit_plugin_load_request_set_description (WebKitPluginLoadRequest *request, const char *description); For didBlockPlugin we could use a similar signal, for just informative ins this case. void (* plugin_blocked) (WebKitWebView *web_view, WebKitPlugin *plugin, gboolean is_visible_in_page); The application could check if after load completes there are blocked plugins, but none of them visible, and use a popup to ask the user, or add a button to the URL bar, or whatever considering that plugin blocked buttons will not be available. And finally a signal emitted when the plugin blocked button is clicked. void (* plugin_unavailability_button_clicked) (WebKitWebView *web_view, WebKitPluginUnavailabilityInformation *info); I'm using unavailability here instead of blocked, because this is also used for plugins that are missing, this can happen for example if the plugin is uninstalled after the plugin list has been populated. WebKitPluginUnavailabilityInformation would be a boxed type with an API like this one. WebKitPluginUnavailabilityReason webkit_plugin_unavailability_information_get_reason (WebKitPluginUnavailabilityInformation *info); WebKitPlugin *webkit_plugin_unavailability_information_get_plugin (WebKitPluginUnavailabilityInformation *info); const char *webkit_plugin_unavailability_information_get_page_uri (WebKitPluginUnavailabilityInformation *info); Reason would be MISSING or BLOCKED for now. Then the application could enable the plugin internally and reload the page so that when load-plugin signal is emitted again it will return LOAD_NORMALLY for that plugin. I think this API provides all the flexibility that the internal or C API allows. There are a few things I'm not completely sure about: - WebKitPluginLoadRequest: do we really need the get_page_uri? wouldn't that be always the current web view uri? I've added the method because that information is provided by the loader client callback, but we need to make sure it's actually needed. For a first version we could avoid that method, and add it later if it's actually useful. But without method, the request is a very simple object, so maybe we could pass the WebKitPlugin directly to the signal and pass an out parameter for the button description. That would make everything simpler, but we won't be able to add more info to the signal without breaking the API. - plugin-blocked: In this case I did the opposite, passing the information as signal arguments. Currently wk passes the frame URL, page URL, plugin mime type and whether the plugin is obscured. We might use a boxed type here too, for example to also provide the page uri and the plugin mime type if needed/useful. - plugin-unavailability-button-clicked: the signal name and the boxed type used to provide the information are too long, we could think about better names. Again I'm not sure about the needed to provide the page uri. Also internally, wk passes the plugin page attribute (I guess this is the page where the plugin can be downloaded in case of missing plugins). > In addition, we should also add a new signal > "unavailable-plugin-button-clicked" to WebView so when this button is > clicked we could unblock this plugin and reload the webpage. > > Best Regards, > Marcos Chavarría Teijeiro. > > [1] https://bugs.webkit.org/show_bug.cgi?id=134357 > _______________________________________________ > webkit-gtk mailing list > [email protected] > https://lists.webkit.org/mailman/listinfo/webkit-gtk -- Carlos Garcia Campos http://pgp.rediris.es:11371/pks/lookup?op=get&search=0xF3D322D0EC4582C3
signature.asc
Description: This is a digitally signed message part
_______________________________________________ webkit-gtk mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-gtk
