├── .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 |
23 | 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 |
44 | 45 | ## Non-goals 46 | 47 | - Allow the script to toggle the power saving mode. 48 | 49 | - Expose the battery level. This requirement is already addressed by the existing [Battery Status API](https://www.w3.org/TR/battery-status/). The proposed API will work together with the Battery Status API, but also addresses many use cases on its own. 50 | 51 | ## User research 52 | 53 | A [research paper](https://www.researchgate.net/publication/341123776_Investigating_the_Correlation_between_Performance_Scores_and_Energy_Consumption_of_Mobile_Web_Apps) discovered a statistically significant negative correlation between performance scores and energy consumption of mobile web apps. The results from a controlled experiment involving 21 real third-party web app implies that an increase in the performance score tends to lead to a decrease in energy consumption. 54 | 55 | Many tools exists for optimizing the initial page load performance. For example, Google’s [Lighthouse](https://developer.chrome.com/docs/lighthouse/), [PageSpeed Insights](https://pagespeed.web.dev/) and guidance from [Core Web Vitals](https://web.dev/vitals/) provide insights for improving the user experience of the initial load. 56 | 57 | This demonstrates that performance optimization of web apps is a well-understood craft with many tools and APIs available to assist web authors. However, explicit energy efficiency optimizations have been left as an implementation detail of the browser, at most exposed through the _browser settings_ to users, see e.g. [Chrome Energy Saver](https://blog.google/products/chrome/new-chrome-features-to-save-battery-and-make-browsing-smoother/) and [Edge Efficiency Mode](https://techcommunity.microsoft.com/t5/articles/efficiency-mode-in-microsoft-edge-save-even-more-battery-life/m-p/3651853). Such optimizations in the browser implementation, however, while useful, cannot take into account the context-sensitive requirements of web apps. This limits the optimization opportunity space in browser implementation to operations that are not time or context sensitive. For example, the browser can batch or delay push message delivery because it is [specified](https://www.w3.org/TR/push-api/) they can be sent at any time. On the other hand, the browser cannot know whether it can disable [transparency in canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas#turn_off_transparency) since it can be crucial to the user experience. 58 | 59 | Because energy-saving measures often have a user visible impact, anecdotal evidence suggests web authors tend to optimize for a better user experience over energy efficiency. Web authors are also lacking tools to measure the energy use and APIs to understand when energy-efficient operation is acceptable, or desired. This explainer discusses the latter problem and explores possible solutions to it. 60 | 61 | All major desktop and mobile OSes have integrated energy saver mode features that are under the user's control. Arguably users are already trained to understand the impact on the user experience of such a feature: users' expectations are lowered and more modest UX is accepted when such a mode is enabled. 62 | 63 |
64 | 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 |
77 | 78 | 79 | ## Detailed design discussion 80 | 81 | ### Energy consumption timeline 82 | 83 | The tools and best practices discussed in [user research](#user-research) are focused on optimizations _during the initial load_. Lighthouse, for example, measures performance metrics such as _First Contentful Paint_, _Time to interactive_ and _First CPU Idle_. These are events that happen early in the lifetime of the webpage, before the [current document readiness](https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness) is "complete". As discussed, these optimizations will, by proxy, often lead to lower energy use too. 84 | 85 | However, the overall energy consumption after the initial load (when the current document readiness is "complete") is more significant (TODO: add data) for a long-running web experience. Such experiences are often implemented following an architectural patterns called [single-page application](https://en.wikipedia.org/wiki/Single-page_application) (SPA) popularized by major [JavaScript frameworks](https://en.wikipedia.org/wiki/Single-page_application#JavaScript_frameworks). SPA is also a [preferred architectural pattern](https://web.dev/learn/pwa/architecture/) for progressive web applications (PWA) with mostly atomic in-page updates. 86 | 87 | This unearths an impactful opportunity to change these JS frameworks' behavior to be more energy efficient: SPAs in particular benefit from runtime energy efficiency optimization that lower the overall energy consumption _during the entire lifetime_ of the web application and not just during the initial load. 88 | 89 | ### Energy saving strategies for web applications 90 | 91 | A number of energy saving strategies are implementation details of the *web app* and context sensitive. That is, the browser implementation cannot apply these optimizations without breaking the UX. This implies the energy saver mode state information must be exposed to web apps to enable these highly application-specific and context-sensitive energy optimizations. 92 | 93 |
94 | 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 |
114 | 115 | 116 | 117 | ## Operating system APIs and the native-land 118 | 119 | All major OSes provide user controls to toggle "Energy Saving Mode" state or equivalent: [Windows](https://support.microsoft.com/en-us/windows/battery-saving-tips-for-windows-a850d64d-ee8e-c8d2-6c75-8ffe6ea3ea99), [Chrome(OS)](https://blog.google/products/chrome/new-chrome-features-to-save-battery-and-make-browsing-smoother/#ug3p3), [macOS](https://support.apple.com/en-gb/guide/mac-help/mh35848/mac#mchlp7877a91), [Android (various)](https://support.google.com/android/answer/7664692#zippy=%2Cturn-on-battery-saver-or-low-power-mode) and [iOS](https://support.apple.com/en-us/HT205234). 120 | 121 | This state information is also exposed to native app developers through native APIs, for example: 122 | - Android [isPowerSaveMode](https://developer.android.com/reference/android/os/PowerManager#isPowerSaveMode()) boolean 123 | - Windows [EffectivePowerMode*](https://learn.microsoft.com/en-us/windows/win32/api/powersetting/ne-powersetting-effective_power_mode) enum values 124 | - macOS and iOS [lowPowerModeEnabled](https://developer.apple.com/documentation/foundation/nsprocessinfo/1617047-lowpowermodeenabled) boolean 125 | 126 | These native APIs are arguably exposed to native apps, since the OS cannot act on behalf of native apps to apply context-sensitive optimizations. Similarly, the browser cannot act on behalf of web applications to enable similar optimization. The browser can however, similarly to the OS, enable generic optimizations such as suspend inactive background tabs or reduce the framerate of [animation frame](https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering) generation. These browser-level optimizations are complementary to the application-level optimizations. 127 | 128 | ## Considered alternatives 129 | 130 | ### Proposed new API 131 | 132 | The closest existing interface to extend would be the `BatteryManager` to allow these two APIs to interact in advanced use cases. A simple event (`energysavingmodechange`) and boolean (`battery.energySavingMode`) pair may be sufficient to enable the majority of the use cases. 133 | 134 | ``` 135 | let b = await navigator.getBattery(); 136 | 137 | if (b.energySaverMode) { 138 | saveEnergy(); 139 | } 140 | 141 | b.energysavermodechange = () => { 142 | if (this.energySaverMode) saveEnergy(); 143 | } 144 | ``` 145 | 146 | This API could hang off of its own interface if future extensibility is expected. Or if we expect implementers to support only this API and not the rest of the `BatteryManager`, or if we want to permission-gate the two APIs separately. 147 | 148 | ### New metadata element attribute "battery-savings" 149 | 150 | If a site wanted to allow reduced framerate if it saved battery, they would add this to their page: 151 | 152 | ``` 153 | 154 | ``` 155 | If a site wanted to allow generic slowdown of script execution: 156 | 157 | ``` 158 | 159 | ``` 160 | 161 | Source: [Explainer: web page settings to save battery](https://github.com/chrishtr/battery-savings/blob/master/explainer.md) 162 | 163 | ### New HTTP header "Save-Energy" network client hint 164 | 165 | A new HTTP header similar to [`Save-Data: on`](https://wicg.github.io/savedata/#save-data-request-header-field): 166 | 167 | ``` 168 | GET /document HTTP/2 169 | Host: www.example.com 170 | Accept-Encoding: * 171 | Save-Energy: On 172 | ``` 173 | 174 | Source: [Power-saving detection / coarser low-power insights](https://github.com/WebKit/explainers/issues/47) 175 | 176 | ### New CSS media query "prefers-energy-saving" 177 | 178 | A new CSS media feature "prefers-energy-saving" similar to ["prefers-reduced-data"](https://www.w3.org/TR/mediaqueries-5/#prefers-reduced-data). 179 | 180 | The prefers-energy-saving media feature could be used to detect if the user has a preference for being served energy saving content that uses less energy for the page to be rendered. 181 | 182 | ``` 183 | .image { 184 | background-image: url("images/heavy.jpg"); 185 | } 186 | 187 | @media (prefers-energy-saving: reduce) { 188 | .image { 189 | background-image: url("images/light.jpg"); 190 | } 191 | } 192 | ``` 193 | 194 | Source: https://github.com/w3c/battery/issues/9#issuecomment-657527653 195 | 196 | 197 | ## Stakeholder Feedback / Opposition 198 | 199 | - WebKit: https://github.com/WebKit/explainers/issues/47 200 | 201 | ## References & acknowledgements 202 | 203 | Many thanks for valuable feedback and advice from: 204 | 205 | - Peter Beverloo 206 | - J. S. Choi 207 | - Gilles Dubuc 208 | - Robert Linder 209 | - Sangwhan Moon 210 | - Luc Potage 211 | - Noam Rosenthal 212 | - Joseph Scott 213 | - Jimmy Wärting 214 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Battery Status API 6 | 7 | 8 | 10 | 53 | 54 | 55 |
56 | This specification defines an API that provides information about the 57 | battery status of the hosting device. 58 |
59 |
60 |

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 |
69 |
70 |

