w3c / screen-wake-lock

Screen Wake Lock API
https://www.w3.org/TR/screen-wake-lock/
Other
86 stars 35 forks source link

Need maximum screen brightness mode #129

Open tomayac opened 5 years ago

tomayac commented 5 years ago

Apart from low-power mode (#84), this issue makes the case for adding a way to ask for maximum screen brightness mode, for example, to read QR codes (described in this use case issue). Here is a real-world example from Starbucks:

screenshot 2018-10-19 at 09 35 36

mounirlamouri commented 5 years ago

Isn't this orthogonal to this API? Should it be part of an API to control screen brightness? Do we know how these applications do this in current platforms (Android/iOS)?

tomayac commented 5 years ago

That’s the iOS way: https://developer.apple.com/documentation/uikit/uiscreen/1617830-brightness. I think it makes most sense as part of Wake Locks, as it’s generally considered a system-level thing to change, and native apps only request maximum screen brightness for allowing for codes to be read (iOS Wallet for general cards/tickets, DB Navigator as an example of a German train ticketing app).

mounirlamouri commented 5 years ago

Well, both Android and iOS platforms offer direct access to the screen brightness. We have a Screen interface on the Web. Why not expose this information there?

marcoscaceres commented 5 years ago

It's a strange one... @tomayac implies that it's declarative - because of intent... Could be imperative, but that seems kinda scary that any random web page could start having fun with the brightness.... could also even be a css thing, where you can request the brightness, but then the OS/browser can handle the request based on environmental conditions (e.g., if it's night or day).

mounirlamouri commented 5 years ago

I am not certain that moving the accessibility to maximum is very different from being able to set it to anything. Reading it is a different issue as it will be a fingerprinting surface.

tomayac commented 5 years ago

Judging from what I personally have seen with native apps, the only instance where I have encountered an app override the current system-level brightness is the (QR, bar-) code reading case.

I wouldn’t want (Web) apps to be able to read or modify my screen’s brightness apart from the use case described before. So I would argue for thinking of this as declarative.

mounirlamouri commented 5 years ago

I do not think that setting the brightness to an arbitrary value or setting it to maximum is any different with regards to potential for abuse. Reading brightness would however be a fingerprinting issue. Either way, I think we may be able to find a better home for this use case.

tomayac commented 5 years ago

I think we may be able to find a better home for this use case

@mounirlamouri Are you thinking of exposing a dedicated Web Screen Brightness API? One thing I (hopefully correctly) took away from @marcoscaceres' TPAC session slot (10:15AM on Friday) was that the general direction was to reduce the number of APIs on the Web Platform? Do you want to let individual browser tabs control (i.e., let write, but not read) their brightness?

tomayac commented 5 years ago

CC: @henrikjoreteg

mounirlamouri commented 5 years ago

I'm all for having less APIs but we shouldn't just move feature requests to other APIs just to avoid creating a new spec and API surface. If we believe the feature is worth having and we can't build it on top of another one, we should create another API. I would say that it would make more sense in the spirit of Marcos' comment to have an API to set the brightness instead of an API to set the screen to full brightness as if we need an API to set the brightness someday, it would create another API surface.

HenrikJoreteg commented 5 years ago

Hey folks! 👋 I'm the dev who first built that barcode screen on the Starbucks PWA.

I just have a couple of points of feedback. In my opinion, this is all in the interest of better supporting an entire class of applications that involve scanning a phone screen with a barcode reader. Insufficient contrast sometimes makes this harder, which is incredibly annoying. In the case of starbucks, if the PWA screen scan fails, then having to switch to the native app, or otherwise problem solve with the barista is incredibly frustrating. It transforms the experience from: "wow this is cool, look what a tech-savvy coffee-drinker I am" into "Crap, this is embarrassing, this app sucks, etc."

The main thing I originally asked for when we brought this up to Dion and others at Google a couple of years ago now was specifically:

  1. A permission-gated way to temporarily ask for screen brightness to go to 100%
  2. A way to ask the phone to stay awake so you don't pull it up while waiting in queue at starbucks, then find yourself trying to tap the screen to keep it awake while you're waiting for the person in front of you to order their orange mocha frappuccino with extra whip and sprinkles :)

I would imagine an API for this being something along the lines of:

window.requestWakeLock({fullScreenBrightness: true, timeout: 60000})
  .then(() => {
    // lock succeeded!
  })
  .catch(() => {
    // failed or rejected
  })

I really don't think there's a great usecase for reading screen brightness, or setting a specific brightness. It cause fingerprinting issues and frankly, feels like an OS-level concern that the user should get to decide. Again, this is all about enabling reliable scanning of phone screens.

The reason I suggested passing fullScreenBrightness as an option to a primary API of requestWakeLock instead of doing something like requestFullScreenBrightness is because I could see games and such wanting to prevent screens from falling asleep even if the user isn't tapping on the screen. Sometimes there are long in-game videos or animations where avoiding the screen going to sleep would be nice. So doing a wake-lock without adjusting screen brightness seems like a valid use case.

And, I think any time you want to enable screen scanning (barcodes, etc), it makes sense to keep the screen alive as often there's waiting involved, and having the screen go to sleep while actively trying to scan a phone is super annoying.

Anyway, that's just my two cents. I would love to see something along these lines land in browsers. Seems like something that would improve UX on the web for a large number of use cases.

marcoscaceres commented 5 years ago

@HenrikJoreteg, great feedback. Thank you. What you propose makes sense.

mounirlamouri commented 5 years ago

I think we should differentiate these three things:

In my opinion, even though the use case is valid and we should resolve it, it's unclear that it's a good idea going forward to try to resolve this use case specifically. In general, the Web Platform is looking at offering low level APIs as high level APIs end up too limited. I think that we could offer a better API if the app could simply set the brightness from 0 to 1 with pretty much the same threat model. Furthermore, linking the API to Wake Lock creates a similar limitation: even though for scanning use cases (eg. Starbucks), linking the two APIs make sense, as a platform, we need to think beyond this and we shouldn't assume anyone interested to change the brightness wants the screen to stay on.

jyasskin commented 5 years ago

There's a small risk of DoS if we let sites reduce the screen brightness, since users might not then be able to see the screen well enough to undo it. A separate API could, of course, deal with that risk, perhaps by forbidding sites from decreasing the brightness, or by showing a different prompt if the brightness is going down from when it's increasing.

Even after the Extensible Web Manifesto, we sometimes decide to provide a high-level API if it means the permission prompt can be simpler. This doesn't prevent us from also providing the low-level API with a scarier permission prompt.

So, what would the permission prompt look like for the brightness-setting API? Is it as acceptable to ask for forgiveness in that case as it is for wake-locks, given the concern above?

Will the extra complexity in defending against DoS slow down implementation of the lower-level API, when we might be able to get the wake-lock version sooner?

HenrikJoreteg commented 5 years ago

I personally can't think of a single good use case for wanting to set a specific brightness. This is not something I can imagine wanting as a user. To me that feels like a website reaching a hand out of my screen, opening my settings and moving the slider back and forth. As a user, that just seems wrong. That's an OS-level concern.

The only exception I've been able to think of is this screen barcode scenario. And the only reason I would be OK with that, as a user, is because it provides a very specific utility: It temporarily turns my phone into a concert ticket, boarding pass, etc. Under no other circumstances would I want a web app to mess with my screen brightness.

The truth is, even in that scenario I don't love the idea of a website having that power. But I'm perfectly happy to temporarily give it the power to transform my phone into a replacement for a paper boarding pass.

marcoscaceres commented 5 years ago

I have to agree with everything @HenrikJoreteg said. The only use case we have identified is "wake lock" (cooking a recipe, reading a book), and optionally and temporarily requesting full brightness (e.g., Starbucks, Eventbrite, and airline apps) ... we might not even need the timeout, it could just disable when the user performs and action such as turns off the screen, switches tabs, etc.

I also would definitely not want a website screwing around with the brightness level for random reasons, specially because on brightness adapts dynamically to the environment and time of day.

In my mind, the only question is around permission for bumping the brightness up.

tomayac commented 5 years ago

+1 to Henrik's and Marcos' comments. The brightness bump should also definitely require a user gesture, like, for example, opening a view in the app with a barcode (the gesture would be tapping something).

marcoscaceres commented 5 years ago

"triggered by user activation", as the cool spec kids say 😎 (really, 🤓)

HenrikJoreteg commented 5 years ago

There needs to be a corresponding way to cancel the wake lock as well. Maybe the promise returns an object with a .clear() method.

marcoscaceres commented 5 years ago

Would what’s already in the spec not work?


navigator.getWakeLock("screen", {fullBrightness: true}).then(wakeLock => {
  var request = wakeLock.createRequest();
  setTimeout(() => {
    request.cancel();
  }, 1000);
});
HenrikJoreteg commented 5 years ago

@marcoscaceres I'm late to the discussion here forgive me, yes that seems reasonable. 👍

mounirlamouri commented 5 years ago

I have to agree with everything @HenrikJoreteg said. The only use case we have identified is "wake lock" (cooking a recipe, reading a book), and optionally and temporarily requesting full brightness (e.g., Starbucks, Eventbrite, and airline apps) ... we might not even need the timeout, it could just disable when the user performs and action such as turns off the screen, switches tabs, etc.

Designed an API only based on use cases and not trying to expand from them seems dangerous and may end up with design flaws. Offering a larger ability will trigger new use cases we did not think of. One issue that may happen in the future is that full brightness will end up way too bright on some phones. With HDR getting more popular, display brightness will increase and we could end up in a situation where full brightness will simply be way too bright in some cases.

Also, brightness changes on mobile OSes, as far as I can tell, are specific to the application (Activity, on Android, I believe). Similarly, brightness changes should only apply to the tab, ideally in fullscreen even. I wouldn't worry much about applications trying to change the brightness as they wouldn't have an effect unless they are visible and the UA could put min values to make sure they don't attempt to keep the screen black.

HenrikJoreteg commented 5 years ago

@mounirlamouri if full brightness is too bright then how would you propose an app deal with this? Are you suggesting it would be better perhaps to set a target brightness in lumens?

In my opinion, the best APIs are where you clearly and succinctly express intent. So perhaps rather than arbitrarily saying "full brightness" what if it was something along the lines of "optimizeForScanning"? Or even "optimizeForContrast"

marcoscaceres commented 5 years ago

@mounirlamouri wrote:

Designed an API only based on use cases and not trying to expand from them seems dangerous and may end up with design flaws. Offering a larger ability will trigger new use cases we did not think of.

I'm sympathetic to this argument - but the potential to abuse and user annoyance as we described above is too obvious and great. Fine grained control is definitely not something we would consider implementing in Firefox.

I wouldn't worry much about applications trying to change the brightness as they wouldn't have an effect unless they are visible and the UA could put min values to make sure they don't attempt to keep the screen black.

I worry :( I don't think I can sell this internally.

@HenrikJoreteg wrote:

In my opinion, the best APIs are where you clearly and succinctly express intent. So perhaps rather than arbitrarily saying "full brightness" what if it was something along the lines of "optimizeForScanning"? Or even "optimizeForContrast"

I guess we could go down this route, but we've only come up with the a single purpose. We could make a working assumption that "optimizeForContrast" is the default, and then enhance the API if we come up with other things (based on actual apps needing to do actual things - like StarBucks).

HenrikJoreteg commented 5 years ago

I'm all for the simplest option. Are we aware of any scenario where max brightness would be a bad thing?

marcoscaceres commented 5 years ago

So, played with a few native apps. I don’t think we want a permission prompt. It should just be “triggered by user activation” (if the OS allows it).

jyasskin commented 5 years ago

Amusingly, if the "screen" wakelock is implemented on Android with https://developer.android.com/reference/android/view/WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON, as https://developer.android.com/reference/android/os/PowerManager.html#SCREEN_DIM_WAKE_LOCK recommends, we'll get max-brightness automatically. Maybe the web should follow along and have high-brightness implied by "screen".

mounirlamouri commented 5 years ago

The documentation is slightly confusing. It doesn't give max brightness but keeps the brightness as it is. This in in opposition to the solution that reduces the brightness but never shuts down the screen.

kenchris commented 5 years ago

Brightness wake lock is deprecated in Android. You are supposed to use FLAG_KEEP_SCREEN_ON.

Screenshot 2019-04-04 at 14 29 17

That will keep normal brightness (user set) and not dim or turn off the screen (dimming happens on Android just before the screen turns off)

Counting manually, my Pixel screen stays on for 30 seconds, then dims and stays dimmed for 10 seconds then turns off. Something like that.

Screenshot 2019-04-04 at 14 29 01

I think the conclusion is that we should not have a special "brightness" wake lock, but add some info in the spec that UAs should not dim while the lock is held. That could be non-nominative as well, if we want to be really flexible.

kenchris commented 5 years ago

You can (on Android at least) temporarily override the screen brightness and set it to max.

https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#BRIGHTNESS_OVERRIDE_FULL

image

aarongustafson commented 5 years ago

Hey all, I wanted to resurrect this discussion as there doesn’t seem to have been any resolution. We’ve heard this feature request a few times now from customers so it seems like it’s needed.

Reading through the above, there seem to be two options:

  1. Implement a screen brightness configuration option as part of Wake Lock, or
  2. Implement a separate brightness control API.

Is that a fair assessment? Then, beyond that, there is some discussion around how much control a developer should be granted over screen brightness:

  1. Full, granular control
  2. Ability to request full brightness, lowest brightness, or return to system settings

Based on my read through of the concerns above, it seems like the "lowest" brightness setting (if we decided to implement it) should not allow for a completely blank screen, right? I’m honestly uncertain what a use case for such an option would be, so it may not be needed.

Personally, I like @marcoscaceres’ API recommendation:

navigator.getWakeLock("screen", {fullBrightness: true}).then(wakeLock => {
  var request = wakeLock.createRequest();
  setTimeout(() => {
    request.cancel();
  }, 1000);
});

If we decided that we did want to have the lowest brightness option, that configuration option could probably be brightness with the acceptable values being "highest," "lowest", "none" (with "none being the default"?).

In terms of a use case roundup, here’s what I’ve got:

marcoscaceres commented 5 years ago

Maybe all we need is “auto” (which is the default) and “full”. I’m still unconvinced there is a use case for anything other than “full” brightness, but it gives us an extension point.

Alternatively, using a boolean is nice because if we can abuse type coercion between 0-1 (false/true) and then step using floats (e.g., 0.5) - but again, not something that should be in v1 imo.

aarongustafson commented 5 years ago

I like "auto" and "full" because it’s very clear what you are requesting.

tomayac commented 5 years ago

Just wondering, above, @marcoscaceres wrote

Would what’s already in the spec not work?

It seems like the only occurrence of "brightness' is in the introduction. Did it get removed?

Regarding keywords, maybe "maximum" (QR code use case, etc.), "auto", and "minimum" (I just need the screen to be on to occasionally check the status of something, but don't want to waste energy [probably more on desktop]) would work?

mounirlamouri commented 5 years ago

As we are adding permission plumbing into Chromium for Wake Lock, I would worry that binding wake lock and screen brightness could end up requiring some user consent for something that could be hard to describe (all the alternatives of "this application wants to keep your screen on at max brightness") and also would potentially gate the screen brightness feature behind another feature's security requirements.

If we just want to expose three values, what's wrong with screen.overrideBrightness(enum BrightnessOverride)?

marcoscaceres commented 5 years ago

As we discussed previously, we didn’t come up with a use case for overriding the brightness independently of requesting the wake lock. If users want to prevent the brightness change, I think we can avoid the permission prompt and just make it a UA setting (like, “prevent web pages from changing screen brightness”). Apart from some potential battery consumption, there isn’t a real privacy or security risk that would warrant needing a permission prompt, imo.

aarongustafson commented 5 years ago

I initially wondered about separating them as well @mounirlamouri, but I've come to agree with @marcoscaceres’ perspective on this. If, down the road, there is a brightness use case that does not involve a wake lock, we can always consider a separate API and this configuration option will remain useful as an optional convenience when using wake lock.

mounirlamouri commented 5 years ago

As @kenchris mentioned above, Android used to have this exact API and deprecated it. Why makes us think that we will not end up facing a similar faith?

aarongustafson commented 5 years ago

@mounirlamouri @kenchris Do we have any insight into why Android deprecated it?

mounirlamouri commented 5 years ago

I do not have more background than what's in the documentation. It seems that there was a permission issue. This said, AFAICT, there are no permissions required to change the screen brightness on Android today. Maybe at the time that API needed permissions because of screen brightness changes? In general, I think that merging APIs should require a justification instead of splitting them in logical units.

aarongustafson commented 5 years ago

In general, I think that merging APIs should require a justification instead of splitting them in logical units.

Normally, I’d be 100% with you. I’m just struggling to think of a use case that does not involve Wake Lock. Unless, of course, ChromeOS (or KaiOS) is interested in managing device brightness purely from web code. If that’s the case, separating might make sense. And in that instance, I could also see a desire for granular control over brightness level. When tied to wake lock, however, I think the broad strokes approach outlined above is ideal. I’m also not averse to having this feature exposed via a convenient configuration option when making a wake lock request.

Perhaps a compromise would be to plumb the brightness controls separately, but not (yet) expose them as a distinct DOM API. That way the code remains separate and the features—wake lock and brightness control—are not directly tied together. Wake Lock could then call that separate API under the hood when the associated configuration option is used. It seems like that might be the most flexible approach, allowing us to focus on this use case now, but it also keeps all options on the table for a distinct API if some solid use cases materialize in the future.

marcoscaceres commented 5 years ago

Respectively, I’d really like to avoid us going down the “web os” path... many of us carry deep scars from previous attempts. Let’s solve the use cases at hand, which I think the above proposal does.

If we find a need to add fine-grained brightness control, we can do that later.

brainfoolong commented 4 years ago

Hi, i just want to give feedback why i also would need a "full brightness/wake lock" feature. First, i think this should be 2 different APIs

I have a native app that saves barcodes/qrcodes that then will be scanned from display by shops and different scanners.

Most of the time, when this is not working, the screen brightness is the problem. Many scanners just need more brightness to be able to scan from display. Probably this will be more of a problem in the future because more and more services provide scanable codes.

I converted my native app into PWA and that's one thing that is currently simply not possible with web technology. I have to display the information that the user must manually turn up the brightness in the phone settings. That's not handy.

In general with PWA's, we hear in every corner that this can and probably should replace simple native apps. I think with this idea in mind, such an "easy" API should be implemented.

In comparison: We get a massive new file api with native file access, which is definetely much more risky than screen brightness or wake locks.

Just my feedback.

Greetz Roland

marcoscaceres commented 4 years ago

Thanks @brainfoolong! That's really good input for us to consider.

CheloXL commented 4 years ago

I would also like to suggest "half" to the list of possible brightness. My app currently makes use of the WakeLock so the user is able to see a timer/dynamic info on screen. This is coupled with the speech api (TTS), that reads the info, so the user has several feedback channels.

Most of the time, if the user enabled TTS, that means that he/she is not really interested in watching the screen (but I still need it on for TTS to work). Been able to (maybe after some time) reduce the brightness will let the user save some battery.

This is similar on how the timer/stopwatch works on Android. You start the timer, and after some time, the screen dims (but never switches off).

marcoscaceres commented 4 years ago

You start the timer, and after some time, the screen dims (but never switches off).

This would be the default behavior then. It's basically, request full brightness, or "auto" (OS controlled).

CheloXL commented 4 years ago

This would be the default behavior then. It's basically, request full brightness, or "auto" (OS controlled).

Mmm.. I don't think so. Right now the screen brightness is what is defined by the user (as you said, OS controlled). With full, that means full brightness. In neither cases the screen dimmes after some time if the wake lock is active.

I would like a way to acquire the lock in whatever level the user defined, and after some time, I release that lock and acquire a new one at half of user defined brightness.

marcoscaceres commented 4 years ago

and acquire a new one at half of user defined brightness.

I see, but overriding the user's brightness is a non-starter. The only options I see are:

  1. acquire wake lock (default): ... lock acquires, OS may dim the screen but it doesn't shut off (outside the browsers control).
  2. acquire wake lock (full brightness): ... lock acquires, full brightness is requested but not guaranteed, screen may dim if OS wants to.

Full brightness is never assured, and neither is dimming (as it's OS controlled). Best we (browsers) can do is request it and hope for the best.

CheloXL commented 4 years ago

Sorry, but I don't get it... if you can request full brightness, why you can't request half brightness? Of course no one is assured to happen.

Regarding the screen dim, right now at least on Android, the dim never happens with a WakeLock. Once you acquire the lock, the screen remains in the same brightness until you release it.

I really don't NEED a half brightness, but what I really want is the dim feature the phone already has. Maybe, instead of the "half" option, another setting (bool) to let the OS decide if it can dim the screen after a time (defined by the user on the OS). This option will one work on phones with that feature.

marcoscaceres commented 4 years ago

Sorry, but I don't get it... if you can request full brightness, why you can't request half brightness? Of course no one is assured to happen.

I see "half brightness" as the user's/system's default. For example: you request the lock, the screen locks at whatever brightness, after 1 minute the system dims it (but doesn't switch off). If the user touches the screen, the OS just puts everything back to normal brightness.

This is different from "full": which is "turn it to full and try to keep it full for as long as possible". The OS may dim, but if the user touches the screen, then it should return to full brightness.

Hence, the "half brightness" is basically just the default behavior of screen wake lock.

Make sense or am I missing something?