This document specifies an API that allows web applications to increase the brightness of a device's screen under certain conditions.

Introduction

Allowing web applications to request an increase to the display's brightness would help address the following use cases:

The proposed Screen Brightness API extends the Screen interface with a new operation, inspired by the [[screen-wake-lock]] API.

Policy control

The Screen Brightness API defines a [=policy-controlled feature=] identified by the string `"screen-brightness"`. Its [=default allowlist=] is `["self"]`.

Concepts

The task source for the tasks mentioned in this specification is the screen brightness task source.

Extensions to the `Document` interface

Internal slots

Internal slot Initial value Description
[[\ActiveBrightnessSentinels]] An empty list. A list of {{ScreenBrightnessSentinel}} objects associated with this {{Document}}.

Extensions to the `Screen` interface

The [[[CSSOM-View]]] specification defines the Screen interface, which this specification extends:

        [SecureContext]
        partial interface Screen {
          Promise<ScreenBrightnessSentinel> requestBrightnessIncrease();
        };
      

The requestBrightnessIncrease() method

The requestBrightnessIncrease() method steps are:

  1. Let |document:Document| be [=this=]'s [=relevant settings object=]'s [=associated Document=].
  2. If |document| is not [=allowed to use=] the [=policy-controlled feature=] named "`screen-brightness`", return [=a promise rejected with=] a {{"NotAllowedError"}} {{DOMException}}.
  3. If the |document|'s [=Document/browsing context=] is `null`, return [=a promise rejected with=] a {{"NotAllowedError"}} {{DOMException}}.
  4. If |document| is not [=Document/fully active=], return [=a promise rejected with=] a {{"NotAllowedError"}} {{DOMException}}.
  5. If |document| does not have [=transient activation=], return [=a promise rejected with=] a {{"NotAllowedError"}} {{DOMException}}.
  6. Let |promise:Promise| be [=a new promise=].
  7. Run the following steps in parallel:
    1. Queue a global task on the screen brightness task source given |document|'s relevant global object to run these steps:
      1. If |document|'s [=Document/visibility state=] is "`hidden`", then:
        1. Reject |promise| with a {{"NotAllowedError"}} {{DOMException}}.
        2. Abort these steps.
      2. If |document|.{{Document/[[ActiveBrightnessSentinels]]}} [=list/is empty=], then invoke the following steps in parallel:
        1. Ask the underlying operating system to increase the brightness screen.
      3. Let |sentinel:ScreenBrightnessSentinel| be a new {{ScreenBrightnessSentinel}} object.
      4. [=List/Append=] |sentinel| to |document|.{{Document/[[ActiveBrightnessSentinels]]}}.
      5. Resolve |promise| with |sentinel|.
  8. Return |promise|.

The ScreenBrightnessSentinel interface

        [SecureContext, Exposed=(Window)]
        interface ScreenBrightnessSentinel : EventTarget {
          readonly attribute boolean released;
          Promise<undefined> release();
          attribute EventHandler onrelease;
        };
      

A {{ScreenBrightnessSentinel}} object provides a handle to a screen brightness increase request. Releasing all {{ScreenBrightnessSentinel}} instances tell the underlying operating system to use normal screen brightness policy.

Internal slots

{{ScreenBrightnessSentinel}} instances are created with the following internal slots:

Internal slot Initial value Description (non-normative)
[[\Released]] `false` Whether the given {{ScreenBrightnessSentinel}} has been released.

The released attribute

The {{ScreenBrightnessSentinel/released}} getter steps are to return [=this=].{{ScreenBrightnessSentinel/[[Released]]}}.

The release() method

The {{ScreenBrightnessSentinel/release()}} method steps are:

  1. If this's {{ScreenBrightnessSentinel/[[Released]]}} is `false`, then run release a screen brightness increase request with |document:Document| set to [=this=]'s [=relevant settings object=]'s [=associated Document=] and |sentinel:ScreenBrightnessSentinel| set to this.
  2. Return a promise resolved with `undefined`.

