crystal-face
crystal-face copied to clipboard
Crash on Venu 3.80 firmware
User Tim Marsh has kindly supplied crash logs. All his crashes have the same callstack:
Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2019-12-22T00:50:52Z
Part-Number: 006-B3226-00
Firmware-Version: '3.80'
Language-Code: eng
ConnectIQ-Version: 3.1.5
Store-Id: 9fd04d09-8c80-4c81-9257-17cfa0f0081b
Store-Version: 61
Filename: 9C825636
Appname: Crystal
Stack:
- pc: 0x10003189
- pc: 0x1000301e
Callstack corresponds to the following code:
function onExitSleep() {
// ...
// If watch does not support per-second updates, AND HideSeconds property is false,
// show seconds, and make move bar original width.
if (!PER_SECOND_UPDATES_SUPPORTED && !App.getApp().getProperty("HideSeconds")) {
setHideSeconds(false);
}
// ...
}
function setHideSeconds(hideSeconds) {
if (mIsBurnInProtection) {
return;
}
mTime.setHideSeconds(hideSeconds); // <-- CRASH HERE
mDrawables[:MoveBar].setFullWidth(hideSeconds);
}
~~This suggests that PER_SECOND_UPDATES_SUPPORTED
is false
for Venu, or else setHideSeconds()
would not be called. This implies that Ui.WatchFace
no longer has :onPartialUpdate
in the latest Venu firmware:~~
// N.B. Not all watches that support SDK 2.3.0 support per-second updates e.g. 735xt.
private const PER_SECOND_UPDATES_SUPPORTED = Ui.WatchFace has :onPartialUpdate;
~~When Venu exits sleep, it is still in always-on mode, so the mTime
drawable reference will be null
, until the watch face switches back to the regular layout at the beginning of the next onUpdate()
draw cycle. This explains the crash.~~
AFAIK, Venu has never advertised onPartialUpdate
support, so setHideSeconds()
is always called from onExitSleep()
. So mIsBurnInProtection
must be failing to be set, so setHideSeconds()
fails to return early, causing the crash. mIsBurnInProtection
is set as follows in onEnterSleep()
:
// If watch requires burn-in protection, set flag to true when entering sleep.
// #157 Add screen width test, as Fenix 5X firmware 15.10 incorrectly sets requiresBurnInProtection to true.
// TODO: Remove this workaround before OLED screens with different width are introduced.
var settings = Sys.getDeviceSettings();
if (settings has :requiresBurnInProtection && settings.requiresBurnInProtection && (/* Venu */ settings.screenWidth == 390)) {
mIsBurnInProtection = true;
mBurnInProtectionChangedSinceLastDraw = true;
}
Given that Venu was crashing even before the #157 fix that added the screenWidth
test, this could mean that Venu is no longer reporting requiresBurnInProtection
on firmware 3.80.
An alternative explanation is that Venu starts off in sleep mode, without calling onEnterSleep()
, so mIsBurnInProtection
fails to be set while in sleep mode.
But if the crash is caused by a mTime
being null
, this suggests that the always-on layout is active, which is only possible if mBurnInProtectionChangedSinceLastDraw
was successfully set to true
, AND mIsBurnInProtection
was also successfully set to true
. This only occurs in onEnterSleep()
, since both variables are initialise to false
at startup.
So how is isBurnInProtection
false at the start of onExitSleep()
? Is onExitSleep()
being called twice?
Without understanding the underlying cause, given that it's nearly Christmas, a quick fix for the crash would be to return early from setHideSeconds()
if mTime
is null
.