Open Bug 1626003 Opened 4 years ago Updated 1 year ago

Implement a way to turn on and off WebExtension APIs depending on support

Categories

(GeckoView :: Extensions, enhancement, P3)

Unspecified
All
enhancement

Tracking

(Not tracked)

People

(Reporter: agi, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [geckoview:m78])

One thing that's gonna more important as we add more and more support for APIs in GeckoView is to make sure that the APIs are available to extensions only if the app actually supports them (e.g. we could tie it to the relevant delegate being attached).

So what this bug entails is

  1. add a way in Gecko to add support for an API at runtime (this might already exist)
  2. tie the above API to attaching/detaching delegates in the API, hopefully we can make this code fairly generic to avoid duplication

This will probably turn into a metabug.

:rpl, :robwu, any pointers/concerns/comments in regards to 1 are much appreciated :)

Flags: needinfo?(rob)
Flags: needinfo?(lgreco)

What are the requirements?

  1. Is this something that should apply to a feature in its entirely (for all extensions), or only to specific extensions?
  2. Is this something that should be toggle-able at runtime? When?
  3. What is the granularity? Full API namespaces or specific methods?
  4. In terms of thoroughness:
    1. Prevent extensions from using APIs (e.g. namespace/function exists but throws upon calling).
    2. Prevent extensions from seeing APIs (e.g. namespace/function is hidden).
    3. Minimizing the performance impact (memory usage) of APIs (i.e. API not available to extensions, implementation not registered at all).

We already have something set up to dynamically enable and disable APIs (specific methods or full namespaces) depending on whether extension has a specific permission or not. This is highly flexible (scores positive on points 1-3), but is less optimal than a compile-time (or even "first run"-time) disable.

Flags: needinfo?(rob)
Whiteboard: [geckoview:m77]

(In reply to :Agi | ⏰ PST | he/him from comment #0)

One thing that's gonna more important as we add more and more support for APIs in GeckoView is to make sure that the APIs are available to extensions only if the app actually supports them (e.g. we could tie it to the relevant delegate being attached).

So what this bug entails is

  1. add a way in Gecko to add support for an API at runtime (this might already exist)

This sounds pretty similar to what we support for WebExtension APIs locked behind optional permissions, and making more APIs to be allowed to be requested as optional is something that we are doing (and we would like to keep doing for more of them) in Firefox desktop too (and so it would be a shared need / goal).

Given that on GeckoView the optional permissions requests (as well as revoking them) would have to be delegated to the embedder app, if we could leverage that then:

  • the embedder app would have the choice to deny the permission (and related API) requested by the extension at runtime without consulting the user if it needs/wants to (e.g. because the app did "configure" GeckoView to never allow a certain optional_permission for an API that doesn't want to support at all)
  • the extension would already expecting that the permission (and API) requested may be denied (and would be more likely prepared to handle that case gracefully)

how that sounds to you?

is there any of the APIs already defined at toolkit level or android level that you think would also need to allow this on GeckoView?
or is something you feel it may be only needed for new APIs not yet defined (or new Android / Geckoview specific APIs)?

(I want to be sure that we got a good picture of the use case you have in mind, and the reasoning behind it).

Flags: needinfo?(lgreco)
Priority: -- → P1

idk if we'd want to use permissions here, that feels like overloading what the addon wants with what the app supports. An "app manifest", if such a thing exists, might be a better/clearer solution. That would, as suggested, prevent registration of the api namespace in the first place.

Then there is probably some minimal/core set of API namespaces that should be required to be supported by all gv apps, such as runtime and extension.

In addition to that, it would probably be prudent to require the addon to express supported gv apps in the addon manifest, along with versioning. This way an app can have some assurance that any given addon should work correctly when loaded (and not break in any surprising way).

This is how GeckoView works right now, when features need action from the app (e.g. "open a new tab") apps can optionally set a delegate to respond to the specific action. This delegates can be set at any time, but what we really care about (performance-wise at least) is the case where an app sets the delegate sometimes shortly after startup.

For extensions specifically we can take the TabDelegate delegate, what I would like to have is this:

  • Until the app hasn't registered a TabDelegate, there will be no tabs support at all, the tabs object will be undefined (or whatever feasible).
  • When the app registers the TabDelegate we enable tabs to be available
  • If the app unregisters the TabDelegate, tabs would become undefined again, this is however not that important

This can be done for entire modules (tabs rather than tabs.create). I don't think we need anything super granular. It would only apply to APIs that need an app component, all others would be enabled as usual.

My understanding is that we already do something like that (as you mentioned) when the extension doesn't have permission, so I'm not clear on why it would cause worse performance? Could anyone expand on that?

An "app manifest", if such a thing exists, might be a better/clearer solution. That would, as suggested, prevent registration of the api namespace in the first place.

I would like to avoid the app doing anything more than registering the delegate to enable a feature, if at all possible.

In addition to that, it would probably be prudent to require the addon to express supported gv apps in the addon manifest, along with versioning. This way an app can have some assurance that any given addon should work correctly when loaded (and not break in any surprising way).

For this we can just tie the Fenix version to the Gecko version, I don't think we need anything fancier than that. When third party browsers start caring about that stuff we can think about it.

Until the app hasn't registered a TabDelegate, there will be no tabs support at all, the tabs object will be undefined (or whatever feasible).

This changes a basic premise of how extensions work. I'm not saying we shouldn't go down this road, but we should be very careful and deliberate about this if we decide it is the only way forward.

Right now extensions have some level of guarantee for APIs (assuming they are supported by any given implementation):

  • it is a default (non-permission) API, so it is always there
  • it is a API that requires a permission
    • they use required permissions, so it is always there
    • they use an optional permission (if the api supports that), they can request/revoke and have notifications for addition/removal. If they've been granted permission, on restart the api is always there. The extension should re-check on startup so it doesn't try to do something it cannot, the user may have removed the permission (e.g. in safe mode, though we currently do not have UI for optional permissions).

The above of course depends on the API being supported.

Having an app add/remove APIs doesn't really work for default APIs.

Ideally an app would express what they support on startup and those APIs would be available by default to the extension. Addon startup could wait until app information is available. Removing (default) API support at runtime adds a burden to the add-on developer to write in a way that any given API may disappear. We need to provide some level of guarantee to the extension that it will be able to operate.

We do have a bug to move more permissions to optional permissions, for APIs covered by those, there is a way to request/grant, but that still does not necessarily cover the startup issue.

Yeah I agree we shouldn't put this on the shoulders of add-on developers, and I don't think we would want to move to a world where an API can disappear at any moment either.

I discussed it with :snorp a little on slack and it seems that we should be able to let embedders give us the list of supported APIs at init time (when the Gecko process is started, essentially) so that the Addon infrastructure can set the right flags correctly.

Whiteboard: [geckoview:m77] → [geckoview:m78]
Priority: P1 → P2
Rank: 1
Priority: P2 → P1
Whiteboard: [geckoview:m78] → [geckoview:m78][geckoview:m79]
Whiteboard: [geckoview:m78][geckoview:m79] → [geckoview:m78][geckoview:m80]
Priority: P1 → P2
Whiteboard: [geckoview:m78][geckoview:m80] → [geckoview:m78]

Still relevant, either for H2 or later

Priority: P2 → P3
Severity: normal → S3
Rank: 1 → 333

Tasks and enhancements should have severity N/A.

Severity: S3 → N/A
You need to log in before you can comment on or make changes to this bug.