71 | Introduction 72 |

73 |

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 |
97 |
98 |

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 |
104 |
105 |

106 | Security and privacy considerations 107 |

108 |

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 |
132 |
133 |

134 | Concepts 135 |

136 |

137 | The task source for the tasks mentioned in this 138 | specification is the battery status task source. 139 |

140 |
141 |
142 |

143 | Extensions to the `Navigator` interface 144 |

145 |
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 |
156 |

157 | Internal slots 158 |

159 | 160 | 161 | 162 | 165 | 168 | 171 | 172 | 173 | 174 | 175 | 178 | 181 | 184 | 185 | 186 | 189 | 192 | 197 | 198 | 199 |
163 | Internal slot 164 | 166 | Initial value 167 | 169 | Description 170 |
176 | [[\BatteryPromise]] 177 | 179 | `null` 180 | 182 | A {{Promise}} returned by calls to {{Navigator/getBattery()}}. 183 |
187 | [[\BatteryManager]] 188 | 190 | `null` 191 | 193 | The {{BatteryManager}} instance associated with a given 194 | {{Navigator}} after it has been created via 195 | {{Navigator/getBattery()}}. 196 |
200 |
201 |
202 |

203 | The `getBattery()` method 204 |

205 |

207 | The getBattery() method steps are: 208 |

