├── .github
└── workflows
│ ├── auto-publish.yml
│ └── tidy.yml
├── .pr-preview.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── energy-saver-mode-explainer.md
├── index.html
├── releases
├── CR.html
├── CR2-diff.html
├── CR2.html
├── LC2-diff.html
├── PR-diff.html
└── PR.html
├── tidyrc
└── w3c.json
/.github/workflows/auto-publish.yml:
--------------------------------------------------------------------------------
1 | # Workflow based on the w3c/spec-prod action example to deploy to W3C using Echidna:
2 | # https://github.com/w3c/spec-prod/blob/main/docs/examples.md#deploy-to-w3c-using-echidna
3 |
4 | name: CI
5 |
6 | on:
7 | pull_request: {}
8 | push:
9 | branches: [gh-pages]
10 | paths:
11 | - 'index.html'
12 | jobs:
13 | main:
14 | name: Build, Validate and Deploy
15 | runs-on: ubuntu-20.04
16 | steps:
17 | - uses: actions/checkout@v2
18 | - uses: w3c/spec-prod@v2
19 | with:
20 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }}
21 | # Replace following with appropriate value. See options.md for details.
22 | W3C_WG_DECISION_URL: https://lists.w3.org/Archives/Public/public-device-apis/2021May/0008.html
23 | W3C_BUILD_OVERRIDE: |
24 | specStatus: WD
25 | shortName: battery-status
26 |
--------------------------------------------------------------------------------
/.github/workflows/tidy.yml:
--------------------------------------------------------------------------------
1 | name: Run tidy on spec
2 | on:
3 | push:
4 | branches:
5 | - "gh-pages"
6 | paths:
7 | - "index.html"
8 |
9 | jobs:
10 | tidy:
11 | name: Reformat index.html if necessary
12 | # We need macos-latest because tidy-2:5.6.0 which is present on all Ubuntu
13 | # releases supported by GitHub actions has a bug that causes the documents
14 | # to be wrongly formatted.
15 | # https://github.com/w3c/screen-wake-lock/pull/319 has more details.
16 | runs-on: macos-latest
17 | steps:
18 | - uses: actions/checkout@v2
19 | - run: brew install tidy-html5
20 | - run: tidy -config tidyrc -modify index.html
21 | - uses: peter-evans/create-pull-request@v3
22 | with:
23 | body: |
24 | Automated change.
25 |
26 | `index.html` reformatted with `tidy -config tidyrc -modify index.html`.
27 | branch: html-tidy
28 | commit-message: "chore: Reformat document using tidy-html5"
29 | delete-branch: true
30 | title: "chore(tidy): reformat index.html"
31 |
--------------------------------------------------------------------------------
/.pr-preview.json:
--------------------------------------------------------------------------------
1 | {
2 | "src_file": "index.html",
3 | "type": "respec"
4 | }
5 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/).
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the
2 | [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy/) and
3 | [Software and Document License](https://www.w3.org/Consortium/Legal/copyright-
4 | software). To make substantive contributions to specifications, you must either participate
5 | in the relevant W3C Working Group or make a non-member patent licensing commitment.
6 |
7 | If you are not the sole contributor to a contribution (pull request), please identify all
8 | contributors in the pull request comment.
9 |
10 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows:
11 |
12 | ```
13 | +@github_username
14 | ```
15 |
16 | If you added a contributor by mistake, you can remove them in a comment with:
17 |
18 | ```
19 | -@github_username
20 | ```
21 |
22 | If you are making a pull request on behalf of someone else but you had no part in designing the
23 | feature, you can remove yourself with the above syntax.
24 |
25 | # Tests
26 |
27 | For normative changes, a corresponding
28 | [web-platform-tests](https://github.com/web-platform-tests/wpt) PR is highly appreciated. Typically,
29 | both PRs will be merged at the same time. Note that a test change that contradicts the spec should
30 | not be merged before the corresponding spec change. If testing is not practical, please explain why
31 | and if appropriate [file a web-platform-tests issue](https://github.com/web-platform-tests/wpt/issues/new)
32 | to follow up later. Add the `type:untestable` or `type:missing-coverage` label as appropriate.
33 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | All documents in this Repository are licensed by contributors
2 | under the
3 | [W3C Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software).
4 |
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Battery Status API
2 |
3 | This repository contains the
4 | [Battery Status API](https://w3c.github.io/battery/)
5 | specification that is being worked on in the
6 | [W3C Device APIs Working Group](http://www.w3.org/2009/dap/).
--------------------------------------------------------------------------------
/energy-saver-mode-explainer.md:
--------------------------------------------------------------------------------
1 | # Energy Saver Mode ⚡🔋
2 |
3 | ## Authors:
4 |
5 | - Anssi Kostiainen
6 |
7 | ## Participate
8 | - GitHub issue https://github.com/w3c/battery/issues/9
9 |
10 | ## Introduction
11 |
12 | >**Energy conservation** is the effort to reduce wasteful energy consumption by using fewer energy services. This can be done by **using energy more effectively** or **changing one's behavior** to use less service. ([Wikipedia](https://en.wikipedia.org/wiki/Energy_conservation))
13 |
14 | This document discusses an energy saver mode feature that is an integral part of modern operating systems. This feature provides a hint to native applications that they should use energy more effectively or change their behavior to avoid doing something or postpone non-critical tasks. This information would be equally beneficial to web apps to enable more energy-efficient web experiences.
15 |
16 | ## Goals
17 |
18 | The end user expects modern web applications to use less energy when the OS-level energy saver mode setting is turned on. Web authors have currently no means to apply such optimization on demand informed by this signal because it does not exist.
19 |
20 | Below we expand on use cases that may make use of context-sensitive [energy saving strategies](#energy-saving-strategies-for-web-applications) with the help of a [proposed new API](#proposed-new-api) that exposes the OS-level energy saver mode state and a corresponding signal.
21 |
22 | Use cases for Energy Saver Mode
24 |
25 | - Web app disables CSS animations and stops video playback when the energy saver mode is turned on.
26 |
27 | - Web app adjusts the amount/number of data/messages it fetches over the network as well as the polling frequency depending on the energy saving mode state.
28 |
29 | - If the user has put the device in energy saving mode, the webmail client will only poll for new data if the user explicitly interacts with the app and clicks an "Update" button. If the energy saving mode is turned off, the app fetches data without user interaction.
30 |
31 | - Web-based navigation app will only start an energy-intensive operation that must run to completion if the device is not in energy saving mode. For example, when starting a long-running navigation, the user may be recommended to turn on the energy saver mode (if the battery is also low).
32 |
33 | - The mapping app will show a simpler 2D map if the energy saving mode is on, and only turn the WebGL-powered 3D map on by default if the energy saver mode is off.
34 |
35 | - Web app will only start a long-running energy-intensive operation if the energy saving mode is turned off. For example, download high-resolution textures in a web-based game, or enable extra video feeds in a web-based video conferencing app.
36 |
37 | - The user manually turns on the OS energy saving mode even if the battery level is 95% to ensure the device will survive a long-haul flight. While on the plane, the user browses the web and uses his favourite web apps using the airliner's Wi-Fi service. The web-based apps in use automatically enable optimizations to prolong the battery life: service worker caching approach is switched to "cache as needed", features using WebGL are disabled, and automatic polling for new data over network is stopped.
38 |
39 | - The user is laying in her bed before going to sleep. The phone's battery is below 15% and the energy saver mode is automatically turned on by the OS. Knowing the phone will soon be able to recharge over night, the user will turn off the energy saver mode and the web-based email client starts to fetch new emails automatically while she is working to reach inbox zero. (The OS also returns the screen brightness to its normal setting.)
40 |
41 | - A web developer conducts an A/B test of a new version of a web application to ensure all of its diverse userbase still receives a good experience. The performance metric data retrieved via [Performance Timeline](https://www.w3.org/TR/performance-timeline-2/) is adjusted to consider the energy saver mode state.
42 |
43 |
65 | Other interesting tidbits
66 |
67 |
68 | - Some estimates put the global carbon emissions of the internet’s 5 billion worldwide users on par with that of the airline industry. ([Ecograder](https://ecograder.com/how-it-works))
69 |
70 | - The internet consumes a lot of electricity. 416.2 TWh per year to be precise. To give you some perspective, that's more than the entire United Kingdom. ([Website Carbon Calculator](https://www.websitecarbon.com/))
71 |
72 | - The web must be an environmentally sustainable platform. ([W3C TAG Ethical Web Principles](https://www.w3.org/TR/ethical-web-principles/#sustainable))
73 |
74 | - The web design industry has taken early steps to define [strategies](https://sustainablewebdesign.org/strategies/) for delivering sustainable web design projects and developed tools such as Ecograder that crawl websites to give an emissions estimate.
75 |
76 |
95 | Examples of context-sensitive energy optimizations
96 |
97 |
98 | - stop or limit [animations](https://developer.mozilla.org/en-US/docs/Web/Performance/Animation_performance_and_frame_rate) via SVG, JavaScript, canvas and WebGL, CSS animation, video, animated gifs and PNGs
99 | - stop or limit script-driven background activity
100 | - do not automatically poll (or push) for new data over the network, fetch data only when requested by the user (e.g. hit "get new messages" in an email client)
101 | - increase the polling frequency of new data to a reasonable level (e.g. update stock ticker data hourly instead of every minute)
102 | - adjust the amount or number of messages or data in a single fetch
103 | - avoid eager pre-loading and fetch only minimal assets required upon load
104 | - use lower quality assets, images, and videos, or use placeholder images in place of non-cricial ones
105 | - throttle or disable secondary content e.g. optional third-party embeds
106 | - selectively employ [optimizations for canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas)
107 | - reduce or do not use canvas, WebGL, WebGPU or other energy-intensive web capabilities
108 | - prefer "cache as needed" over "precaching" as a [service worker caching approach](https://web.dev/learn/pwa/assets-and-data/#frequently-used-cache-approaches)
109 | - use a darker theme
110 | - stop rendering (non-critical) audio
111 | - release the screen lock to allow the OS to turn the screen off sooner
112 | - (TODO: interaction with the [Screen Wake Lock API](https://www.w3.org/TR/screen-wake-lock/))
113 |
61 | The Devices and Sensors Working Group will apply editorial 62 | modernizations to this specification, perform a round of self-review 63 | and revisions on the security and privacy aspects of the API before 64 | requesting horizontal review. Existing 66 | security and privacy issues are available. 67 |
68 |74 | The Battery Status API specification defines a means for web developers 75 | to programmatically determine the battery status of the hosting device. 76 | Without knowing the battery status of a device, a web developer must 77 | design the web application with an assumption of sufficient battery 78 | level for the task at hand. This means the battery of a device may 79 | exhaust faster than desired because web developers are unable to make 80 | decisions based on the battery status. Given knowledge of the battery 81 | status, web developers are able to craft web content and applications 82 | which are power-efficient, thereby leading to improved user experience. 83 | Authors should be aware, however, that a naïve implementation of this 84 | API can negatively affect the battery life. 85 |
86 |87 | The Battery Status API can be used to defer or scale back work when the 88 | device is not charging in or is low on battery. An archetype of an 89 | advanced web application, a web-based email client, may check the 90 | server for new email every few seconds if the device is charging, but 91 | do so less frequently if the device is not charging or is low on 92 | battery. Another example is a web-based word processor which could 93 | monitor the battery level and save changes before the battery runs out 94 | to prevent data loss. 95 |
96 |99 | This specification defines conformance criteria that apply to a single 100 | product: the user agent that implements the interfaces that 101 | it contains. 102 |
103 |109 | The API defined in this specification is used to determine the battery 110 | status of the hosting device. 111 |
112 |113 | The user agent SHOULD not expose high precision readouts of battery 114 | status information as that can introduce a new fingerprinting vector. 115 |
116 |117 | The user agent MAY ask the user for battery status information access, 118 | or alternatively, enforce the user permission requirement in its 119 | private browsing modes. 120 |
121 |122 | The user agent SHOULD inform the user of the API use by scripts in an 123 | unobtrusive manner to aid transparency and to allow the user to revoke 124 | the API access. 125 |
126 |127 | The user agent MAY obfuscate the exposed value in a way that authors 128 | cannot directly know if a hosting device has no battery, is charging or 129 | is exposing fake values. 130 |
131 |137 | The task source for the tasks mentioned in this 138 | specification is the battery status task source. 139 |
140 |146 | [SecureContext] 147 | partial interface Navigator { 148 | Promise<BatteryManager> getBattery(); 149 | }; 150 |151 |
152 | This method was exposed to a non-secure context until PR #51. 154 |
155 |163 | Internal slot 164 | | 165 |166 | Initial value 167 | | 168 |169 | Description 170 | | 171 |
---|---|---|
176 | [[\BatteryPromise]] 177 | | 178 |179 | `null` 180 | | 181 |182 | A {{Promise}} returned by calls to {{Navigator/getBattery()}}. 183 | | 184 |
187 | [[\BatteryManager]] 188 | | 189 |190 | `null` 191 | | 192 |193 | The {{BatteryManager}} instance associated with a given 194 | {{Navigator}} after it has been created via 195 | {{Navigator/getBattery()}}. 196 | | 197 |
207 | The getBattery() method steps are: 208 |
209 |240 | [SecureContext, Exposed=Window] 241 | interface BatteryManager : EventTarget { 242 | readonly attribute boolean charging; 243 | readonly attribute unrestricted double chargingTime; 244 | readonly attribute unrestricted double dischargingTime; 245 | readonly attribute double level; 246 | attribute EventHandler onchargingchange; 247 | attribute EventHandler onchargingtimechange; 248 | attribute EventHandler ondischargingtimechange; 249 | attribute EventHandler onlevelchange; 250 | }; 251 |252 |
253 | The BatteryManager interface represents the current 254 | battery status information of the hosting device. 255 |
256 |257 | The user agent is said to be unable to report the battery 258 | status information if it is not able to report the values for any 259 | of the attributes, for example, due to a user or system preference, 260 | setting, or limitation. 261 |
262 | 270 |275 | {{BatteryManager}} instances are created with the following 276 | internal 278 | slots: 279 |
280 |284 | Internal slot 285 | | 286 |287 | Initial value 288 | | 289 |
---|---|
294 | [[\Charging]] 295 | | 296 |297 | `true` 298 | | 299 |
302 | [[\ChargingTime]] 303 | | 304 |305 | 0 306 | | 307 |
310 | [[\DischargingTime]] 311 | | 312 |313 | Positive Infinity 314 | | 315 |
318 | [[\Level]] 319 | | 320 |321 | 1.0 322 | | 323 |
331 | The {{BatteryManager/[[Charging]]}} internal slot represents the 332 | charging state of the system's battery. It MUST be set to `false` 333 | if the battery is discharging, and set to `true` if the battery is 334 | charging, the implementation is unable to report the state, or 335 | there is no battery attached to the system, or otherwise. 336 |
337 |338 | When the system battery's charging state changes, the user agent 339 | must run the update the battery status and notify algorithm 340 | with {{BatteryManager/[[Charging]]}}, `true` or `false` depending 341 | on whether the battery is charging or discharging, and 342 | "[=chargingchange=]". 343 |
344 |350 | The {{BatteryManager/[[ChargingTime]]}} internal slot represents 351 | the remaining time in seconds until the system's battery is fully 352 | charged. It MUST be set to 0 if the battery is full or there is no 353 | battery attached to the system, and to the value positive Infinity 354 | if the battery is discharging, the implementation is unable to 355 | report the remaining charging time, or otherwise. 356 |
357 |358 | When the battery charging time is updated, the user agent must run 359 | the update the battery status and notify algorithm with 360 | {{BatteryManager/[[ChargingTime]]}}, the new charging time in 361 | seconds, and "[=chargingtimechange=]". 362 |
363 |369 | The {{BatteryManager/[[DischargingTime]]}} attribute represents the 370 | remaining time in seconds until the system's battery is completely 371 | discharged and the system is about to be suspended. It MUST be set 372 | to the value positive Infinity if the battery is charging, the 373 | implementation is unable to report the remaining discharging time, 374 | there is no battery attached to the system, or otherwise. 375 |
376 |377 | When the battery discharging time is updated, the user agent must 378 | run the update the battery status and notify algorithm with 379 | {{BatteryManager/[[DischargingTime]]}}, the new discharging time in 380 | seconds, and "[=dischargingtimechange=]". 381 |
382 |388 | The {{BatteryManager/[[Level]]}} internal slot represents the 389 | system's battery's level. It MUST be set to 0 if the system's 390 | battery is depleted and the system is about to be suspended, and to 391 | 1.0 if the battery is full, the implementation is unable to report 392 | the battery's level, or there is no battery attached to the system. 393 |
394 |395 | When the battery level is updated, the user agent must run the 396 | update the battery status and notify algorithm with 397 | {{BatteryManager/[[Level]]}}, the new battery level, and 398 | "[=levelchange=]". 399 |
400 |402 | The definition of how often the "[=chargingtimechange=]", 403 | "[=dischargingtimechange=]", and "[=levelchange=]" events are fired 404 | is left to the implementation. 405 |
406 |412 | The charging getter steps are to return 413 | [=this=].{{BatteryManager/[[Charging]]}}. 414 |
415 |421 | The chargingTime getter steps are to return 422 | [=this=].{{BatteryManager/[[ChargingTime]]}}. 423 |
424 |430 | The dischargingTime getter steps are to return 431 | [=this=].{{BatteryManager/[[DischargingTime]]}}. 432 |
433 |439 | The level getter steps are to return 440 | [=this=].{{BatteryManager/[[Level]]}}. 441 |
442 |448 | The following are the event handlers (and their corresponding 449 | event handler event types) that MUST be supported as 450 | attributes by the {{BatteryManager}} object: 451 |
452 |456 | event handler 457 | | 458 |459 | event handler event type 460 | | 461 |
---|---|
466 | onchargingchange 467 | | 468 |469 | `chargingchange` 470 | | 471 |
474 | onchargingtimechange 475 | | 476 |477 | `chargingtimechange` 478 | | 479 |
482 | ondischargingtimechange 483 | | 484 |485 | `dischargingtimechange` 486 | | 487 |
490 | onlevelchange 491 | | 492 |493 | `levelchange` 494 | | 495 |
504 | To update the battery status and notify given an internal 505 | slot |slot|, a |value| and an |eventName|, run the following steps: 506 |
507 |535 | If a hosting device contains more than one battery, 536 | {{BatteryManager}} SHOULD expose a unified view of the batteries. 537 |
538 |539 | The {{BatteryManager/[[Charging]]}} internal slot MUST be set to true 540 | if at least one battery's charging state as described above is true. 541 | Otherwise, it MUST be set to false. 542 |
543 |544 | The {{BatteryManager/[[ChargingTime]]}} internal slot can be set to 545 | the maximum charging time of the individual batteries if charging in 546 | parallel, and to the sum of the individual charging times if charging 547 | serially. 548 |
549 |550 | The {{BatteryManager/[[DischargingTime]]}} internal slot can be set 551 | to the maximum discharging time of the individual batteries if 552 | discharging in parallel, and to the sum of individual discharging 553 | times if discharging serially. 554 |
555 |556 | The {{BatteryManager/[[Level]]}} internal slot can be set to the 557 | average of the levels of batteries of same capacity, or the weighted 558 | average of the battery levels for batteries of different capacities. 559 |
560 |
567 | The Battery Status API is a policy-controlled feature identified
568 | by the string "battery
". Its [=policy-controlled
569 | feature/default allowlist=] is [=default
570 | allowlist/'self'=]
.
571 |
578 | This trivial example writes the battery level to the console each time 579 | the level changes: 580 |
581 |582 | // We get the initial value when the promise resolves ... 583 | navigator.getBattery().then(function(battery) { 584 | console.log(battery.level); 585 | // ... and any subsequent updates. 586 | battery.onlevelchange = function() { 587 | console.log(this.level); 588 | }; 589 | }); 590 |591 |
592 | Alternatively, the same using the addEventListener()
593 | method:
594 |
596 | navigator.getBattery().then(function(battery) { 597 | console.log(battery.level); 598 | battery.addEventListener('levelchange', function() { 599 | console.log(this.level); 600 | }); 601 | }); 602 |603 |
604 | The following example updates the indicators to show the charging 605 | state, level and time remaining in minutes: 606 |
607 |608 | <!DOCTYPE html> 609 | <html> 610 | <head> 611 | <title>Battery Status API Example</title> 612 | <script> 613 | window.onload = function () { 614 | function updateBatteryStatus(battery) { 615 | document.querySelector('#charging').textContent = battery.charging ? 'charging' : 'not charging'; 616 | document.querySelector('#level').textContent = battery.level; 617 | document.querySelector('#dischargingTime').textContent = battery.dischargingTime / 60; 618 | } 619 | 620 | navigator.getBattery().then(function(battery) { 621 | // Update the battery status initially when the promise resolves ... 622 | updateBatteryStatus(battery); 623 | 624 | // .. and for any subsequent updates. 625 | battery.onchargingchange = function () { 626 | updateBatteryStatus(battery); 627 | }; 628 | 629 | battery.onlevelchange = function () { 630 | updateBatteryStatus(battery); 631 | }; 632 | 633 | battery.ondischargingtimechange = function () { 634 | updateBatteryStatus(battery); 635 | }; 636 | }); 637 | }; 638 | </script> 639 | </head> 640 | <body> 641 | <div id="charging">(charging state unknown)</div> 642 | <div id="level">(battery level unknown)</div> 643 | <div id="dischargingTime">(discharging time unknown)</div> 644 | </body> 645 | </html> 646 |647 |
655 | The group is deeply indebted to Mounir Lamouri, Jonas Sicking, and the 656 | Mozilla WebAPI team in general for their invaluable feedback based on 657 | prototype implementations. Many thanks to the people behind the System 658 | Information API and Device Orientation Event specification for the 659 | initial inspiration. Also thanks to the nice folks bringing us the Page 660 | Visibility specification, which motivated the editor of this 661 | specification to write the introduction chapter discussing some 662 | real-world high value use cases that apply equally to this 663 | specification. Special thanks to all the participants of the Device 664 | APIs Working Group and others who have sent in substantial feedback and 665 | comments, and made the Web a better place for everyone by doing so. 666 | Finally, thanks to Lukasz Olejnik, Gunes Acar, Claude Castelluccia, and 667 | Claudia Diaz for the privacy analysis of the API. 668 |
669 |Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
428 |429 | The functionality described in this specification was initially 430 | specified as part of the 431 | System Information 432 | API but has been extracted in order to be more readily available, 433 | more straightforward to implement, and in order to produce a 434 | specification that could be implemented on its own merits without 435 | interference with other, often unrelated, features. 436 |
437 |This document was published by the Device APIs Working Group as a Candidate Recommendation. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-device-apis@w3.org (subscribe, archives). W3C publishes a Candidate Recommendation to indicate that the document is believed to be stable and to encourage implementation by the developer community. This Candidate Recommendation is expected to advance to Proposed Recommendation on 01 July 2012. All feedback is welcome.
Publication as a Candidate Recommendation does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
444 | The Battery Status API specification defines a means for web 445 | developers to programmatically determine the battery status of the 446 | hosting device. Without knowing the battery status of a device, a web 447 | developer must design the web application with an assumption of 448 | sufficient battery level for the task at hand. This means the battery 449 | of a device may exhaust faster than desired because web developers are 450 | unable to make decisions based on the battery status. Given knowledge 451 | of the battery status, web developers are able to craft web content and 452 | applications which are power-efficient, thereby leading to improved 453 | user experience. 454 |
455 |456 | The Battery Status API can be used to defer or scale back work when 457 | the device is not charging in or is low on battery. An archetype of an 458 | advanced web application, a web-based email client, may check the 459 | server for new email every few seconds if the device is charging, 460 | but do so less frequently if the device is not charging or is low on 461 | battery. Another example is a web-based word processor which could 462 | monitor the battery level and save changes before the battery runs 463 | out to prevent data loss. 464 |
465 |466 | The following example shows how a web-based email client could check 467 | for new emails every ten seconds without knowledge of the battery 468 | status: 469 |
470 |<!DOCTYPE html>471 |
<html>
<head>
<title>Email Client</title>
<script>
var mail = {
INTERVAL_DEFAULT: 1000 * 10,
interval: null,
timer: 0,
check: function () {
console.log('Checking the server for new emails using an interval of ' +
(mail.interval / 1000) + ' seconds.');
},
setTimer: function (interval) {
if (interval === mail.interval) { return; }
if (mail.timer !== 0) { clearTimeout(mail.timer); }
if (interval) { mail.timer = setInterval(function () { mail.check(); }, interval); }
mail.interval = interval;
}
};
window.addEventListener('load', function () {
mail.setTimer(!mail.interval ? mail.INTERVAL_DEFAULT : mail.interval);
}, false);
</script>
</head>
<body></body>
</html>
472 | The script will always check for emails every ten seconds, even if the 473 | battery level is critically low and the device is not charging. 474 | This is an example of poor resource management. 475 |
476 |
477 | Using the BatteryManager
interface, the web application is, for
478 | example, able to throttle checking for emails if the device is low on
479 | battery, stop checking for emails if the battery is critically low and
480 | resume normal operation when the battery is charging:
481 |
<!DOCTYPE html>483 |
<html>
<head>
<title>Battery-aware Email Client</title>
<script>
var mail = {
INTERVAL_BATTERY_LOW: 1000 * 60 * 10,
INTERVAL_DEFAULT: 1000 * 10,
interval: null,
timer: 0,
check: function () {
console.log('Checking the server for new emails using an interval of ' +
(mail.interval / 1000) + ' seconds.');
},
setTimer: function (interval) {
if (interval === mail.interval) { return; }
if (mail.timer !== 0) { clearTimeout(mail.timer); }
if (interval) { mail.timer = setInterval(function () { mail.check(); }, interval); }
mail.interval = interval;
}
};
window.addEventListener('load', function () {
mail.setTimer(!mail.interval ? mail.INTERVAL_DEFAULT : mail.interval);
}, false);
var battery = navigator.battery;
battery.addEventListener('dischargingtimechange', function () {
if (battery.dischargingTime < 60 * 30 || battery.level < 0.1) {
mail.setTimer(mail.INTERVAL_BATTERY_LOW);
console.log('30 minutes remaining or level below 10%, checking the server less frequently.');
} else if (battery.dischargingTime < 60 * 10 || battery.level < 0.05) {
mail.setTimer(null);
console.log('10 minutes remaining or level below 5%, stop checking the server.');
}
}, false);
battery.addEventListener('chargingchange', function () {
if (battery.charging) {
mail.setTimer(mail.INTERVAL_DEFAULT);
console.log('Battery is charging, checking the server normally.');
}
}, false);
</script>
</head>
<body></body>
</html>
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].
486 |487 | This specification defines conformance criteria that apply to a single 488 | product: the user agent that implements the 489 | interfaces that it contains. 490 |
491 |492 | Implementations that use ECMAScript to implement the APIs defined in 493 | this specification must implement them in a manner consistent with the 494 | ECMAScript Bindings defined in the Web IDL specification [WEBIDL], 495 | as this specification uses that specification and terminology. 496 |
497 |
501 | The
502 | Function
interface represents a function in the scripting
503 | language being used as defined in [HTML5].
504 |
506 | The concepts 507 | queue a task and 508 | 509 | fires a simple event are defined in [HTML5]. 510 |
511 |512 | The terms 513 | event handlers and 514 | 515 | event handler event types are defined in [HTML5]. 516 |
517 |521 | The API defined in this specification is used to determine the battery 522 | status of the hosting device. The information disclosed has minimal 523 | impact on privacy or fingerprinting, and therefore is exposed without 524 | permission grants. For example, authors cannot directly know if there 525 | is a battery or not in the hosting device. 526 |
527 |BatteryManager
Interface[NoInterfaceObject]
548 | interface BatteryManager : EventTarget {
549 | readonly attribute boolean charging;
550 | readonly attribute double chargingTime;
551 | readonly attribute double dischargingTime;
552 | readonly attribute double level;
553 | [TreatNonCallableAsNull]
554 | attribute Function? onchargingchange;
555 | [TreatNonCallableAsNull]
556 | attribute Function? onchargingtimechange;
557 | [TreatNonCallableAsNull]
558 | attribute Function? ondischargingtimechange;
559 | [TreatNonCallableAsNull]
560 | attribute Function? onlevelchange;
561 | };
562 |
charging
of type boolean, readonly chargingTime
of type double, readonly dischargingTime
of type double, readonly level
of type double, readonly
574 | When a BatteryManager
object is created,
575 | charging
must be set to true, chargingTime
576 | to 0, level
to 1.0 and dischargingTime
to
577 | the value positive Infinity, if the implementation is unable to report
578 | the battery's charging state, charging time, level or remaining time
579 | respectively.
580 |
582 | The charging
attribute must be set to false if the battery
583 | is discharging, and set to true, if the battery is charging, the
584 | implementation is unable to report the state, or there is no battery
585 | attached to the system, or otherwise. When the battery charging state
586 | is updated, the user agent must queue a task which sets
587 | the charging
attribute's value and fires a simple
588 | event named chargingchange
at the
589 | BatteryManager
object.
590 |
592 | The chargingTime
attribute must be set to 0, if the
593 | battery is full or there is no battery attached to the system, and to
594 | the value positive Infinity if the battery is discharging, the
595 | implementation is unable to report the remaining charging time, or
596 | otherwise. When the battery charging time is updated, the user
597 | agent must queue a task which sets the
598 | chargingTime
attribute's value and fires a simple
599 | event named chargingtimechange
at the
600 | BatteryManager
object.
601 |
603 | The dischargingTime
attribute must be set to the value
604 | positive Infinity, if the battery is charging, the implementation is
605 | unable to report the remaining discharging time, there is no battery
606 | attached to the system, or otherwise. When the battery discharging time
607 | is updated, the user agent must queue a task which sets
608 | the dischargingTime
attribute's value and fires a
609 | simple event named dischargingtimechange
at the
610 | BatteryManager
object.
611 |
613 | The level
attribute must be set to 0 if the system's
614 | battery is depleted and the system is about to be suspended, and to
615 | 1.0 if the battery is full, the implementation is unable to report the
616 | battery's level, or there is no battery attached to the system. When
617 | the battery level is updated, the user agent must queue a
618 | task which sets the level
attribute's value and
619 | fires a simple event named levelchange
at
620 | the BatteryManager
object.
621 |
chargingtimechange
,
624 | dischargingtimechange
, and levelchange
625 |
events are fired is left to the implementation.
626 |
630 | The following are the event handlers (and their corresponding
631 | event handler event types) that must be supported as
632 | attributes by the BatteryManager
object:
633 |
event handler | 638 |event handler event type | 639 |
---|---|
onchargingchange |
644 | chargingchange |
645 |
onchargingtimechange |
648 | chargingtimechange |
649 |
ondischargingtimechange |
652 | dischargingtimechange |
653 |
onlevelchange |
656 | levelchange |
657 |
666 | This trivial example writes the battery level to the console each time 667 | the level changes: 668 |
669 |navigator.battery.onlevelchange = function () {671 |
console.log(navigator.battery.level);
};
673 | Alternatively, the same using the addEventListener()
674 | method:
675 |
navigator.battery.addEventListener('levelchange', function () {678 |
console.log(navigator.battery.level);
}, false);
680 | The following example updates the indicators to show the charging 681 | state, level and time remaining in minutes: 682 |
683 |<!DOCTYPE html>685 |
<html>
<head>
<title>Battery Status API Example</title>
<script>
var battery = navigator.battery;
battery.onchargingchange = function () {
document.querySelector('#charging').textContent = battery.charging ? 'charging' : 'not charging';
};
battery.onlevelchange = function () {
document.querySelector('#level').textContent = battery.level;
};
battery.ondischargingtimechange = function () {
document.querySelector('#dischargingTime').textContent = battery.dischargingTime / 60;
};
</script>
</head>
<body>
<div id="charging">(charging state unknown)</div>
<div id="level">(battery level unknown)</div>
<div id="dischargingTime">(discharging time unknown)</div>
</body>
</html>
690 | The group is deeply indebted to Mounir Lamouri, Jonas Sicking, and 691 | the Mozilla WebAPI team in general for their invaluable feedback 692 | based on prototype implementations. Many thanks to the people behind 693 | the System Information API and Device Orientation Event specification 694 | for the initial inspiration. Also thanks to the nice folks bringing us 695 | the Page Visibility specification, which motivated the editor of this 696 | specification to write the introduction chapter discussing some 697 | real-world high value use cases that apply equally to this 698 | specification. Special thanks to all the participants of the Device 699 | APIs Working Group and others who have sent in substantial feedback 700 | and comments, and made the Web a better place for everyone by 701 | doing so. 702 |
703 |
433 |
434 |
435 |
436 |
437 |
438 |
483 | Copyright © 484 | 2014 485 | 486 | W3C® 487 | (MIT, 488 | ERCIM, 489 | Keio, Beihang), 490 | 491 | All Rights Reserved. 492 | 493 | W3C liability, 494 | trademark and 495 | 496 | document use 497 | 498 | rules apply. 499 |
500 | 501 | 502 |505 | This specification defines an API that provides information about the 506 | battery status of the hosting device. 507 |
512 | This section describes the status of this document at the time of its publication. 513 | Other documents may supersede this document. A list of current W3C publications and the 514 | latest revision of this technical report can be found in the W3C technical reports index at 515 | http://www.w3.org/TR/. 516 |
517 | 518 |519 | The functionality described in this specification was initially 520 | specified as part of the 521 | System Information 522 | API but has been extracted in order to be more readily available, 523 | more straightforward to implement, and in order to produce a 524 | specification that could be implemented on its own merits without 525 | interference with other, often unrelated, features. 526 |
527 |528 | No substantial changes have been made since the 529 | 530 | W3C Last Call Working Draft 28 August 2014 531 | (diff). 532 |
533 |534 | The CR exit criterion is two interoperable deployed implementations of 535 | each feature. No features are marked as 'at-risk'. 536 |
537 | 538 |This API uses EcmaScript promises, and as a result, relies on the second edition of WebIDL which has not yet started its path on the W3C Recommendation track. That dependency will need to be analysed before the document can make further progress.
539 | 540 |541 | This document was published by the Device APIs Working Group as a Candidate Recommendation. 542 | 543 | This document is intended to become a W3C Recommendation. 544 | 545 | 546 | If you wish to make comments regarding this document, please send them to 547 | public-device-apis@w3.org 548 | (subscribe, 549 | archives). 550 | 551 | 552 | 553 | W3C publishes a Candidate Recommendation to indicate that the document is believed to be 554 | stable and to encourage implementation by the developer community. This Candidate 555 | Recommendation is expected to advance to Proposed Recommendation no earlier than 556 | 03 February 2015. 557 | 558 | 559 | All comments are welcome. 560 | 561 |
562 | 563 |564 | Please see the Working Group's implementation 565 | report. 566 |
567 | 568 | 569 |570 | Publication as a Candidate Recommendation does not imply endorsement by the W3C 571 | Membership. This is a draft document and may be updated, replaced or obsoleted by other 572 | documents at any time. It is inappropriate to cite this document as other than work in 573 | progress. 574 |
575 | 576 | 577 | 578 |579 | 580 | This document was produced by a group operating under the 581 | 5 February 2004 W3C Patent 582 | Policy. 583 | 584 | 585 | 586 | 587 | W3C maintains a public list of any patent 588 | disclosures 589 | 590 | made in connection with the deliverables of the group; that page also includes 591 | instructions for disclosing a patent. An individual who has actual knowledge of a patent 592 | which the individual believes contains 593 | Essential 594 | Claim(s) must disclose the information in accordance with 595 | section 596 | 6 of the W3C Patent Policy. 597 | 598 | 599 |
600 | 601 |602 | This document is governed by the 14 October 2005 W3C Process Document. 603 |
604 | 605 | 606 | 607 | 608 | 609 |This section is non-normative.
615 |616 | The Battery Status API specification defines a means for web 617 | developers to programmatically determine the battery status of the 618 | hosting device. Without knowing the battery status of a device, a web 619 | developer must design the web application with an assumption of 620 | sufficient battery level for the task at hand. This means the battery 621 | of a device may exhaust faster than desired because web developers are 622 | unable to make decisions based on the battery status. Given knowledge 623 | of the battery status, web developers are able to craft web content and 624 | applications which are power-efficient, thereby leading to improved 625 | user experience. Authors should be aware, however, that a naïve 626 | implementation of this API can negatively affect the battery life. 627 |
628 |629 | The Battery Status API can be used to defer or scale back work when 630 | the device is not charging in or is low on battery. An archetype of an 631 | advanced web application, a web-based email client, may check the 632 | server for new email every few seconds if the device is charging, 633 | but do so less frequently if the device is not charging or is low on 634 | battery. Another example is a web-based word processor which could 635 | monitor the battery level and save changes before the battery runs 636 | out to prevent data loss. 637 |
638 |642 | As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, 643 | and notes in this specification are non-normative. Everything else in this specification is 644 | normative. 645 |
646 |The key words MUST, MUST NOT, and SHOULD are 647 | to be interpreted as described in [RFC2119]. 648 |
649 | 650 |651 | This specification defines conformance criteria that apply to a single 652 | product: the user agent that implements the 653 | interfaces that it contains. 654 |
655 |656 | Implementations that use ECMAScript to implement the APIs defined in 657 | this specification must implement them in a manner consistent with the 658 | ECMAScript Bindings defined in the Web IDL specification [WEBIDL2], 659 | as this specification uses that specification and terminology. 660 |
661 |665 | The following concepts, terms and interfaces are defined in [HTML5]: 666 |
667 |
669 | Navigator
671 | EventHandler
684 | 685 | Promise objects are defined in [ECMASCRIPT]. 686 |
687 |This section is non-normative.
690 |691 | The API defined in this specification is used to determine the battery 692 | status of the hosting device. The information disclosed has minimal 693 | impact on privacy or fingerprinting, and therefore is exposed without 694 | permission grants. For example, the user agent can obfuscate the 695 | exposed value in a way that authors cannot directly know if a hosting 696 | device has no battery, is charging or is exposing fake values. 697 |
698 |BatteryManager
interface
741 | The BatteryManager
interface represents the current battery
742 | status information of the hosting device. The charging
743 | attribute represents the charging state of the system's battery.
744 | The chargingTime
attribute represents the time remaining
745 | in seconds until the system's battery is fully charged. The
746 | dischargingTime
attribute represents the time remaining in
747 | seconds until the system's battery is completely discharged and the
748 | system is about to be suspended, and the level
attribute
749 | represents the level of the system's battery.
750 |
interface BatteryManager : EventTarget {
752 | readonly attribute boolean charging;
753 | readonly attribute unrestricted double chargingTime;
754 | readonly attribute unrestricted double dischargingTime;
755 | readonly attribute double level;
756 | attribute EventHandler onchargingchange;
757 | attribute EventHandler onchargingtimechange;
758 | attribute EventHandler ondischargingtimechange;
759 | attribute EventHandler onlevelchange;
760 | };
761 |
762 | When the user agent is to create a new
763 | BatteryManager
object, it MUST instantiate a new
764 | BatteryManager
object and set its attributes' values to those
765 | that represent the current battery status information, unless
766 | the user agent is unable to report the battery status
767 | information, in which case the values MUST be set to default
768 | values as follows:
769 | charging
MUST be set to true,
770 | chargingTime
MUST be set to 0,
771 | dischargingTime
MUST be set to positive Infinity, and
772 | level
MUST be set to 1.0.
773 |
775 | The user agent is said to be unable to report the 776 | battery status information, if it is not able to report the 777 | values for any of the attributes, for example, due to a user or system 778 | preference, setting, or limitation. 779 |
780 |781 | Implementations unable to report the battery status information 782 | emulate a fully charged and plugged in battery to reduce the potential 783 | for fingerprinting and prevent applications from degrading performance, 784 | if the battery status information is not made available, for example. 785 |
787 | The charging
788 | attribute MUST be set to false if the battery
789 | is discharging, and set to true, if the battery is charging, the
790 | implementation is unable to report the state, or there is no battery
791 | attached to the system, or otherwise. When the battery charging state
792 | is updated, the user agent MUST queue a task which sets
793 | the charging
attribute's value and fires a simple
794 | event named chargingchange
at the
795 | BatteryManager
object.
796 |
798 | The chargingTime
799 | attribute MUST be set to 0, if the
800 | battery is full or there is no battery attached to the system, and to
801 | the value positive Infinity if the battery is discharging, the
802 | implementation is unable to report the remaining charging time, or
803 | otherwise. When the battery charging time is updated, the user
804 | agent MUST queue a task which sets the
805 | chargingTime
attribute's value and fires a simple
806 | event named chargingtimechange
at the
807 | BatteryManager
object.
808 |
810 | The dischargingTime
811 | attribute MUST be set to the value
812 | positive Infinity, if the battery is charging, the implementation is
813 | unable to report the remaining discharging time, there is no battery
814 | attached to the system, or otherwise. When the battery discharging time
815 | is updated, the user agent MUST queue a task which sets
816 | the dischargingTime
attribute's value and fires a
817 | simple event named dischargingtimechange
at the
818 | BatteryManager
object.
819 |
821 | The level
822 | attribute MUST be set to 0 if the system's
823 | battery is depleted and the system is about to be suspended, and to
824 | 1.0 if the battery is full, the implementation is unable to report the
825 | battery's level, or there is no battery attached to the system. When
826 | the battery level is updated, the user agent MUST queue a
827 | task which sets the level
attribute's value and
828 | fires a simple event named levelchange
at
829 | the BatteryManager
object.
830 |
832 | The definition of how often the chargingtimechange
,
833 | dischargingtimechange
, and levelchange
834 |
events are fired is left to the implementation.
835 |
839 | If a hosting device contains more than one battery,
840 | BatteryManager
SHOULD expose an unified view of the batteries.
841 |
843 | The charging
attribute MUST be set to true if at least
844 | one battery's charging
state as described above is true.
845 | Otherwise, it MUST be set to false.
846 |
848 | The chargingTime
attribute can be set to the maximum
849 | charging time of the individual batteries if charging in parallel,
850 | and to the sum of the individual charging times if charging serially.
851 |
853 | The dischargingTime
attribute can be set to the maximum
854 | discharging time of the individual batteries if discharging in
855 | parallel, and to the sum of individual discharging times if
856 | discharging serially.
857 |
859 | The level
attribute can be set to the average of the
860 | levels of batteries of same capacity, or the weighted average of the
861 | battery level attributes for batteries of different capacities.
862 |
867 | The following are the event handlers (and their corresponding
868 | event handler event types) that MUST be supported as
869 | attributes by the BatteryManager
object:
870 |
event handler | 875 |event handler event type | 876 |
---|---|
881 |
882 | onchargingchange
883 |
884 | |
885 |
886 |
887 | chargingchange
888 |
889 | |
890 |
893 |
894 | onchargingtimechange
895 |
896 | |
897 |
898 |
899 | chargingtimechange
900 |
901 | |
902 |
905 |
906 | ondischargingtimechange
907 |
908 | |
909 |
910 |
911 | dischargingtimechange
912 |
913 | |
914 |
917 |
918 | onlevelchange
919 |
920 | |
921 |
922 |
923 | levelchange
924 |
925 | |
926 |
This section is non-normative.
934 |935 | This trivial example writes the battery level to the console each time 936 | the level changes: 937 |
938 |// We get the initial value when the promise resolves ... 939 | navigator.getBattery().then(function(battery) { 940 | console.log(battery.level); 941 | // ... and any subsequent updates. 942 | battery.onlevelchange = function() { 943 | console.log(this.level); 944 | }; 945 | });
947 | Alternatively, the same using the addEventListener()
948 | method:
949 |
navigator.getBattery().then(function(battery) { 951 | console.log(battery.level); 952 | battery.addEventListener('levelchange', function() { 953 | console.log(this.level); 954 | }); 955 | });
957 | The following example updates the indicators to show the charging 958 | state, level and time remaining in minutes: 959 |
960 |<!DOCTYPE html> 961 | <html> 962 | <head> 963 | <title>Battery Status API Example</title> 964 | <script> 965 | window.onload = function () { 966 | function updateBatteryStatus(battery) { 967 | document.querySelector('#charging').textContent = battery.charging ? 'charging' : 'not charging'; 968 | document.querySelector('#level').textContent = battery.level; 969 | document.querySelector('#dischargingTime').textContent = battery.dischargingTime / 60; 970 | } 971 | 972 | navigator.getBattery().then(function(battery) { 973 | // Update the battery status initially when the promise resolves ... 974 | updateBatteryStatus(battery); 975 | 976 | // .. and for any subsequent updates. 977 | battery.onchargingchange = function () { 978 | updateBatteryStatus(battery); 979 | }; 980 | 981 | battery.onlevelchange = function () { 982 | updateBatteryStatus(battery); 983 | }; 984 | 985 | battery.ondischargingtimechange = function () { 986 | updateBatteryStatus(battery); 987 | }; 988 | }); 989 | }; 990 | </script> 991 | </head> 992 | <body> 993 | <div id="charging">(charging state unknown)</div> 994 | <div id="level">(battery level unknown)</div> 995 | <div id="dischargingTime">(discharging time unknown)</div> 996 | </body> 997 | </html>
1002 | The group is deeply indebted to Mounir Lamouri, Jonas Sicking, and 1003 | the Mozilla WebAPI team in general for their invaluable feedback 1004 | based on prototype implementations. Many thanks to the people behind 1005 | the System Information API and Device Orientation Event specification 1006 | for the initial inspiration. Also thanks to the nice folks bringing us 1007 | the Page Visibility specification, which motivated the editor of this 1008 | specification to write the introduction chapter discussing some 1009 | real-world high value use cases that apply equally to this 1010 | specification. Special thanks to all the participants of the Device 1011 | APIs Working Group and others who have sent in substantial feedback 1012 | and comments, and made the Web a better place for everyone by 1013 | doing so. 1014 |
1015 |535 | Copyright © 536 | 2016 537 | 538 | W3C® 539 | (MIT, 540 | ERCIM, 541 | Keio, Beihang). 542 | W3C liability, 543 | trademark and 544 | document use 545 | rules apply. 546 |
547 |550 | This specification defines an API that provides information about the 551 | battery status of the hosting device. 552 |
554 | This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/. 555 |
556 | 557 |558 | No substantial changes have been made to the Battery Status API since 559 | the W3C Candidate 560 | Recommendation of December 2014 (diff) , 561 | however the document now has more detailed privacy considerations, 562 | including advice regarding the implications of high precision readouts, 563 | based on feedback from 564 | implementation experience. It also has updated references. 565 |
566 |567 | The implementation 568 | report of the API shows all features have been implemented by two 569 | independent deployed browsers, meeting the CR exit criteria. We had no 570 | CR features marked as 'at-risk'. 571 |
572 |573 | There is a known issue with some WebIDL implementations that are not 574 | specific to the Battery Status API; the interoperability effect of that 575 | issue is minimal, since it only affects error handling in case where 576 | the API is mis-used, which is in practice detected at development time 577 | rather than usage time. 578 |
579 | 580 |581 | This document was published by the Device APIs Working Group as a Proposed Recommendation. 582 | This document is intended to become a W3C Recommendation. 583 | 584 | The W3C Membership and other interested parties are invited to review the document and 585 | send comments to 586 | public-device-apis@w3.org 587 | (subscribe, 588 | archives) 589 | through 29 April 2016. Advisory Committee Representatives should consult their 590 | WBS questionnaires. 591 | Note that substantive technical comments were expected during the Last Call review 592 | period that ended 02 October 2014. 593 |
594 |595 | Please see the Working Group's implementation 596 | report. 597 |
598 |599 | Publication as a Proposed Recommendation does not imply endorsement by the W3C 600 | Membership. This is a draft document and may be updated, replaced or obsoleted by other 601 | documents at any time. It is inappropriate to cite this document as other than work in 602 | progress. 603 |
604 |605 | This document was produced by 606 | a group 607 | operating under the 608 | 5 February 2004 W3C Patent 609 | Policy. 610 | W3C maintains a public list of any patent 611 | disclosures 612 | made in connection with the deliverables of 613 | the group; that page also includes 614 | instructions for disclosing a patent. An individual who has actual knowledge of a patent 615 | which the individual believes contains 616 | Essential 617 | Claim(s) must disclose the information in accordance with 618 | section 619 | 6 of the W3C Patent Policy. 620 |
621 |622 | This document is governed by the 14 October 2005 W3C Process Document. 623 |
624 | 625 |This section is non-normative.
649 |650 | The Battery Status API specification defines a means for web developers 651 | to programmatically determine the battery status of the hosting device. 652 | Without knowing the battery status of a device, a web developer must 653 | design the web application with an assumption of sufficient battery 654 | level for the task at hand. This means the battery of a device may 655 | exhaust faster than desired because web developers are unable to make 656 | decisions based on the battery status. Given knowledge of the battery 657 | status, web developers are able to craft web content and applications 658 | which are power-efficient, thereby leading to improved user experience. 659 | Authors should be aware, however, that a naïve implementation of this 660 | API can negatively affect the battery life. 661 |
662 |663 | The Battery Status API can be used to defer or scale back work when the 664 | device is not charging in or is low on battery. An archetype of an 665 | advanced web application, a web-based email client, may check the 666 | server for new email every few seconds if the device is charging, but 667 | do so less frequently if the device is not charging or is low on 668 | battery. Another example is a web-based word processor which could 669 | monitor the battery level and save changes before the battery runs out 670 | to prevent data loss. 671 |
672 |675 | As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, 676 | and notes in this specification are non-normative. Everything else in this specification is 677 | normative. 678 |
679 |The key words MAY, MUST, MUST NOT, and SHOULD are 680 | to be interpreted as described in [RFC2119]. 681 |
682 | 683 |684 | This specification defines conformance criteria that apply to a single 685 | product: the user agent that implements the interfaces that 686 | it contains. 687 |
688 |689 | Implementations that use ECMAScript to implement the APIs defined in 690 | this specification must implement them in a manner consistent with the 691 | ECMAScript Bindings defined in the Web IDL specification [WEBIDL], 692 | as this specification uses that specification and terminology. 693 |
694 |700 | The following concepts, terms and interfaces are defined in [HTML5]: 701 |
702 |Navigator
705 | EventHandler
708 | 731 | 732 | Promise objects are defined in [ECMASCRIPT]. 733 |
734 |This section is non-normative.
739 |740 | The API defined in this specification is used to determine the battery 741 | status of the hosting device. 742 |
743 |744 | The user agent SHOULD not expose high precision readouts of battery 745 | status information as that can introduce a new fingerprinting vector. 746 |
747 |748 | The user agent MAY ask the user for battery status information access, 749 | or alternatively, enforce the user permission requirement in its 750 | private browsing modes. 751 |
752 |753 | The user agent SHOULD inform the user of the API use by scripts in an 754 | unobtrusive manner to aid transparency and to allow the user to revoke 755 | the API access. 756 |
757 |758 | The user agent MAY obfuscate the exposed value in a way that authors 759 | cannot directly know if a hosting device has no battery, is charging or 760 | is exposing fake values. 761 |
762 |BatteryManager
interface
803 |
805 | The BatteryManager
interface represents the current battery
806 | status information of the hosting device. The
807 | charging
attribute represents the charging state of the
808 | system's battery. The chargingTime
attribute represents
809 | the time remaining in seconds until the system's battery is fully
810 | charged. The dischargingTime
attribute represents the time
811 | remaining in seconds until the system's battery is completely
812 | discharged and the system is about to be suspended, and the
813 | level
attribute represents the level of the system's
814 | battery.
815 |
interface BatteryManager : EventTarget {
817 | readonly attribute boolean charging;
818 | readonly attribute unrestricted double chargingTime;
819 | readonly attribute unrestricted double dischargingTime;
820 | readonly attribute double level;
821 | attribute EventHandler onchargingchange;
822 | attribute EventHandler onchargingtimechange;
823 | attribute EventHandler ondischargingtimechange;
824 | attribute EventHandler onlevelchange;
825 | };
826 |
827 | When the user agent is to create a new
828 | BatteryManager
object, it MUST instantiate a new
829 | BatteryManager
object and set its attributes' values to those
830 | that represent the current battery status information, unless
831 | the user agent is unable to report the battery status
832 | information, in which case the values MUST be set to default
833 | values as follows: charging
MUST be set to true,
834 | chargingTime
MUST be set to 0,
835 | dischargingTime
MUST be set to positive Infinity, and
836 | level
MUST be set to 1.0.
837 |
839 | The user agent is said to be unable to report the battery 840 | status information, if it is not able to report the values for 841 | any of the attributes, for example, due to a user or system preference, 842 | setting, or limitation. 843 |
844 |845 | Implementations unable to report the battery status information 846 | emulate a fully charged and plugged in battery to reduce the potential 847 | for fingerprinting and prevent applications from degrading performance, 848 | if the battery status information is not made available, for example. 849 |
851 | The charging
attribute
852 | MUST be set to false if the battery is discharging, and set to true, if
853 | the battery is charging, the implementation is unable to report the
854 | state, or there is no battery attached to the system, or otherwise.
855 | When the battery charging state is updated, the user agent MUST
856 | queue a task which sets the charging
attribute's
857 | value and fires a simple event named
858 |
at the chargingchange
BatteryManager
object.
859 |
861 | The chargingTime
862 | attribute MUST be set to 0, if the battery is full or there is no
863 | battery attached to the system, and to the value positive Infinity if
864 | the battery is discharging, the implementation is unable to report the
865 | remaining charging time, or otherwise. When the battery charging time
866 | is updated, the user agent MUST queue a task which sets
867 | the chargingTime
attribute's value and fires a simple
868 | event named
at the
869 | chargingtimechange
BatteryManager
object.
870 |
872 | The dischargingTime
attribute
873 | MUST be set to the value positive Infinity, if the battery is charging,
874 | the implementation is unable to report the remaining discharging time,
875 | there is no battery attached to the system, or otherwise. When the
876 | battery discharging time is updated, the user agent MUST
877 | queue a task which sets the dischargingTime
878 | attribute's value and fires a simple event named
879 |
at the dischargingtimechange
BatteryManager
880 | object.
881 |
883 | The level
attribute MUST be
884 | set to 0 if the system's battery is depleted and the system is about to
885 | be suspended, and to 1.0 if the battery is full, the implementation is
886 | unable to report the battery's level, or there is no battery attached
887 | to the system. When the battery level is updated, the user agent
888 | MUST queue a task which sets the level
attribute's
889 | value and fires a simple event named
890 |
at the levelchange
BatteryManager
object.
891 |
893 | The definition of how often the
,
894 | chargingtimechange
, and
895 | dischargingtimechange
events are fired is left to the
896 | implementation.
897 | levelchange
903 | If a hosting device contains more than one battery,
904 | BatteryManager
SHOULD expose an unified view of the batteries.
905 |
907 | The charging
attribute MUST be set to true if at least
908 | one battery's charging
state as described above is true.
909 | Otherwise, it MUST be set to false.
910 |
912 | The chargingTime
attribute can be set to the maximum
913 | charging time of the individual batteries if charging in parallel,
914 | and to the sum of the individual charging times if charging serially.
915 |
917 | The dischargingTime
attribute can be set to the maximum
918 | discharging time of the individual batteries if discharging in
919 | parallel, and to the sum of individual discharging times if
920 | discharging serially.
921 |
923 | The level
attribute can be set to the average of the
924 | levels of batteries of same capacity, or the weighted average of the
925 | battery level attributes for batteries of different capacities.
926 |
933 | The following are the event handlers (and their corresponding
934 | event handler event types) that MUST be supported as
935 | attributes by the BatteryManager
object:
936 |
941 | event handler 942 | | 943 |944 | event handler event type 945 | | 946 |
---|---|
951 | onchargingchange
952 | |
953 |
954 | chargingchange
955 | |
956 |
959 | onchargingtimechange
960 | |
961 |
962 | chargingtimechange
963 | |
964 |
967 | ondischargingtimechange
968 | |
969 |
970 | dischargingtimechange
971 | |
972 |
975 | onlevelchange
976 | |
977 |
978 | levelchange
979 | |
980 |
This section is non-normative.
989 |990 | This trivial example writes the battery level to the console each time 991 | the level changes: 992 |
993 |// We get the initial value when the promise resolves ... 994 | navigator.getBattery().then(function(battery) { 995 | console.log(battery.level); 996 | // ... and any subsequent updates. 997 | battery.onlevelchange = function() { 998 | console.log(this.level); 999 | }; 1000 | });
1002 | Alternatively, the same using the addEventListener()
1003 | method:
1004 |
navigator.getBattery().then(function(battery) { 1006 | console.log(battery.level); 1007 | battery.addEventListener('levelchange', function() { 1008 | console.log(this.level); 1009 | }); 1010 | });
1012 | The following example updates the indicators to show the charging 1013 | state, level and time remaining in minutes: 1014 |
1015 |<!DOCTYPE html> 1016 | <html> 1017 | <head> 1018 | <title>Battery Status API Example</title> 1019 | <script> 1020 | window.onload = function () { 1021 | function updateBatteryStatus(battery) { 1022 | document.querySelector('#charging').textContent = battery.charging ? 'charging' : 'not charging'; 1023 | document.querySelector('#level').textContent = battery.level; 1024 | document.querySelector('#dischargingTime').textContent = battery.dischargingTime / 60; 1025 | } 1026 | 1027 | navigator.getBattery().then(function(battery) { 1028 | // Update the battery status initially when the promise resolves ... 1029 | updateBatteryStatus(battery); 1030 | 1031 | // .. and for any subsequent updates. 1032 | battery.onchargingchange = function () { 1033 | updateBatteryStatus(battery); 1034 | }; 1035 | 1036 | battery.onlevelchange = function () { 1037 | updateBatteryStatus(battery); 1038 | }; 1039 | 1040 | battery.ondischargingtimechange = function () { 1041 | updateBatteryStatus(battery); 1042 | }; 1043 | }); 1044 | }; 1045 | </script> 1046 | </head> 1047 | <body> 1048 | <div id="charging">(charging state unknown)</div> 1049 | <div id="level">(battery level unknown)</div> 1050 | <div id="dischargingTime">(discharging time unknown)</div> 1051 | </body> 1052 | </html>
1059 | The group is deeply indebted to Mounir Lamouri, Jonas Sicking, and the 1060 | Mozilla WebAPI team in general for their invaluable feedback based on 1061 | prototype implementations. Many thanks to the people behind the System 1062 | Information API and Device Orientation Event specification for the 1063 | initial inspiration. Also thanks to the nice folks bringing us the Page 1064 | Visibility specification, which motivated the editor of this 1065 | specification to write the introduction chapter discussing some 1066 | real-world high value use cases that apply equally to this 1067 | specification. Special thanks to all the participants of the Device 1068 | APIs Working Group and others who have sent in substantial feedback and 1069 | comments, and made the Web a better place for everyone by doing so. 1070 | Finally, thanks to Lukasz Olejnik, Gunes Acar, Claude Castelluccia, and 1071 | Claudia Diaz for the privacy analysis of the API. 1072 |
1073 |