xous-core/services/gam
Gianguido Sorà 46ca14e2f9
Squashed commit of the following:
commit a09100ab4a
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:55:55 2022 +0800

    bump lockfile

commit 53172e1471
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:46:40 2022 +0800

    bump verification pins

commit 36398810dd
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:24:36 2022 +0800

    bump version numbers to absorb new syscalls

commit 062fa6178a
Merge: ac4a854e 3bcc955a
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:23:31 2022 +0800

    Merge branch 'reply-and-receive-next-syscall' into main

commit ac4a854e49
Merge: d1375343 e4c298db
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:22:25 2022 +0800

    Merge branch 'main' of github.com:betrusted-io/xous-core into main

commit 3bcc955aba
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:21:43 2022 +0800

    add test code that also benchmarks the new routines.

commit e4c298db40
Merge: f71278b4 e2bf7109
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 30 15:16:13 2022 +0800

    Merge pull request #289 from betrusted-io/reply-and-receive-next-syscall

    Reply and receive next syscall

commit e2bf710939
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:06:51 2022 +0800

    services: xous-ticktimer: use reply_and_receive_next()

    Convert the ticktimer server to use the new
    reply_and_receive_next_legacy() call. This is an example of how to use
    this API for future projects.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 0e75b8e479
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:05:26 2022 +0800

    test-spawn: rename `Message` to `MessageEnvelope`

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 3218bde2b4
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:04:01 2022 +0800

    kernel: implement reply_and_receive_next

    Implement `ReplyAndReceiveNext` as a syscall. This will reply to a
    message, pull the next message out of the queue, and then re-queue the
    server to run. This should make servers much more responsive.

    This patch has been tested on both hosted and native modes.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit d1375343c1
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 23:34:48 2022 +0800

    update release notes

commit f71278b422
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 22:04:55 2022 +0800

    fix issue #109 - refactor key fill/scan to not crash after pruning

    After a prune, key fill/scan can crash because there is an assumption
    that data is always resident in the cache for a small key.

    This code handles the case where the small key data was evicted during
    a prune, and reads the data back in just for that key on demand.

    Furthermore, during a `sync` call, it will pull in the key data
    that corresponds to the page containing just the small key, allowing
    that page to be re-composed and replaced in memory. caching is used
    on the decryption of the small key page so the expensive bit
    of the call should only happen once per small key bank.

    tested with pddb-ci and manually in hosted mode.

    A portion of code was re-written to make it clear that only the
    length of allocated data is copied to/from disk and memory, instead
    of the reserved space as the previous code would indicate. The reserved
    space is guaranteed to be zero because the RAM-based page for composing
    the small key block is zero-ized prior to operations; left comments
    reminding me of this in the future so I don't accidentally optimize
    something out and cause data leakage between small keys because I'm
    allowing the reserved areas to contain stale data.

commit e25da3a720
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 22:04:15 2022 +0800

    add implemenation of the `prune` debug call

    this allows us to trigger the cache prune manually, instead of
    in response to memory backpressure only

commit 549e67fead
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 22:03:19 2022 +0800

    add a `prune` debug call to force a hard-prune of the pddb cache

commit e045574d39
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:06:51 2022 +0800

    services: xous-ticktimer: use reply_and_receive_next()

    Convert the ticktimer server to use the new
    reply_and_receive_next_legacy() call. This is an example of how to use
    this API for future projects.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 23c17d7632
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:05:26 2022 +0800

    test-spawn: rename `Message` to `MessageEnvelope`

    Signed-off-by: Sean Cross <sean@xobs.io>

commit aae5f3737c
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:04:01 2022 +0800

    kernel: implement reply_and_receive_next

    Implement `ReplyAndReceiveNext` as a syscall. This will reply to a
    message, pull the next message out of the queue, and then re-queue the
    server to run. This should make servers much more responsive.

    This patch has been tested on both hosted and native modes.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit ab0c7d3b32
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:03:39 2022 +0800

    kernel: server: check buf is some when returning mem

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 46f340324d
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:02:57 2022 +0800

    kernel: rename `Message` -> `MessageEnvelope`

    This syncs with the latest changes to `xous-rs`.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 911ddb60fc
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:01:27 2022 +0800

    kernel: debug: fix klog on baremetal

    klog() refers to an outdated `.uart` struct, which has since been
    renamed to `.serial`.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit d88254b1b1
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:00:35 2022 +0800

    xous: add reply_and_receive_next_legacy call

    This call is used to return values while simultaneously listening for
    new messages.

    The -legacy suffix is used to disambiguate scalar values, so we know
    whether to send Scalar1, Scalar2, or Scalar5 messages.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 64c88f9942
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 21:00:05 2022 +0800

    xous: add Message type

    This type actually contains the message contents, and will be used to
    return data to the caller.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit d463f9563f
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 29 20:58:51 2022 +0800

    xous: rename Message to MessageEnvelope

    This reflects the fact that up until now, the `Message` struct has
    merely been the envelope that surrounds the message. It does not contain
    any actual Message contents.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 49ce85f9a8
Author: Sean Cross <sean@xobs.io>
Date:   Wed Jul 6 15:57:10 2022 +0800

    ticktimer-server: prepare for using ReplyAndReceiveNext

    Misc cleanup prior to switching which call we use.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit be56af6303
Author: Sean Cross <sean@xobs.io>
Date:   Wed Jul 6 15:35:22 2022 +0800

    xous: add wrapper for reply_and_receive_next

    This wrapper enables userspace programs to use the new
    ReplyAndReceiveNext syscall easily.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 36e6e6c30b
Author: Sean Cross <sean@xobs.io>
Date:   Wed Jul 6 15:18:32 2022 +0800

    xous: syscall: add ReplyAndReceiveNext call

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 1e56598b10
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 00:53:32 2022 +0800

    chore: fix some typos

commit 1291b0f00b
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 00:38:27 2022 +0800

    add issue # to release note

commit 7206f24271
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 00:37:47 2022 +0800

    update release notes

commit 2f30e1b50a
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 00:11:03 2022 +0800

    implement #269

commit 5370c333da
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 29 00:10:42 2022 +0800

    add callback for monitoring basis lock/unlock events

commit 8d42feb051
Author: bunnie <bunnie@kosagi.com>
Date:   Wed Dec 28 19:48:40 2022 +0800

    increase heap for mtxcli; add memory usage reporting

commit ac1df054ab
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 26 13:52:44 2022 +0800

    absorb 22-bit satp fix

commit 89500015a7
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 15 17:52:55 2022 +0800

    try to fix regression from #284

    still hitting cache coherence edge cases. expanding the flush
    set read by one more way.

commit 41ea0a37c5
Merge: e422740d b288d93a
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 15 14:36:40 2022 +0800

    Merge branch 'main' of github.com:betrusted-io/xous-core into main

commit b288d93abd
Merge: 8e1d0502 d4527b82
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 15 14:00:10 2022 +0800

    Merge pull request #284 from betrusted-io/use-thin-lto

    cargo: use thin-lto

commit d4527b8227
Author: Sean Cross <sean@xobs.io>
Date:   Thu Dec 15 12:26:00 2022 +0800

    cargo: use thin-lto

    Use thin LTO for linking. This shouldn't have too big of an affect on
    the resulting binary size, and it fixes the build for 1.66.0:

    = note: rust-lld: error: undefined symbol:
    core::panicking::panic_str_nounwind::h9b449c0fe03c8dac
    >>> referenced by compiler_builtins.22a3dcb1-cgu.13
    >>> compiler_builtins-b913bacb8fda1c55.compiler_builtins.22a3dcb1-cgu.13.rcgu.o:(compiler_builtins::math::libm::rem_pio2_large::rem_pio2_large::h3db6431f23a281c1)
    in archive root\lib\rustlib\riscv32imac-unknown-xous-elf\lib\libcompiler_builtins-b913bacb8fda1c55.rlib
    >>> referenced by compiler_builtins.22a3dcb1-cgu.13
    >>> compiler_builtins-b913bacb8fda1c55.compiler_builtins.22a3dcb1-cgu.13.rcgu.o:(compiler_builtins::math::libm::rem_pio2_large::rem_pio2_large::h3db6431f23a281c1)
    in archive root\lib\rustlib\riscv32imac-unknown-xous-elf\lib\libcompiler_builtins-b913bacb8fda1c55.rlib

    Signed-off-by: Sean Cross <sean@xobs.io>

commit e422740d37
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 23:03:50 2022 +0800

    chore: last one. really.

commit ad79ebf8ba
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 23:02:09 2022 +0800

    chore: more typos. no really, i can stop at any time.

commit b1b6d46d27
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 22:56:37 2022 +0800

    chore: more typos

    probably should not have tried to spell check this, now i'm wasting
    my time.

commit 283ea1de0d
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 22:49:25 2022 +0800

    chore: fix more typos, add french dictionary to vscode workspace settings

commit 1d94968b2f
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 22:36:47 2022 +0800

    chore: fix typos

commit e930d88563
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 01:42:00 2022 +0800

    placeholder for 0.9.12 release notes

commit 8e1d05020d
Author: bunnie <bunnie@kosagi.com>
Date:   Tue Dec 13 00:32:11 2022 +0800

    add v0.9.11 to the restore.py URL list

commit bd230f5bb0
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:51:27 2022 +0800

    fix text to speech mode preferences setting

    never allow the audio system to be turned off for blind people,
    and disallow 0-volume setting as well.

commit 38bc254bb9
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:28:33 2022 +0800

    fix missing ja/zh translation

commit 60d4482ce2
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:16:04 2022 +0800

    bump lockfile

commit 56f0843229
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:08:28 2022 +0800

    bump verifier numbers

commit 5370ce396d
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:07:20 2022 +0800

    bump all revs due to SoC artifact update

commit cac0e57cda
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:06:31 2022 +0800

    change default target

commit 04b441a234
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:06:19 2022 +0800

    add 0.9.11 build artifact

commit 08cf863ff5
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 16:05:15 2022 +0800

    update SoC artifacts for 0.9.11 build

commit c32b5d5bac
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 15:31:15 2022 +0800

    bump release notes

commit 80ce119c95
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 15:31:06 2022 +0800

    fix RSSI calculations

commit edf24d9fc2
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 14:11:19 2022 +0800

    clean up on the wifi signal bars

commit eb17edc4ec
Merge: 9a580070 435a6ea2
Author: bunnie <bunnie@kosagi.com>
Date:   Mon Dec 12 11:47:18 2022 +0800

    Merge pull request #283 from gsora/feat/wifi-signal-bars

    feat: wifi signal bar

commit 9a580070a3
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 11 17:50:51 2022 +0800

    revert threaded init question now that deface issue is fixed

commit f9cdf31857
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 11 17:07:29 2022 +0800

    bump release notes

commit 196ceb0d29
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 11 16:42:03 2022 +0800

    fix: avoid thrashing when recomputing previously defaced canvases

    There was a dubious line that I never felt good about and today
    I found out why. By flipping every canvas to drawable before doing
    the intersection computation we also throw away the defacement state,
    so previously defaced canvases would lose their status bit, causing
    thrashing of the canvases anytime there is a re-computation of
    the canvas ordering.

    This fix caches if a canvas was already defaced, and if it turns out
    that an on-screen canvas should not be drawable but was already
    defaced, the setting is re-applied, preventing thrashing.

commit dca043d387
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 11 16:41:53 2022 +0800

    improve context swap debug messages

commit 8d8dd2bd2f
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 11 16:41:25 2022 +0800

    fix typo in unwrap message

commit f31afa5125
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 11 16:41:06 2022 +0800

    remove unused opcode in shellchat; improve debug output

commit 6138b65d76
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 23:44:18 2022 +0800

    update comments to reflect changes in CI infra

commit 399124f942
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 22:05:47 2022 +0800

    fix hosted mode

commit 939e13950d
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 18:59:55 2022 +0800

    comment out debug in rootkeys implementation section

commit 2097afc166
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 18:58:06 2022 +0800

    add efuse burning flow to rootkeys

    currently only available for builds that have the `efuse` feature
    enabled

commit 19e16aea29
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 18:56:59 2022 +0800

    fix jtag fuse burning & add diagnostic messages

    - msb/lsb swap on efuse bank fixed
    - hazardous-debug feauter gates added
    - dry-run for "testing only" added

commit 4ec866e1d7
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 18:56:12 2022 +0800

    add diagnostic seal command

commit f5c687a524
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 17:45:30 2022 +0800

    clarify user prompt

commit 2b4e47384e
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 17:44:54 2022 +0800

    add fused device support and warnings to precursorupdater

commit e42c4c7b33
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 16:39:14 2022 +0800

    add warnings & support for fused devices

    burning a generic image to a fused device will surely lead to
    a brick, so, try to keep a user from shooting themselves in the foot.

commit c2f7a63f97
Author: bunnie <bunnie@kosagi.com>
Date:   Sat Dec 10 16:39:01 2022 +0800

    remove some whitespace to allow for easier debugging

commit 1f89843122
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 9 12:38:53 2022 +0800

    defer init root keys question until status thread starts

    also defer the preference thread from loading until after the
    PDDB mount thread is started -- doesn't make sense to start it
    any earlier than that, since it depends on the PDDB being mounted.

commit 02f9701546
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 8 17:42:12 2022 +0800

    make an explicit dvt feature to simplify flags

commit 4dd983bfc4
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 8 17:19:05 2022 +0800

    adjust security parameters for dvt build

commit fc08c3e29d
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 8 17:14:47 2022 +0800

    add hazardous-debug to modals bip-39

    for convenient key printout during debug. flag is normally off.

commit dd82b7f32a
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 8 17:14:21 2022 +0800

    add no-codec mode to status

    this is for DVT builds where the codec isn't supported, needed
    for efuse testing

commit a5d341c7a6
Author: bunnie <bunnie@kosagi.com>
Date:   Thu Dec 8 14:09:36 2022 +0800

    add a bitstream encryption/recovery tool for fused devices

    This is useful for recovering bricked devices where the backup
    key is available. This tool can be used to generate an FPGA
    image for a device that has been permanently fused to a non-0
    backup key.

commit 4f270f54be
Author: bunnie <bunnie@kosagi.com>
Date:   Wed Dec 7 22:24:56 2022 +0800

    revert debugging on status opcodes

commit 435a6ea2bd
Author: Gianguido Sorà <me@gsora.xyz>
Date:   Wed Dec 7 14:28:07 2022 +0100

    feat: wifi signal bar

    This commit draws a Wi-Fi signal bar with 5 bars (lowest to highest signal), to the right of SSID name.

    Signal power is calculated from a lowest of -90dBm to a maximum of -30dBm, by increments of 13dBm.

commit f84a9d10c7
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 4 18:13:37 2022 +0800

    add placeholder for the efuse flow in the rootkey service

commit 8208a86c08
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 4 18:12:30 2022 +0800

    add the UX front-end for backup key burning

    - instructions for BBRAM flow (refers to wiki)
    - consent for efuse flow
    - fix a blocking issue on backup prep (minor problem, just gives
    users more time to contemplate without a panic)

commit 3838f3bc15
Author: bunnie <bunnie@kosagi.com>
Date:   Sun Dec 4 18:12:05 2022 +0800

    add a pause for context swaps on menu release