209 |
    210 |
  1. If [=this=].{{Navigator/[[BatteryPromise]]}} is `null`, then set 211 | it to [=a new promise=] in [=this=]'s [=relevant realm=]. 212 |
  2. 213 |
  3. If [=this=]'s [=relevant global object=]'s [=associated 214 | `Document`=] is not [=allowed to use=] the "`battery`" 215 | [=policy-controlled feature=], then [=reject=] 216 | [=this=].{{Navigator/[[BatteryPromise]]}} with a 217 | {{"NotAllowedError"}} {{DOMException}}. 218 |
  4. 219 |
  5. Otherwise: 220 |
      221 |
    1. If [=this=].{{Navigator/[[BatteryManager]]}} is `null`, then 222 | set it to the result of creating a [=new=] {{BatteryManager}} in 223 | [=this=]'s [=relevant realm=]. 224 |
    2. 225 |
    3. [=Resolve=] [=this=].{{Navigator/[[BatteryPromise]]}} with 226 | [=this=].{{Navigator/[[BatteryManager]]}}. 227 |
    4. 228 |
    229 |
  6. 230 |
  7. Return [=this=].{{Navigator/[[BatteryPromise]]}}. 231 |
  8. 232 |
233 |
234 |
235 |
236 |

237 | The `BatteryManager` interface 238 |

239 |
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 |
271 |

272 | Internal slots 273 |

274 |

275 | {{BatteryManager}} instances are created with the following 276 | internal 278 | slots: 279 |

