Skip to content

Commit bb1ee9b

Browse files
authored
Fix HTML5 battery API (#24677)
The old `navigator.battery` API is not longer present in modern browsers which all use `navigator.getBattery()`. Tested locally on my laptop. See https://developer.mozilla.org/en-US/docs/Web/API/BatteryManager
1 parent d20434c commit bb1ee9b

9 files changed

+58
-37
lines changed

src/lib/libhtml5.js

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,18 +2091,19 @@ var LibraryHTML5 = {
20912091
return registerBeforeUnloadEventCallback({{{ cDefs.EMSCRIPTEN_EVENT_TARGET_WINDOW }}}, userData, true, callbackfunc, {{{ cDefs.EMSCRIPTEN_EVENT_BEFOREUNLOAD }}}, "beforeunload");
20922092
},
20932093

2094-
$fillBatteryEventData: (eventStruct, e) => {
2095-
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.chargingTime, 'e.chargingTime', 'double') }}};
2096-
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.dischargingTime, 'e.dischargingTime', 'double') }}};
2097-
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.level, 'e.level', 'double') }}};
2098-
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.charging, 'e.charging', 'i8') }}};
2094+
$fillBatteryEventData: (eventStruct, battery) => {
2095+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.chargingTime, 'battery.chargingTime', 'double') }}};
2096+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.dischargingTime, 'battery.dischargingTime', 'double') }}};
2097+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.level, 'battery.level', 'double') }}};
2098+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenBatteryEvent.charging, 'battery.charging', 'i8') }}};
20992099
},
21002100

2101-
$battery: () => navigator.battery || navigator.mozBattery || navigator.webkitBattery,
2101+
$hasBatteryAPI: () => typeof navigator != 'undefined' && navigator.getBattery,
2102+
$hasBatteryAPI__internal: true,
21022103

21032104
$registerBatteryEventCallback__noleakcheck: true,
2104-
$registerBatteryEventCallback__deps: ['$JSEvents', '$fillBatteryEventData', '$battery', '$findEventTarget', 'malloc'],
2105-
$registerBatteryEventCallback: (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
2105+
$registerBatteryEventCallback__deps: ['$JSEvents', '$fillBatteryEventData', 'malloc'],
2106+
$registerBatteryEventCallback: (battery, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
21062107
#if PTHREADS
21072108
targetThread = JSEvents.getTargetThreadForEventCallback(targetThread);
21082109
#endif
@@ -2114,7 +2115,7 @@ var LibraryHTML5 = {
21142115
#else
21152116
var batteryEvent = JSEvents.batteryEvent;
21162117
#endif
2117-
fillBatteryEventData(batteryEvent, battery());
2118+
fillBatteryEventData(batteryEvent, battery);
21182119

21192120
#if PTHREADS
21202121
if (targetThread) __emscripten_run_callback_on_thread(targetThread, callbackfunc, eventTypeId, batteryEvent, userData);
@@ -2124,7 +2125,7 @@ var LibraryHTML5 = {
21242125
};
21252126

21262127
var eventHandler = {
2127-
target: findEventTarget(target),
2128+
target: battery,
21282129
eventTypeString,
21292130
callbackfunc,
21302131
handlerFunc: batteryEventHandlerFunc,
@@ -2134,24 +2135,37 @@ var LibraryHTML5 = {
21342135
},
21352136

21362137
emscripten_set_batterychargingchange_callback_on_thread__proxy: 'sync',
2137-
emscripten_set_batterychargingchange_callback_on_thread__deps: ['$registerBatteryEventCallback', '$battery'],
2138+
emscripten_set_batterychargingchange_callback_on_thread__deps: ['$registerBatteryEventCallback', '$hasBatteryAPI'],
21382139
emscripten_set_batterychargingchange_callback_on_thread: (userData, callbackfunc, targetThread) => {
2139-
if (!battery()) return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}};
2140-
return registerBatteryEventCallback(battery(), userData, true, callbackfunc, {{{ cDefs.EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE }}}, "chargingchange", targetThread);
2140+
if (!hasBatteryAPI()) return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}};
2141+
navigator.getBattery().then((b) => {
2142+
registerBatteryEventCallback(b, userData, true, callbackfunc, {{{ cDefs.EMSCRIPTEN_EVENT_BATTERYCHARGINGCHANGE }}}, "chargingchange", targetThread);
2143+
});
21412144
},
21422145

21432146
emscripten_set_batterylevelchange_callback_on_thread__proxy: 'sync',
2144-
emscripten_set_batterylevelchange_callback_on_thread__deps: ['$registerBatteryEventCallback', '$battery'],
2147+
emscripten_set_batterylevelchange_callback_on_thread__deps: ['$registerBatteryEventCallback', '$hasBatteryAPI'],
21452148
emscripten_set_batterylevelchange_callback_on_thread: (userData, callbackfunc, targetThread) => {
2146-
if (!battery()) return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}};
2147-
return registerBatteryEventCallback(battery(), userData, true, callbackfunc, {{{ cDefs.EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE }}}, "levelchange", targetThread);
2149+
if (!hasBatteryAPI()) return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}};
2150+
navigator.getBattery().then((b) => {
2151+
registerBatteryEventCallback(b, userData, true, callbackfunc, {{{ cDefs.EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE }}}, "levelchange", targetThread);
2152+
});
21482153
},
21492154

2155+
$batteryManager: undefined,
2156+
$batteryManager__internal: true,
2157+
21502158
emscripten_get_battery_status__proxy: 'sync',
2151-
emscripten_get_battery_status__deps: ['$fillBatteryEventData', '$battery'],
2159+
emscripten_get_battery_status__deps: ['$fillBatteryEventData', '$hasBatteryAPI', '$batteryManager'],
21522160
emscripten_get_battery_status: (batteryState) => {
2153-
if (!battery()) return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}};
2154-
fillBatteryEventData(batteryState, battery());
2161+
if (!hasBatteryAPI()) return {{{ cDefs.EMSCRIPTEN_RESULT_NOT_SUPPORTED }}};
2162+
if (!batteryManager) {
2163+
navigator.getBattery().then((b) => {
2164+
batteryManager = b;
2165+
});
2166+
return {{{ cDefs.EMSCRIPTEN_RESULT_NO_DATA }}};
2167+
}
2168+
fillBatteryEventData(batteryState, batteryManager);
21552169
return {{{ cDefs.EMSCRIPTEN_RESULT_SUCCESS }}};
21562170
},
21572171

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8310
1+
8305
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
22389
1+
22381

test/other/codesize/test_codesize_minimal_O0.expected.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,6 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile;
986986
'registerGamepadEventCallback',
987987
'registerBeforeUnloadEventCallback',
988988
'fillBatteryEventData',
989-
'battery',
990989
'registerBatteryEventCallback',
991990
'setCanvasElementSize',
992991
'getCanvasElementSize',
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6605
1+
6601
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
17652
1+
17644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
54121
1+
54108
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
52171
1+
52158

test/test_html5_core.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,25 +209,39 @@ void formatTime(char *str, int seconds) {
209209
}
210210
}
211211

212-
bool battery_callback(int eventType, const EmscriptenBatteryEvent *e, void *userData) {
212+
void log_battery_state(const EmscriptenBatteryEvent *e) {
213213
char t1[64];
214214
formatTime(t1, (int)e->chargingTime);
215215
char t2[64];
216216
formatTime(t2, (int)e->dischargingTime);
217-
printf("%s: chargingTime: %s, dischargingTime: %s, level: %g%%, charging: %d\n",
218-
emscripten_event_type_to_string(eventType), t1, t2, e->level*100, e->charging);
217+
printf("battery status: chargingTime: %s, dischargingTime: %s, level: %g%%, charging: %d\n", t1, t2, e->level*100, e->charging);
218+
}
219219

220+
bool battery_callback(int eventType, const EmscriptenBatteryEvent *e, void *userData) {
221+
printf("%s\n", emscripten_event_type_to_string(eventType));
222+
log_battery_state(e);
220223
return 0;
221224
}
222225

223226
bool webglcontext_callback(int eventType, const void *reserved, void *userData) {
224227
printf("%s.\n", emscripten_event_type_to_string(eventType));
225-
226228
return 0;
227229
}
228230

231+
void report_battery_state() {
232+
EmscriptenBatteryEvent bs;
233+
int ret = emscripten_get_battery_status(&bs);
234+
TEST_RESULT(emscripten_get_battery_status);
235+
if (ret == EMSCRIPTEN_RESULT_SUCCESS) {
236+
log_battery_state(&bs);
237+
} else {
238+
printf("battery state not yet available\n");
239+
}
240+
}
241+
229242
#ifndef KEEP_ALIVE
230243
void test_done(void *arg) {
244+
report_battery_state();
231245
emscripten_html5_remove_all_event_listeners();
232246
exit(0);
233247
}
@@ -389,13 +403,7 @@ int main() {
389403
ret = emscripten_set_batterylevelchange_callback(0, battery_callback);
390404
TEST_RESULT(emscripten_set_batterylevelchange_callback);
391405

392-
EmscriptenBatteryEvent bs;
393-
ret = emscripten_get_battery_status(&bs);
394-
TEST_RESULT(emscripten_get_battery_status);
395-
if (ret == EMSCRIPTEN_RESULT_SUCCESS) {
396-
printf("Current battery status:\n");
397-
battery_callback(EMSCRIPTEN_EVENT_BATTERYLEVELCHANGE, &bs, 0);
398-
}
406+
report_battery_state();
399407

400408
ret = emscripten_set_webglcontextlost_callback("#canvas", 0, 1, webglcontext_callback);
401409
ASSERT_RESULT(emscripten_set_webglcontextlost_callback);

0 commit comments

Comments
 (0)