commit 53c9af1033
Author: bunnie <bunnie@kosagi.com>
Date:   Fri Dec 2 23:00:38 2022 +0800

    bump readme's
2023-01-02 15:51:45 +01:00
..
locales Squashed commit of the following: 2022-11-14 16:22:46 +01:00
src Squashed commit of the following: 2023-01-02 15:51:45 +01:00
build.rs xous: Use CARGO_CFG_TARGET_OS in build scripts. 2022-10-12 19:03:46 +02:00
Cargo.toml Squashed commit of the following: 2023-01-02 15:51:45 +01:00
README.md update some docs to refer to the modals refactor 2021-12-17 02:59:18 +08:00

Graphical Abstraction Manager (GAM)

The GAM provides abstract UI primitives to other modules.

The goal is to have this module work in close conjunction with the graphics-server, and all other modules would route abstract UI requests through this module.

Structure

At a high level, you can think of the GAM as a firewall around the graphics-server. The graphics-server has no concept of what pixel belongs where; it's happy to mutate a pixel that is anywhere within the physical hardware framebuffer.

Giving processes direct access to graphics-server means that a less trusted program could draw into an OS-reserved area, thus presenting false information to a user. The GAM solves this problem by dividing the screen into Canvas objects.

Ux Context Names

See tokens.rs for a list of expected boot UX contexts. The GAM enforces a policy that disallows the registration of unexpected UX contexts (including menus). When adding more UX elements, be sure to expand the list of EXPECTED_BOOT_CONTEXTS, or else the registration will fail.

Canvas

A Canvas is a minimal data structure that defines a physical region of the screen that will display a set of primitives. Canvas structures are domiciled in the GAM server, and are considered trusted by default, although there is a flag that can be cleared to make everything within it untrusted.

Each Canvas has a 128-bit GUID. Application processes that wish to draw something to the screen must refer to a Canvas by its 128-bit GUID; it is up to the GAM to not share secure GUIDs with insecure processes. Thus the security of a Canvas rests in the difficulty of guessing the 128-bit GUID, and also in the system not leaking GUIDs.

Every GAM drawing object includes the GUID of the Canvas to which it should be drawn. Upon receiving a draw request, it validates that the GUID exists, and applies any other relevant rules (for example, a higher security process can use the GAM to prohibit all drawing of lower security processes by marking their Canvas as not drawable).

All GAM drawing objects specify pixel offsets from a (0,0) top-left coordinate system. The GAM then handles translating these offsets from a virtual (0,0) Canvas offset to a physical region of a screen through the clip_rect record within the Canvas. The coordinate space of the clip_rect is fixed to the screen's coordinates, that is, (0,0) in the top left, X increasing to the right, Y increasing down.

A Canvas also stores a pan_offset. The pan_offset is added to every coordinate inside the objects that refer to a Canvas and then the result is clipped with clip_rect; this allows for easy implementation of panning and scrolling. (Note: this feature is largely untested as of March 2021)

A Canvas has a trust_level associated with it. Higher numbers are more trusted; 255 is the highest level of trust. Rules for drawing are as follows:

  1. More trusted Canvas objects always render on top of lower trusted object
  2. When a higher trusted Canvas object overlaps a lower trusted object, the lower trusted object is:
    • defaced using hatched lines with a random angle and spacing
    • further updates to the lower trusted object are disallowed.

Thus, a Canvas should not be thought of like a "window", as windows in typical UIs are allowed to freely overlap and clipping is handled by simply drawing over lower layers of content.

Canvas makes it strongly preferred to render trusted and untrusted data side-by-side, rather than one on top of each other.

This policy is partially to help users be very clear as to e.g. where a password box is vs. an image that looks a lot like a password box; but the policy is also informed by the limitations of the underlying hardware. In particular, the underlying memory LCD strongly relies on "dirty bits" for good performance, and doing full-region redraws to handle dirty rectangles on window movement is not an efficient use of dirty bits. Reducing time spent redrawing partially obscured windows is also good for performance and helps to simplify the code base, but these last two considerations are quite minor compared to the primary concern of a "least confusing" UI when it comes to differentiating between trustable and less trustable regions of the screen.

