Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gate background fetch on user activation #143

Open
youennf opened this issue Apr 15, 2020 · 8 comments
Open

Gate background fetch on user activation #143

youennf opened this issue Apr 15, 2020 · 8 comments

Comments

@youennf
Copy link

youennf commented Apr 15, 2020

https://wicg.github.io/background-fetch/#background-fetch-manager-fetch is executing a 'display ' step which might trigger prompting the user. User activation is generally a requirement in those flows. This would also mirror well the desired behavior for downloads.
This would also for instance resolve the case of a backgrounded page trying to start a background fetch.

@jakearchibald
Copy link
Collaborator

https://auto-large-download-test.glitch.me - this site starts a download without user interaction. In Safari this shows a permission dialog, which is the pattern I was trying to enable in the bgfetch spec.

Although calling backgroundFetch.fetch() triggers display, the background fetch may begin in the paused state, and the display may effectively be a permission prompt, requiring user interaction to start the download.

I did this, rather than use an actual permission prompt, so the download could be 'accepted' even after the user has navigated away from the site.

This would also for instance resolve the case of a backgrounded page trying to start a background fetch.

I was hoping to enable this. Eg, a podcast app could start a download in response to a push message. Again, the download could start in a paused state, requiring user interaction to unpause.

The UA could offer options like "always let this site perform background downloads", and "never let this site perform background downloads". The spec allows UAs to unpause/reject background fetches on behalf of the user. It also allows UAs to pause downloads if a situation changes that means the download should wait, or require extra confirmation (eg, the user moves onto a metered connection).

If the above is acceptable, I'm happy to try and make it clearer in the spec.

@youennf
Copy link
Author

youennf commented Apr 16, 2020

Whenever there is UI being shown to the user, it is best to tie it to a context that makes sense to the user.
If a service worker is triggering a prompt, it is for instance difficult to know where and when to show the prompt, contrary to the following flow :

  • The web page wants to start a bg fetch and calls the bg fetch API
  • User Agent shows a prompt on top of the page (like done for getUserMedia, geolocation...)
  • User makes an informed decision based on the prompt and the page.

I was hoping to enable this. Eg, a podcast app could start a download in response to a push message. Again, the download could start in a paused state, requiring user interaction to unpause.

I would guess something like the following could be done:

  • Push message triggers opening a web page
  • Web page provides a button to start the download
  • On user click, web page calls bg fetch API

It seems you are trying to offer more, in particular in the case where user really trusts the web page and has changed some settings so that the web page is allowed to download in the background.
Do we actually need bg fetch to be exposed to service workers?

@jakearchibald
Copy link
Collaborator

It seems you are trying to offer more, in particular in the case where user really trusts the web page and has changed some settings so that the web page is allowed to download in the background.

That, but also the ability to accept the download without having to spin up a page or service worker.

Chrome currently puts download requests in the downloads tray on desktop, and as a notification on mobile. Neither are attached to a page. Safari does a mix:

Screenshot 2020-04-28 at 13 47 17

The permission is part of the page, but the download has started in a paused state.

I guess we could add something to the spec to say the browser can reject the fetch if there's no meaningful place to ask the user.

@youennf
Copy link
Author

youennf commented Apr 28, 2020

The permission is part of the page, but the download has started in a paused state.

Not really, the download has not started at all.
If you do not answer to the download, it will be in a failed state. User might still be able to restart it but this seems like a poor API at this point.

In general, meaningfully prompting the user from a background process is hard. That is the tricky part of supporting bgfetch in service workers. The path seems much clearer on windows.

@jakearchibald
Copy link
Collaborator

Not really, the download has not started at all.

Right, I mean there's UI for it in the downloads section of the browser. This is what I mean by "started in a paused state" - the bgfetch spec uses this in the same way. The download hasn't actually started, but from a UI perspective it can look like it's in a paused state.

In general, meaningfully prompting the user from a background process is hard. That is the tricky part of supporting bgfetch in service workers.

On mobile it doesn't seem too bad, no? You'd get a notification like "podcast.example.com wants to start a download block / allow".

@youennf
Copy link
Author

youennf commented Apr 29, 2020

If we leave the case of service worker calling bgfetch and concentrate on the window case, is there consensus to put a user activation requirement there?

@jakearchibald
Copy link
Collaborator

I don't see why we'd make that a requirement, given that regular downloads don't have that requirement and they're more powerful, since they write straight to a user directory, and don't have CORS restrictions.

@youennf
Copy link
Author

youennf commented Apr 29, 2020

For downloads, this requirement is probably not web compatible anymore.
If we had to redesign regular downloads, making it a requirement would be on the table.

An example is getUserMedia vs. getDisplayMedia: the former has no such requirement (it shipped quite some time ago, and this is hard to enforce user activation) but the latter has that requirement.

Let's look again at the 'start-a-download-in-a-background-page' scenario:

  • I start a tab A
  • I switch to another tab B
  • tab A in the background is starting a download so there is a probably prompt in that tab A.
  • But I am in tab B so I do not see the prompt.
  • Now I can see there is an entry in the download UI, but I cannot unpause it. So I need to find tab A.
  • Tab A is hidden in my 100 other tabs. Sigh, I decide to cancel this download from the download UI. I open a new tab C with the same URL as tab A and wait for the download prompt to happen this time. Great, my download starts. I can then happily close tab C.
  • By chance, a few minutes later, I am back to tab A and I see there is a download prompt. Oh wait, is it the one I cancelled or is it a new one? I don't know so let's accept it, the download is super important to me. Oh wait, nothing happens, that was my cancelled download.

These issues can probably be solved but they are nonetheless difficult to handle properly.
Enforcing a user activation requirement makes things simpler for users and implementors, without reducing much what web developers can do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants