Acknowledged

AppBase.onBackgroundData requires Application.PersistableType, whereas Background.getBackgroundData and Background.exit use Application.PropertyValueType

As per the subject, there is a type discrepancy in the API.

Now, Application.PersistableType is actually defined to be the same as Application.PropertyValueType, which is fine, but Background.getBackgroundData and Background.exit should still be listed as using Application.PersistableType for consistency.

In addition, it would be REALLY good if Application.PersistableType (and/or Application.PropertyValueType) could be extended to include Graphics.BitmapReference and Graphics.FontReference so that these objects can be passed to the foreground through Background.exit. I can't see any reason why this shouldn't be done. It otherwise requires using Storage.set/getValue, which is a heavy-handed approach for sending a tiny object.

  • > However, if you check Storage.getValue[] in the foreground, it is returning a Graphics.BitmapReference

    > So either the reference remains valid when passed through storage, or Gamin is recreating a new reference when you call getValue. Either way, this is something that Background.exit[] should be able to duplicate.

    It's clearly the case that Garmin is creating a new reference when you call getValue[], not that the same reference is saved in Storage and retrieved by getValue[]. There's limit to the amount of time [or number of reboots] that can elapse between calling setValue[] and getValue[], so there's no way in principle to guarantee that a reference would stay valid in that period. The same argument could be made against storing regular references to things, for old devices which don't support the graphics pool / ResourceReferences.

    The point of BitmapReference [and other ResourceReference types] is that graphic-related resources are now stored in the graphics pool, as opposed to app memory. When you call Storage.setValue[] on a BitmapReference, clearly setValue[] [or some function that setValue[] calls] is implicitly calling BitmapReference.get[], and saving the contents of the bitmap to storage.

    When you call Storage.getValue[], it's almost certain that CIQ is:

    - reading the whole bitmap from Storage

    - placing the bitmap in the graphics pool

    - returning a BitmapReference to the graphics pool

    The simple thought [or actual] experiment to do is turn your watch off after your app stores a bitmap to storage. Turn the watch back on, run your app and note that the bitmap is still successfully retrieved from storage. Since we know that the graphics pool is almost certainly not persisted to disk [same as the rest of the watch's RAM]] it's not possible that a BitmapReference is being stored and read from Storage.

  • Some more info:

    In the background, my callback function for makeImageRequest is introduced as:

    public function onImageReceive(responseCode as Number, data as Graphics.BitmapReference or Null) as Void {

    which works fine. However, if within this function I to do:

    if (data instanceof Graphics.BitmapReference) {

    it fails at runtime with

    Error: Permission Required
    Details: Module 'Toybox.Graphics' not available to 'Background'

    If I instead do System.println(data) in the background, it replies with, e.g,.  "Bitmap 1260 x 60", whereas a System.println(im) in the foreground says, e.g., "Obj: 191". So there is something weird going on. The background appears to be faking that it has a BitmapReference, when it actually has a BitmapResource.

  • > I think what's happening is that when you call Storage.setValue(), the bitmap reference is implicitly derefenced, and the bitmap itself is saved to storage.

    Possibly this is happening behind the scenes. However, if you check Storage.getValue() in the foreground, it is returning a Graphics.BitmapReference, which you can verify with

    var im = Application.Storage.getValue("key");
    if (im instanceof Graphics.BitmapReference) {
       System.println("is BitmapReference");
    }

    So either the reference remains valid when passed through storage, or Gamin is recreating a new reference when you call getValue. Either way, this is something that Background.exit() should be able to duplicate.

  • > when I look in the simulator's "device filesystem"

    In Windows this is at %TEMP%\com.garmin.connectiq\GARMIN

    For Mac: $TMPDIR/com.garmin.connectiq/GARMIN

  • > This is consistent with a 550 x 550 8-bit bitmap.

    550 x 550 x 8 bits = 302,500 bytes