Watch face always shows AoD on venu/d2air even in High Power mode — simulator bug or wrong code?


My code follows the guide's pattern:
if (DeviceSettings has :requiresBurnInProtection) {
        if (System has :getDisplayMode) {
            switch (System.getDisplayMode()) {
                case System.DISPLAY_MODE_HIGH_POWER:
                    break;
                case System.DISPLAY_MODE_LOW_POWER:
                    _drawAod(dc);
                    return;
                case System.DISPLAY_MODE_OFF:
                    return;
            }
        } else if (System.getDeviceSettings().requiresBurnInProtection) {
            // Guide says use this to detect low-power mode on original Venu
            _drawAod(dc);
            return;
        }
    }
    // render full watch face
Simulator results:

fr970 (AMOLED) - High Power -> Full face (correct)
fr970 (AMOLED) - Always-On -> Minimal AoD (correct)
fr55 (MIP) - High Power -> Full face (correct)
fr55 (MIP) - Always-Active -> Full face (correct)
venu / d2air - High Power -> Minimal AoD (WRONG)
venu / d2air - Always-Active -> Minimal AoD (correct?)

On venu and d2air, System has :getDisplayMode returns false, so I fall
back to requiresBurnInProtection. The problem: it returns true in both
High Power and Always-Active modes, so the AoD face always renders.

The guide implies requiresBurnInProtection dynamically reflects the
current mode (false = high power, true = low power). But in the
simulator it seems to always be true on these devices regardless of mode.

Side note: the guide's code sample has two apparent typos:
- System.getDisplayMode (missing parentheses, should be System.getDisplayMode())
- requiresBurnInProtection() with parentheses — calling it as a method
crashes at runtime. It is a Boolean property, not a method.

My questions:
1. Is requiresBurnInProtection supposed to return false in High Power
mode on venu/d2air? Is this a simulator bug?
2. If it is always true, is there another way to detect the current
display mode on these devices?
  • I don't have experience with watch faces, but your code seems to skip the checks on certain devices, because the if I'm line 1 prevents you to reach the if I'm line 2 on devices that don't have burn in protection but have display mode (I haven't checked, maybe it's ok, if there is and never can be such future device)

  • The way I've always done it is this:

    class variables:

    var canBurnIn=false;

    var inLowPower=false;

    In initialize for the view, I have this:

    sSettings=System.getDeviceSettings();
    if(sSettings has :requiresBurnInProtection) {      
        canBurnIn=sSettings.requiresBurnInProtection;                  
    }

    And then. with onEnterSleep/onExitSleep. I do this:

        function onExitSleep() {
            inLowPower=false;
        }

        function onEnterSleep() {
            inLowPower=true;    
        }

    and in onUpdate, I do this:

    if(inLowPower && canBurnIn) {
      //draw limited amount to avoid burnin
    } else {
      //draw full screen data
    }
    It works on all devices, MIP or AMOLED

  • Thank you, this pointed me in the right direction! Your pattern works perfectly. I extended it slightly to also handle newer AMOLED devices (fr970, Venu 2+) that support System.getDisplayMode():

    var canBurnIn = false;
    var isSleeping = false;
    
    function initialize() {
        WatchFace.initialize();
        var settings = System.getDeviceSettings();
        if (settings has :requiresBurnInProtection) {
            canBurnIn = settings.requiresBurnInProtection;
        }
    }
    
    function onExitSleep() { isSleeping = false; WatchUi.requestUpdate(); }
    function onEnterSleep() { isSleeping = true; WatchUi.requestUpdate(); }
    
    function onUpdate(dc) {
        if (DeviceSettings has :requiresBurnInProtection) {
            if (System has :getDisplayMode) {
                // Newer AMOLED (fr970, Venu 2+): use display mode API
                switch (System.getDisplayMode()) {
                    case System.DISPLAY_MODE_HIGH_POWER: break;
                    case System.DISPLAY_MODE_LOW_POWER: drawAod(dc); return;
                    case System.DISPLAY_MODE_OFF: return;
                }
            } else if (canBurnIn && isSleeping) {
                // Original venu/d2air: requiresBurnInProtection is a static
                // device flag (always true), not a mode indicator.
                // Use sleep callbacks to detect Always-Active (AoD) mode.
                drawAod(dc); return;
            }
        }
        // MIP or AMOLED High Power: render normal watch face
    }

    Works correctly on fr55 (MIP), venu/d2air, and fr970/Venu 2+.

  • Here's a wf I posted that shows a whole bunch of things, including this, background service, complications, etc.  And it's only about 14k in the sim:

     Simple Example WF that shows a bunch of things