The onrelease attribute

The {{ScreenBrightnessSentinel/onrelease}} attribute is an event handler whose corresponding event handler event type is release.

It is used to notify scripts that a given {{ScreenBrightnessSentinel}} object's handle has been released, either due to the {{ScreenBrightnessSentinel/release()}} method being called or because the screen brightness increase request was released by the user agent.

Garbage collection

While a {{ScreenBrightnessSentinel}} object has one or more event listeners registered for "release", and the {{ScreenBrightnessSentinel}} object hasn't already been released, there MUST be a strong reference from the {{Window}} object that the {{ScreenBrightnessSentinel}} object's constructor was invoked from to the {{ScreenBrightnessSentinel}} object itself.

While there is a task queued by an {{ScreenBrightnessSentinel}} object on the screen brightness task source, there MUST be a strong reference from the {{Window}} object that the {{ScreenBrightnessSentinel}} object's constructor was invoked from to that {{ScreenBrightnessSentinel}} object.

Managing screen brightness increase requests

Auto-releasing screen brightness increase requests

A user agent may release a screen brightness increase request at any time. For example, when:

Handling document loss of full activity

When a {{Document}} |document:Document| becomes no longer [=Document/fully active=], the user agent must run these steps:

  1. [=list/For each=] |sentinel:ScreenBrightnessSentinel| in |document|.{{Document/[[ActiveBrightnessSentinels]]}}:
    1. Run release a screen brightness increase request with |document| and |sentinel|.

Handling document loss of visibility

This specification defines the following [=page visibility change steps=] with [=Document/visibility state=] |state| and |document:Document|:

  1. If |state| is not "`hidden`", abort these steps.
  2. [=list/For each=] |sentinel:ScreenBrightnessSentinel| in |document|.{{Document/[[ActiveBrightnessSentinels]]}}:
    1. Run release a screen brightness increase request with |document| and |sentinel|.

Release screen brightness increase request algorithm

To release a screen brightness increase request for a given |document:Document| and |sentinel:ScreenBrightnessSentinel| run these steps:

  1. If |document|.{{Document/[[ActiveBrightnessSentinels]]}} does not contain |sentinel|, abort these steps.
  2. Remove |sentinel| from |document|.{{Document/[[ActiveBrightnessSentinels]]}}.
  3. Tell the underlying operating system that normal screen brightness policy should be used.
  4. Set |sentinel|'s {{ScreenBrightnessSentinel/[[Released]]}} to `true`.
  5. Fire an event named "`release`" at |sentinel|.

Security and privacy considerations

Active screen brightness increase requests will cause the display to operate at higher power levels than they otherwise would. This will lead to faster battery depletion. It is of particular concern for mobile devices, which often don't have a stationary power source readily available. Complete battery depletion at an unexpected time can lead to inability of the user to make or receive calls and use network services, including the emergency call service.

Implementations MAY ignore requests for screen brightness increase if, for example, the battery capacity is low, or the user has put their device in a power-saving mode.

Examples

        const button = document.querySelector("button");

        button.onclick = async () => {
          try {
            // Try increasing screen brightness for 5 seconds only.
            const sentinel = await screen.requestBrightnessIncrease();
            setTimeout(() => sentinel.release(), 5000);
          } catch(error) {
            // The request failed. Argh ;(
          }
        }
      
        const button = document.querySelector("button");

        button.onclick = async () => {
          // Disable button when user clicks to prevent multiple calls.
          button.disabled = true;
          try {
            // Try increasing screen brightness.
            const sentinel = await screen.requestBrightnessIncrease();
            sentinel.onrelease = () => {
              // Re-enable button when sentinel is released.
              button.disabled = false;
            };
          } catch(error) {
            // Re-enable button when request failed.
            button.disabled = false;
          }
        }
      

This specification defines conformance criteria for a single product: a user agent that implements the interfaces that it contains.

Acknowledgments

We would like to offer our sincere thanks to TODO for their contributions to this work.