Thus, the simple rule is: don't stack content types of different trust levels. If you require content stacking, this can be done for content within a single trust level by using multiple objects within a Canvas, as they have a draw_order attribute and can handle content stacking; but between trust domains, it's both a trust and complexity issue to allow for simultaneous stacking of trust domains with live, full-content update of the underlying layers.

Defacing

Defacing is a policy implemented by the GAM which ensures that when trusted objects are overlaid on top of less trusted objects, the less trusted objects cannot be mistaken for a trusted object. This is to assist users with avoiding phishing attacks through Ux elements presented on less trusted canvases that look like trusted objects.

Defacing basically takes a bit of entropy from the TRNG and renders it in the form of random lines drawn across the defaced area. This allows users to still read the text within the defaced area, but makes it more difficult to mistake this area for something trusted.

Trust Level Policy Implementation

The RegisterUx opcode in gam is responsible for parceling out trust levels.

At boot, there is only a "boot context" -- no user apps are allowed, and all contexts are assigned a high trust level. During the boot process, apps are registered and claim names out of the tokens.rs EXPECTED_BOOT_CONTEXTS name space.

Roadmap (as of Xous 0.8.x): The idea is that once boot is thought to be completed, both xous-names and the gam are checked to ensure that all the available slots for boot processes are occupied. If this check passes, a flag should be set indicating we're done, and the max trust level assignable should drop. This process disallows future no-boot processes from registering as a trusted context, both in terms of their name space and their trust level.

TextView

A TextView object is a heavy data structure that contains both a xous::String and metadata which guides the GAM on how to render the string. Please note the philosophy of the GAM is to hide the exact details of how anything is rendered to the calling application. This both allows users to have greater control over customizing their interfaces, and also helps introduce a layer of protection against phishing; however it also means that UX designers will not be able to have exquisite control over the "look and feel" of their applications.

TextView objects are domiciled on the application process. The application process is responsible for guiding the rough layout of where TextViews go in a canvas. Once the object is finalized, the TextView objects are then mutably lent to the GAM using an rkyv lend wrapper; the calling thread then blocks until the GAM completes the rendering operation.

For layouts that need to adjust in height based on variable-length text strings, the calling application can use the bounds_hint/TextBounds to help manage this. The bounds of a TextView can either be a fixed-sized rectangle, or a box that grows up and out from a point plus a width. So, for example, a TextView could have an anchor in the lower-right hand corner, plus a maximum width, and the height of the box will be computed based as the text is rendered. The height of text can't be known a-priori, because for example, emoji glyphs and hanzi characters will have a different height than latin characters. A dry_run option is also available for a TextView so one can simulate the rendering to determine the height without paying the compuational price.