280 | 281 | 282 | 283 | 286 | 289 | 290 | 291 | 292 | 293 | 296 | 299 | 300 | 301 | 304 | 307 | 308 | 309 | 312 | 315 | 316 | 317 | 320 | 323 | 324 | 325 |
284 | Internal slot 285 | 287 | Initial value 288 |
294 | [[\Charging]] 295 | 297 | `true` 298 |
302 | [[\ChargingTime]] 303 | 305 | 0 306 |
310 | [[\DischargingTime]] 311 | 313 | Positive Infinity 314 |
318 | [[\Level]] 319 | 321 | 1.0 322 |
326 |
327 |

328 | The `[[Charging]]` internal slot 329 |

330 |

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 |
345 |
346 |

347 | The `[[ChargingTime]]` internal slot 348 |

349 |

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 |
364 |
365 |

366 | The `[[DischargingTime]]` internal slot 367 |

368 |

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 |
383 |
384 |

385 | The `[[Level]]` internal slot 386 |

387 |

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 |
401 |

402 | The definition of how often the "[=chargingtimechange=]", 403 | "[=dischargingtimechange=]", and "[=levelchange=]" events are fired 404 | is left to the implementation. 405 |

406 |
407 |
408 |

409 | The `charging` attribute 410 |

411 |

412 | The charging getter steps are to return 413 | [=this=].{{BatteryManager/[[Charging]]}}. 414 |

415 |
416 |
417 |

418 | The `chargingTime` attribute 419 |

420 |

421 | The chargingTime getter steps are to return 422 | [=this=].{{BatteryManager/[[ChargingTime]]}}. 423 |

424 |
425 |
426 |

427 | The `dischargingTime` attribute 428 |

429 |

430 | The dischargingTime getter steps are to return 431 | [=this=].{{BatteryManager/[[DischargingTime]]}}. 432 |

433 |
434 |
435 |

436 | The `level` attribute 437 |

438 |

439 | The level getter steps are to return 440 | [=this=].{{BatteryManager/[[Level]]}}. 441 |

442 |
443 |
444 |

445 | Event handlers 446 |

447 |

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 | 453 | 454 | 455 | 458 | 461 | 462 | 463 | 464 | 465 | 468 | 471 | 472 | 473 | 476 | 479 | 480 | 481 | 484 | 487 | 488 | 489 | 492 | 495 | 496 | 497 |
456 | event handler 457 | 459 | event handler event type 460 |
466 | onchargingchange 467 | 469 | `chargingchange` 470 |
474 | onchargingtimechange 475 | 477 | `chargingtimechange` 478 |
482 | ondischargingtimechange 483 | 485 | `dischargingtimechange` 486 |
490 | onlevelchange 491 | 493 | `levelchange` 494 |
498 |
499 |
500 |

501 | Algorithms 502 |

503 |

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 |
    508 |
  1. Let |global| be the [=current global object=]. 509 |
  2. 510 |
  3. If |global| is not a {{Window}}, abort these steps. 511 |
  4. 512 |
  5. Let |navigator:Navigator| be |global|'s associated {{Navigator}}. 513 |
  6. 514 |
  7. Let |batteryManager:BatteryManager| be the value of |navigator|. 515 | {{Navigator/[[BatteryManager]]}}. 516 |
  8. 517 |
  9. If |batteryManager| is `null`, abort these steps. 518 |
  10. 519 |
  11. [=Queue a global task=] on the [=battery status task source=] 520 | given |global| to run the following steps: 521 |
      522 |
    1. Set |batteryManager|.|slot| to |value|. 523 |
    2. 524 |
    3. [=Fire an event=] named |eventName| at |batteryManager|. 525 |
    4. 526 |
    527 |
  12. 528 |
529 |
530 |
531 |

532 | Multiple batteries 533 |

534 |

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 |
561 |
562 |
563 |

564 | Permissions Policy integration 565 |

566 |

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 |

572 |
573 |
574 |

575 | Examples 576 |

577 |

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 |

595 |
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 |
648 |
649 |
650 |
651 |

652 | Acknowledgements 653 |

654 |

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 |
670 | 671 | 672 | -------------------------------------------------------------------------------- /releases/CR.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Battery Status API 5 | 6 | 7 | 8 | 423 |

W3C

Battery Status API

