I wanted to build a table-top score keeper, using the web and my phone. I couldn’t find a way to disable the auto-dimming feature on the phone. So my phone would log me out constantly.
I’d like web apps for mobile devices to request the user allow the app to disable auto-dimming. This is also known as Wake Lock.
The hard part here is to figure out how to make it work without it being abused and without an annoying user experience.
We can’t have the browser prompt users to ask if the app should be allowed to effect wake lock. Most users won’t even understand what that means. But we’d also like to avoid cases in which a web page can drive your device out of battery on its own.
I would argue the following: apps can already enable wake lock without user permission (or a permission buried in an install screen no one ever reads), and so far they do so without killing battery performance. One can presume that what is at the front of the user’s screen is something the user is paying attention to, and that will get turned off if needed.
Therefore, it can be supported without permission request. Obviously it would only kick in if the browser is the active app and if it is requested by the active tab.
Does it need an API or can it be a simple declarative request? Declarative is easiest (we could have a meta for it and/or a manifest field) but I’m guessing there’s a use case for apps to turn this on/off? In that case, there could be an API modelled off fullscreen.
No reason this wouldn’t be useful on a desktop as well.
Based on the bug you filed in Chromium (which I would link to if I had enough karma), @anssik recently restarted the discussion in bringing this as a new work item, possibly in the Device APIs Working Group.
I certainly support this, this seems to be fairly low hanging fruit.
The problem with a declarative approach is that you want to ability to remove the wake lock as well, e.g. once a video has finished playing.
I was thinking idly whether we could in fact make it so that this API needs to be invoked repeatedly (typically from an event handler) — each invocation would be made the equivalent of a user interaction (which normally stops the screen dim).
That way, you don’t need to remove the wake lock, you just need to stop asking for it.
For instance, assuming a navigator.poke() method:
// keep the screen from dimming while the video plays
document.querySelector("video").ontimeupdate = navigator.poke;
// in a game using the device orientation as the controler
window.addEventListener("deviceorientation", function (e) {
navigator.poke();
// refresh game
});
// in an animation that we're building "manually"
var animate = function () {
navigator.poke();
// stuff
requestAnimationFrame(animate);
}
I like Dom’s poke() proposal. It feels natural. That’s how users manually keep the screen lit: they touch the screen or nudge the mouse. I’d guess this maps to the underlying implementations nicely as well: invoking the method will reset the countdown timer to dim the screen similarly to user action.
On the blink-dev I mentioned we should draft a design document to capture the ideas. If we’d move fast, we could have that discussion in a W3C group even.
[It seems I’m hitting the two links for new users restriction, so leaving out the link to the blink-dev discussion.]
Great! Let me know how things go with the charter discussion. Otherwise, as a natural extension to the Navigator object I think it makes sense in the HTML WG.
Either way I reckon work can start on an unofficial draft. I can open a repo under the w3c GitHub umbrella if you want.
PS: I’ve upped your user karma so you can use more links
HTML WG would be another good home for the feature. In that case, I’d expect we’d model this as an extension spec, propose it to be published under the W3C Document License + CC-BY, and integrate later.
Regardless of which WG takes this, I think it would be helpful to create a repo for the feature under github.com/w3c. We could use the repo for documenting the use cases and proposals to start with. I trust your judgement in naming the repo to save us some bikeshed color
The problem with a declarative approach is that you want to ability to
remove the wake lock as well, e.g. once a video has finished playing.
Just a note, video elements should handle this automatically - particularly if the video is put into fullscreen. No need for anything to be done here.
so document.querySelector("video").ontimeupdate = navigator.poke; is not really needed.
The idea of poke() doesn’t feel natural to me. It seems like a hack to have to put it in places like requestAnimationFrame or other looping events are used. It would be better, IMHO, to just request it per page. This seems to be how Chrome and FxOS does it.
Yeah, I tend to agree that videos should probably trigger that behavior by default, esp. in fullscreen.
I personally don’t feel very strongly about this, although I think the model where you don’t have to release the lock is a bit simpler to manage for developers in an asynchronous context.
As discussed on IRC, having a markup based approach (e.g. for the traditional cooking recipe use case) in addition would probably be nice.
And here is a rough draft of a spec matching navigator.poke. As said previously, I don’t mind if the more classical requestWakeLock approach is preferred; I just thought it made sense to document what’s been discussed so far.
If you go for the poke() approach, how can a website be certain that it “pokes” often enough? Will it be able to check what the user-set timeout is, or how far the countdown has progressed?
While we’re at this pre-standards exploration phase, discussion can happen where people who’d like to contribute are. So let’s continue the discussion here on Discourse if this works for you (if/when we’ll move to the so called standards track we should move the discussion to an appropriate standards mailing list).
Use cases and more complete proposals should go to the GitHub:
I’m happy to see Dom and Marcos already put proposals in the GH and bootstrapped a list of use cases. As you can see, the form of the proposals does not matter at this point. You can use Markdown as Marcos did with his proposal, or if you feel more adventurous you can format your proposal as an Unofficial Draft as Dom did.
As long as the element or parts of the element are in the viewport, this would serve as a hint to the user agent to keep the screen on:
<!DOCTYPE html>
<html>
<head>
<title>Cookbook</title>
</head>
<body>
<div>
Blah blah.
</div>
<h1>
Bacon and eggs recipe
</h1>
<ul keepvisible>
<li>Bacon</li>
<li>Eggs</li>
</ul>
<img src="">
<p keepvisible>
Instructions to make ...
</p>
<div>
Footer and other boilerplate
</div>
</body>
</html>
When the user navigates away from the page, or scrolls the page so that no elements with the “keepvisible” attribute set are within the visible viewport, the implementation would start its implementation-dependent countdown for screen timeout.
This would give us an API for free, for example:
// get all the elements which have their keepvisible attribute set, and set them false
// after the user has somehow confirmed he has finished cooking his bacon
[].forEach.call(
document.querySelectorAll('[keepvisible=true]'),
function (el) {
el.keepvisible = false;
}
);
The simplest use case would be the global usage:
<html keepvisible>
An update after talking to people working with Chromium graphics side of things:
Using the proposed screen.getWakeLock() API or poke() together with getClientRects() and getBoundingClientRect() methods a polyfill could be created that would address the use case without introducing a new attribute to the HTMLElement. The keepvisible attribute could be replaced with a custom data-* or class.
It sounds like such a logic would be cheap to implement in JavaScript today, especially since this is not time-critical (timeouts are in the range of seconds, not milliseconds).
I’m not a big fan of poke() mostly because it doesn’t translate well to native APIs. On iOS, you can prevent the screen to dim and lock using idleTimerDisabled=YES [1], on Android, you would use some wake lock system [2] similar to Firefox OS [3]. The APIs will likely be similar on Desktops: something to prevent the screensaver and the lock screen to start.
I think the right approach would be something similar to Marco’s draft or Firefox OS system. However, I’m mostly interested in the security story around this feature. Should we have yet another prompt or could we try to do something more clever like fullscreen where the lock is happening but the user might get notified about it at some point? I feel that there isn’t much threat to the user with this API but there is a minor possible quality perspective issue wrt to the browser. We could definitely imagine a user complaining that Browser X prevents the phone to suspend even though it’s only the user’s favourite website doing so.
Re the security story and permissions: I like the proposal Dom made on the public-device-apis a while ago:
On the permission front, my rough thinking of a probably workable
approach would be:
no user consent asked when the Web app asks for “always-on”
at the time when the screen would by default go blank, the UA informs the user that the Web is using an “always-on” mode (e.g. via
an infobar), and let the user forbid it;
the UA would probably adjust that behavior depending on the remaining battery (i.e. simply not grant that right when battery is
too low, or prompt the user again if the battery goes down, etc)
likewise, the prompt/infobar might go away completely if the device is charging
I don’t see obvious issues with this approach. Also, this model works regardless of the API shape.
It seems that Dom’s idea and what I had in mind are very similar. However, I’m a bit concerned about showing a message after some period of time because that might be pretty painful for the user; most of the use cases for that API involve a heavy use of the screen. No user will be happy to see a message popping up in the middle of their flappy bird session.
This said, it seems that we agree that permission-wise, the most important bit is that the web page has to be visible, then there is room for experiments I guess.
I think what implementations could do to make this better, is to allow the user to persist the “allow example.org to keep the display on” permission setting (set per origin?). Then, this would be only annoyance the first time the user visits the site (assuming she trusts the site and allows it to persist the setting). This would work similarly to the Fullscreen API.
This would be mostly an annoyance for gaming or other use cases that are fast-paced, but less so for less interactive things such as cookbooks. And if the message can be easily dismissed, and the permission can be persisted, perhaps this is not so big an annoyance.
One good use case to test this API with would indeed be Flappy Bird powered by ambient light and/or proximity events based controls
I agree this is definitely something that would benefit from experimentation.