One can think of a TextView as a text bubble, that can have rounded or square corners, and its content string can be rendered with a selection of options that specify the glyph style (not a font -- it's more of a hint than a specifier), aligment, and the size of the text bubble. The text bubble can either be of a fixed size (such that the string will show ellipses ... if it overruns the bubble), or of a dynamically growable size based on its content.

Thus, a typical "chat-style" app where text bubbles show a history of the chat going from the most recent at the bottom of the screen to the oldest at the top, would start by rendering variable-height text bubbles on the bottom, getting the returned value of the rendered height, and setting the height of the next bubble on top for rendering, and then rendering that.

TextView can both be directly rendered to a Canvas, or managed by secondary object such as a Menu or List to compose other UI elements.

Menu

A Menu object encodes the state of a graphical menu. It's meant to be paired with a dedicated thread that serves as an event loop. You can look at the main menu implementation inside the GAM for an example of how this is done. Most event loops will look about the same; if you do not want to build an event loop, you can use the spawn_helper API to create one for you (see below).

Building a menu is fairly straight forward:

  • register your Menu object's name inside services/gam/src/tokens.rs. Currently, one can only register servers that are "expected" by the system; this is meant to prevent e.g. malicion code injection from conjuring UX elements.
  • create the Menu object by calling Menu::new(name: &str). This will automatically register an empty Menu layout as a Ux element inside the GAM.
  • add menu items by calling .add_item() on your Menu object
  • run the event loop and pass events back to the Menu object for processing

Each MenuItem has the following fields:

  • name: the text shown for the item
  • action_conn: a xous CID to the target server that receives the action of the menu item
  • action_opcode: the local opcode of the target server. Opcodes are private to the server, so menu-actionable opcodes need to be revealed with a helper method on the target server.
  • action_payload: an enum that encodes the payload of the Opcode. For now, only Scalar payloads are implemented, but the framework is there for some kind of a Frankenstein static-buffer to be passed on to targets
  • close_on_select: a boolean which indicates if the menu should automatically close once the item is selected

Modal

A Modal object encodes the state of a modal dialog box. A modal dialog box is limited to this general format:

  • Top text: describe the request
  • Action: the interactive element
  • Bottom text: reserved for validator error messages

The Action currently can be one of the following types:

  • TextEntry: for passwords, or for regular text
  • RadioButtons: for selecting one of many options
  • CheckBox: for selecting any of many options
  • Slider [NOT YET CODED]: for selecting a single numeric value along a range of values

Creating a Modal follows the same general pattern as the Menu, with the exception that the new() function is meant to be "complete": instead of creating a skeleton of a menu, the new() function takes all the necessary arguments for the repsective top, bottom, and action fields and tries to build the modal all in one go. It is, however, possible to dynamically modify the modal once created, using the modify() and remove() methods.

TextEntry supports an input validator; the validator takes as input the proposed payload string, and returns None if valid, or an error message that is plcaed into the dialog box's "bottom text" if the input is invalid.

TextEntry also supports "password" mode. When selected, text visibility can be controlled by a three-selection horizontal radio control that can select between "fully visible", "partially visible", and "fully obscured" states.

TextEntry is specifically coded so that its payload is cleared upon send, so that plaintext passwords are not left hanging around in the heap or stack.

The modals server allows applications to pop up generic modals without having to write all the eventing glue code to the GAM. The server has the following properties:

  • "Does about the right thing" for 90% of the applications
  • Shared between multiple processes with a lock -- so the messages from this server should not be absolutely trusted
  • Currently implements notifications, progress bars, text input, radio buttons, and checkboxes.
  • Has a "pure Rust" blocking API so routines can sequence through the dialog boxes in a declarative fashion without having to write fancy sequencing logic.

Example code:

  • The rtc server contains an example of a modal that uses the modals server.
  • The root-keys server contains an example of a static password modal, and uses an explicitly coded helper thread. It manages its own modals because it has a unique rendering property that can only be summoned by this process.

Helper Threads

A Menu or Modal needs to be able to respond to callbacks from the GAM. You can either do this with a separate, explicitly coded menu loop (as seen is the main menu and the emoji menus), or you can use the spawn_helper convenience call. To use spawn_helper, however, your local server need to implement three opcodes:

  • Redraw - calls the .redraw() method on the modal
  • Rawkeys - handles a set of key events destined for the modal
  • Quit - indicates that the server was told to quit for some reason (currently there's no good reason for this, but in the future once process destruction is supported, this will be important)

Your local server's opcode IDs are arguments to spawn_helper, along with both the private and the public SIDs. The public SID is inside the Menu or Modal object; it's shared with the GAM. The private SID is the SID of your loop handler, which is normally masked by xous-names. The private SID should not be shared with untrusted processes. However, since spawn_helper is in your own memory space, it's OK to shaer the private SID with this thread.

The TL;DR is that the helper thread is just a lookup table that maps UX opcodes to your thread's private opcode space, and it igonres any uknown opcodes.