W3C Candidate Recommendation 08 May 2012

This Version:
http://www.w3.org/TR/2012/CR-battery-status-20120508/
Latest Published Version:
http://www.w3.org/TR/battery-status/
Latest Editor's Draft:
http://dvcs.w3.org/hg/dap/raw-file/tip/battery/Overview.html
Previous version:
http://www.w3.org/TR/2011/WD-battery-status-20111129/
Editors:
Anssi Kostiainen, Nokia
Mounir Lamouri, Mozilla

424 |

Abstract

425 | This specification defines an API that provides information about the 426 | battery status of the hosting device. 427 |

Status of This Document

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.

Table of Contents

438 | 439 | 440 | 441 |
442 |

1. Introduction

This section is non-normative. 443 |

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>
<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>
471 |

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 |

482 |
<!DOCTYPE html>
<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>
483 |
484 | 485 |

2. Conformance

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 |
498 |
499 |

3. Terminology

500 |

501 | The 502 | Function interface represents a function in the scripting 503 | language being used as defined in [HTML5]. 504 |

505 |

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 |
518 |
519 |

4. Security and privacy considerations

520 |

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 |
528 | 544 | 545 |
546 |

6. BatteryManager Interface

547 |
[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 | 

6.1 Attributes

charging of type boolean, readonly
563 | Represents if the system's battery is charging. 564 |
No exceptions.
chargingTime of type double, readonly
565 | Represents the time remaining in seconds until the system's battery 566 | is fully charged. 567 |
No exceptions.
dischargingTime of type double, readonly
568 | Represents the time remaining in seconds until the system's battery 569 | is completely discharged and the system is about to be suspended. 570 |
No exceptions.
level of type double, readonly
571 | Represents the current battery level scaled from 0 to 1.0. 572 |
No exceptions.
573 |

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 |

581 |

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 |

591 |

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 |

602 |

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 |

612 |

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 |

622 |
623 | The definition of how often the chargingtimechange, 624 | dischargingtimechange, and levelchange 625 | events are fired is left to the implementation. 626 |
627 |
628 |

6.2 Event handlers

629 |

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 |

634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 |
event handlerevent handler event type
onchargingchangechargingchange
onchargingtimechangechargingtimechange
ondischargingtimechangedischargingtimechange
onlevelchangelevelchange
660 |
661 |
662 | 663 |
664 |

7. Examples

This section is non-normative. 665 |

666 | This trivial example writes the battery level to the console each time 667 | the level changes: 668 |

669 |
670 |
navigator.battery.onlevelchange = function () {
  console
.log(navigator.battery.level);
};
671 |
672 |

673 | Alternatively, the same using the addEventListener() 674 | method: 675 |

676 |
677 |
navigator.battery.addEventListener('levelchange', function () {
  console
.log(navigator.battery.level);
}, false);
678 |
679 |

680 | The following example updates the indicators to show the charging 681 | state, level and time remaining in minutes: 682 |

683 |
684 |
<!DOCTYPE html>
<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>
685 |
686 |
687 |
688 |

A. Acknowledgements

689 |

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 |
704 | 705 | 706 |

B. References

B.1 Normative references

[HTML5]
Ian Hickson, David Hyatt. 707 | 708 | HTML 5. 709 | 4 March 2010. 710 | W3C Working Draft. 711 | 712 | URL: http://www.w3.org/TR/2010/WD-html5-20100304/
[RFC2119]
S. Bradner. 713 | 714 | Key words for use in RFCs to Indicate Requirement Levels. 715 | March 1997. 716 | Internet RFC 2119. 717 | (Work in progress.) 718 | URL: http://www.ietf.org/rfc/rfc2119.txt
[WEBIDL]
Cameron McCormack. 719 | 720 | Web IDL. 721 | 19 December 2008. 722 | W3C Working Draft. 723 | 724 | URL: http://www.w3.org/TR/2008/WD-WebIDL-20081219
-------------------------------------------------------------------------------- /releases/CR2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Battery Status API 5 | 6 | 7 | 8 | 431 | 504 |

Abstract

505 | This specification defines an API that provides information about the 506 | battery status of the hosting device. 507 |

Status of This Document

508 | 509 | 510 | 511 |

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 |

Table of Contents

610 | 611 | 612 | 613 |
614 |

1. Introduction

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 |
639 | 640 |

2. Conformance

641 |

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 |
662 |
663 |

3. Terminology

664 |

665 | The following concepts, terms and interfaces are defined in [HTML5]: 666 |

667 | 683 |

684 | 685 | Promise objects are defined in [ECMASCRIPT]. 686 |

687 |
688 |
689 |

4. Security and privacy considerations

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 |
699 |
700 |

5. The Navigator interface

701 |
partial interface Navigator {
 702 |     Promise<BatteryManager> getBattery ();
 703 | };
704 |

705 | For each browsing context, there is a battery promise, 706 | which is initially set to null. It is a Promise 707 | object which holds a BatteryManager. 708 |

709 |

710 | The getBattery() 711 | method, when invoked, MUST run the following steps: 712 |

713 | 733 |

734 | The user agent MUST NOT reject the battery promise. 735 |

736 |
737 | 738 |
739 |

6. The BatteryManager interface

740 |

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 |

751 |
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 |

774 |

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 |
Note

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 |

786 |

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 |

797 |

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 |

809 |

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 |

820 |

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 |

831 |
Note

832 | The definition of how often the chargingtimechange, 833 | dischargingtimechange, and levelchange 834 | events are fired is left to the implementation. 835 |

836 |
837 |

6.1 Multiple batteries

838 |

839 | If a hosting device contains more than one battery, 840 | BatteryManager SHOULD expose an unified view of the batteries. 841 |

842 |

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 |

847 |

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 |

852 |

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 |

858 |

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 |

863 |
864 |
865 |

6.2 Event handlers

866 |

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 |

871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 885 | 890 | 891 | 892 | 897 | 902 | 903 | 904 | 909 | 914 | 915 | 916 | 921 | 926 | 927 | 928 |
event handlerevent handler event type
881 | 882 | onchargingchange 883 | 884 | 886 | 887 | chargingchange 888 | 889 |
893 | 894 | onchargingtimechange 895 | 896 | 898 | 899 | chargingtimechange 900 | 901 |
905 | 906 | ondischargingtimechange 907 | 908 | 910 | 911 | dischargingtimechange 912 | 913 |
917 | 918 | onlevelchange 919 | 920 | 922 | 923 | levelchange 924 | 925 |
929 |
930 |
931 | 932 |
933 |

7. Examples

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 |
Example 1
// 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 | });
946 |

947 | Alternatively, the same using the addEventListener() 948 | method: 949 |

950 |
Example 2
navigator.getBattery().then(function(battery) {
 951 |   console.log(battery.level);
 952 |   battery.addEventListener('levelchange', function() {
 953 |     console.log(this.level);
 954 |   });
 955 | });
956 |

957 | The following example updates the indicators to show the charging 958 | state, level and time remaining in minutes: 959 |

960 |
Example 3
<!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>
998 |
999 |
1000 |

A. Acknowledgements

1001 |

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 |
1016 | 1017 | 1018 |

B. References

B.1 Normative references

[ECMASCRIPT]
Allen Wirfs-Brock. ECMA-262 ECMAScript Language Specification, Edition 6. Draft. URL: http://people.mozilla.org/~jorendorff/es6-draft.html 1019 |
[HTML5]
Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. HTML5. 28 October 2014. W3C Recommendation. URL: http://www.w3.org/TR/html5/ 1020 |
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119 1021 |
[WEBIDL2]
Cameron McCormack. Web IDL (Second Edition). 13 November 2014. Editor’s Draft. URL: http://heycam.github.io/webidl/ 1022 |
1023 | -------------------------------------------------------------------------------- /releases/PR.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Battery Status API 6 | 7 | 8 | 9 | 10 | 506 | 549 |

Abstract

550 | This specification defines an API that provides information about the 551 | battery status of the hosting device. 552 |

Status of This Document

553 |

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 |
644 | 645 |
646 |

1. 647 | Introduction 648 |

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 |
673 |

2. Conformance

674 |

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 |
695 |
696 |

3. 697 | Terminology 698 |

699 |

700 | The following concepts, terms and interfaces are defined in [HTML5]: 701 |

702 | 730 |

731 | 732 | Promise objects are defined in [ECMASCRIPT]. 733 |

734 |
735 |
736 |

4. 737 | Security and privacy considerations 738 |

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 |
763 |
764 |

5. 765 | The Navigator interface 766 |

767 |
partial interface Navigator {
 768 |     Promise<BatteryManager> getBattery ();
 769 | };
770 |

771 | For each browsing context, there is a battery 772 | promise, which is initially set to null. It is a 773 | Promise object which holds a BatteryManager. 774 |

775 |

776 | The getBattery() 777 | method, when invoked, MUST run the following steps: 778 |

779 | 796 |

797 | The user agent MUST NOT reject the battery promise. 798 |

799 |
800 |
801 |

6. 802 | The BatteryManager interface 803 |

804 |

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 |

816 |
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 |

838 |

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 |
Note

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 |

850 |

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 | chargingchange at the BatteryManager object. 859 |

860 |

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 chargingtimechange at the 869 | BatteryManager object. 870 |

871 |

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 | dischargingtimechange at the BatteryManager 880 | object. 881 |

882 |

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 | levelchange at the BatteryManager object. 891 |

892 |
Note

893 | The definition of how often the chargingtimechange, 894 | dischargingtimechange, and 895 | levelchange events are fired is left to the 896 | implementation. 897 |

898 |
899 |

6.1 900 | Multiple batteries 901 |

902 |

903 | If a hosting device contains more than one battery, 904 | BatteryManager SHOULD expose an unified view of the batteries. 905 |

906 |

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 |

911 |

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 |

916 |

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 |

922 |

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 |

927 |
928 |
929 |

6.2 930 | Event handlers 931 |

932 |

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 |

937 | 938 | 939 | 940 | 943 | 946 | 947 | 948 | 949 | 950 | 953 | 956 | 957 | 958 | 961 | 964 | 965 | 966 | 969 | 972 | 973 | 974 | 977 | 980 | 981 | 982 |
941 | event handler 942 | 944 | event handler event type 945 |
951 | onchargingchange 952 | 954 | chargingchange 955 |
959 | onchargingtimechange 960 | 962 | chargingtimechange 963 |
967 | ondischargingtimechange 968 | 970 | dischargingtimechange 971 |
975 | onlevelchange 976 | 978 | levelchange 979 |
983 |
984 |
985 |
986 |

7. 987 | Examples 988 |

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 |
Example 1
// 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 | });
1001 |

1002 | Alternatively, the same using the addEventListener() 1003 | method: 1004 |

1005 |
Example 2
navigator.getBattery().then(function(battery) {
1006 |   console.log(battery.level);
1007 |   battery.addEventListener('levelchange', function() {
1008 |     console.log(this.level);
1009 |   });
1010 | });
1011 |

1012 | The following example updates the indicators to show the charging 1013 | state, level and time remaining in minutes: 1014 |

1015 |
Example 3
<!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>
1053 |
1054 |
1055 |

A. 1056 | Acknowledgements 1057 |

1058 |

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 |
1074 | 1075 | 1076 |

B. References

B.1 Normative references

[ECMASCRIPT]
Ecma International. ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/ 1077 |
[HTML5]
Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. W3C. HTML5. 28 October 2014. W3C Recommendation. URL: http://www.w3.org/TR/html5/ 1078 |
[RFC2119]
S. Bradner. IETF. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119 1079 |
[WEBIDL]
Cameron McCormack; Boris Zbarsky. W3C. WebIDL Level 1. 8 March 2016. W3C Candidate Recommendation. URL: http://www.w3.org/TR/WebIDL-1/ 1080 |
-------------------------------------------------------------------------------- /tidyrc: -------------------------------------------------------------------------------- 1 | char-encoding: utf8 2 | indent: yes 3 | wrap: 80 4 | tidy-mark: no 5 | -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": 43696, 3 | "contacts": [ 4 | "himorin" 5 | ], 6 | "shortName": "battery-status", 7 | "repo-type": "rec-track", 8 | "policy": "open" 9 | } 10 | --------------------------------------------------------------------------------