Skip to content
Visor Developers

Briefing panel

The Meta Ray-Ban Display's home has a Briefing panel: glanceable cards for the weather, sports, stocks and reminders. The phone serves the panel on svc9002, and the detail screens a card opens on svc43, as Bloks. Visor serves Meta's cards from Meta's servers, and apps' own cards beside them, details and buttons included. This page covers the panel, the cards' payloads, the detail screens, their buttons and the icons. See Display internet for svc43 and Device Access Toolkit for Bloks as DAT uses it.

svc9002: the panels

Type Direction Message
1 Display to phone Which panels are on
2 Phone to Display PanelInfo {1 id, 2 name, 3 ttl s, 4 renderer (2 = Bloks), 5 data provider (1 = DataX), 6 cache policy}
0 Display to phone OpenPanel {2 HostInfo}
0 Phone to Display Command {1 command (0 create, 3 error), 2 widget (5 data payload), 3 stats {1 os, 3 ms}, 10 data, 11 error details}
3, 4 Both Prewarm, and its answer {1 0}

The Briefing is panel 30. HostInfo is {1 device (2 = wrist), 4 Bloks version, 5 design system, 7 repeated card config, 8 persist, 9 request id}, each card config {1 id, 2 name, 4 enabled, 5 panel id, 6 cached hash}.

The answer's data is {1 payloads, 2 repeated catalogue entry, 3 fresh ttl s, 4 ttl s}:

  • Payloads are gzipped: {1 repeated {1 card id, 2 Bloks JSON, 3 content hash}, 2 preview}.
  • A catalogue entry is {1 id, 2 name, 3 description, 4 enabled, 6 hash, 7 icon}, the icon as drawable://<name>_filled_32. It fills the Display's list of Briefing cards, where the wearer turns cards off.
  • The Display asks again when the wearer opens the Briefing after the fresh TTL. Meta answers 300 s, and Visor 15 s while apps have cards there. It keeps a card's payload while its hash stays the same.

Meta's cards come from the GraphQL query XFBGlanceablesQuery (doc id 168198258811666417495687582669). Its variables are {bloks_version_id, device_type ("GREATWHITE" or "WRIST"), design_system_version, timezone, request_id, assistant_locale, display_locale, latitude, longitude, enabled_glanceables [{id, name, cached_hash}]}. It answers xfb_glanceables {l1_payload_list [{id, payload, content_hash}], all_glanceables [{id, name, enabled, icon_uri}], preview, fresh_ttl, ttl}. The card ids are the names: Weather, Stocks, Sports, Reminders.

A card

A card's payload is {"layout":{"bloks_payload":{"data":[],"tree":...}}}. Its tree is a Container (22655) of the panel's material (23457 {38 "meta-ai-kinetic"}) around a Flexbox with the card's content, padded 24 dp. Meta's cards style their text as:

Line Font Size, line height
Title ("Weather") optimistic-iris-sd-700 24, 32 sp
Figure ("8 degrees") optimistic-iris-hd-700 36, 44 sp, or 40, 48 sp in a detail
Detail line optimistic-iris-sd-400 22, 28 sp

They also use optimistic-iris-sd-500 for names. Meta's Stocks colours a rise #FF009914 and grey text #FFC6C9CF. The Weather card pins a 104 dp illustration in its top corner with an absolute position.

Clicking into a card

A card's root carries extensions (key 133): an OnClickExtension (23426) whose script (key 35) opens the detail screen, prefetch scripts (13914), and a focus and accessibility extension (14001). The click script runs bk.action.bloks.FetchAsyncComponents and opens com.bloks.www.screen.query.wearables.GlanceablesDetailScreenQuery, container config 22942. Its preloaded params are {data_type, design_system_version, latitude, longitude, ttl 3600, data_hash, timezone, assistant_locale}, where data_type is the card's name and data_hash a hash of its detail. The Weather card's scripts also carry the location and a spoken label. The Stocks card's carry neither, so Visor copies the Stocks card's scripts onto apps' cards, with the name and the hash replaced.

The screen is a generic shell. It asks for the detail on svc43 type 9, app id com.bloks.www.async.components.GlanceablesDetailQuery, with params {data_hash, design_system_version, timezone, assistant_locale, latitude, data_type, longitude}. The answer, gzipped on type 10:

{"component_query_responses": [{
  "payload": "<JSON: {\"components\": [{\"id\": \"component\", \"payload\": {\"layout\": {\"bloks_payload\": {...}}}}]}>",
  "consumed_params": {"data_hash": "data_hash", ...},
  "app_id": "com.bloks.www.async.components.GlanceablesDetailQuery"
}]}

A bloks payload with only data and tree is enough: Visor answers apps' details that way, and the Display draws them. Meta's carry ft, embedded_payloads and error_attribution too, and a render lifecycle script (16529) that reports __infra_component_did_render.

Pages

Meta's Weather (now, the next hours, the week) and Stocks (one page a stock) details are a horizontal pager, component 17259:

Key Value
35 "horizontal"
36 true, snapping page by page
38 "DOTS", the page indicator
40 "UNDER", its place
42 "flex_end"

Each page is a Container (22655) of the kinetic material with an id, inside a Flexbox with 24 dp at its sides (keys 56 and 57). The pager's bind extension (13914, key 42) focuses the first page 100 ms after it binds: (e1w (e24 (e23 100 (e24 (e1w (e24 (dps (dn3 "<page id>")))))))), that is Apply, FuncConst, Delay, RequestFocus and Find.

Buttons in a detail

Meta's Stocks detail has "Add stock" and "Remove stock". Each one calls the phone with bk.action.bloks.AsyncActionWithDataManifestV2:

(AsyncActionWithDataManifestV2 "com.bloks.www.glanceables.remove_subscription"
  (mins.CallRuntime 6 "params" <JSON {"server_params": {"item_type": "stock", "timezone": ..., "source": "per_card_tap"},
                                       "client_input_params": {"item": "^IXIC"}}>)
  (tree.Make 16131 36 <done> 35 <failed> 40 <client params> 38 "current-screen")
  (array.Make))

That reaches the phone as svc43 type 11, and the phone answers on type 12. On failure Meta shows bk.action.wearables.ShowToast "Something went wrong. Please check connection" null "NEGATIVE". The toast's third argument is one of AFFIRMATIVE, NEGATIVE, EXIT and UNKNOWN.

Visor gives apps' buttons the same call with its own app id, com.bloks.www.visor.card_click, and server_params {card, id}, answers it on the phone, and hands the click to the card's app. Done shows the element's toast, AFFIRMATIVE.

Components and keys

Seen in Meta's Briefing payloads. A guessed role says so.

Component Keys
13320 Flexbox 32 children, 41 direction, 42 wrap, 44 justify, 36 align items, 59 54 58 55 padding top, bottom, start, end, 56 57 the sides (guessed), 38 background, 133 extensions
13314 Decoration 35 drawable, 43 false (role unknown)
13340 Solid colour 35 a themed colour
13365 Themed colour 35 and 36: #AARRGGBB for the two themes
13335 Text 41 text, 45 size and 53 its unit ("sp"), 46 "normal", 35 font, 48 themed colour, 59 line height, 38 max lines, 42 alignment ("end")
13323 Image 41 URL, 35 tint (a themed colour)
24201 Base style 41 height, 58 width, 54 position ("absolute"), 57 top, 36 bottom, 42 start, 55 end, 59 z order (999), 61 align self, 63 grow, 65 shrink, 49 43 48 44 margins
22655 Container 32 children, 41 material, 33 id, 133 extensions
23457 Material 38 "meta-ai-kinetic", 40 corners
17259 Pager above
16851 Draws one of embedded_payloads by bk.action.template.Make (guessed)
24214 A text input ("Say a stock name or ticker...")
24020 An error view: 46 title, 45 body, 42 icon
17233 A rail action: 42 label, 40 icon, 41 script
23426 OnClickExtension 35 script
13914 Bind scripts: 41 and 42
14001 Focus and accessibility: 35 label, 40 focusable, 42 "yes", 45 role, 55 actions (14117 {35 "click", 36 label, 38 script}), 70 on focus, 71 test id
16529 Render lifecycle: 35 script

DAT's toolkit app takes a plain "#FFFFFF" under text key 43. The Briefing's own text uses the themed colour under 48. Visor sends #RRGGBB under 43 in both, and the Display draws it.

Scripts

A script is a string that starts with a tab, its functions named by base-36 ids: dn1 is 17677, bk.action.bloks.FetchAsyncComponents. The Display's own table is in its System UI, GreatwhiteSystemUIRelease, class X.AbstractC529337u. It has the Display-only bk.action.wearables.* functions, among them ShowToast 23898 (ifu), ShowToastV2 24489 and NativeOnClickAction 23958. The Meta AI app's table has the rest under the same ids.

Icons

An icon is drawable://<name>_filled_32 or _outline_32, which the Display draws from its own set. Meta's cards add a fallback: drawable://<name>_filled_32/?img_url=<encoded URL>, the URL https://static.xx.fbcdn.net/assets/?set=wearables_icons&name=<name with dashes>-filled-32-light&density=1.

The CDN answers 404 for a name it lacks, so it can check a name. It sends Access-Control-Allow-Origin: *. Found there and in Meta's cards:

Set Names
Weather illustrations, in colour, no _filled_32 bks_sunny, bks_partly_cloudy, bks_cloudy, bks_rainy, bks_snow, bks_thunderstorm, bks_foggy; at night bks_nt_clear, bks_nt_partly_cloudy, bks_nt_cloudy, bks_nt_rainy, bks_nt_snow, bks_nt_thunderstorm, bks_nt_foggy
Glyphs small_triangle_up, small_triangle_down, chart_line, trophy, checkmark_stacked_folder, horizontal_line_circle, plus_circle, phone_x

Missing on the CDN: bks_clear, bks_snowy, bks_windy, bks_drizzle, bks_mostly_cloudy. A tint (image key 35) would flatten an illustration's colours, so Meta's weather images carry none.

Reference code: Panels.kt, BloksRelay.kt, DatLayout.kt, BriefingCards.kt

Open questions

  • How the Display reads an answer on svc43 type 12, and whether Visor's minimal action {"layout":{"bloks_payload":{"data":[],"ft":{},"action":"\t(e2f 1)"}}} runs the click's done callback.
  • How an action can refresh an open detail, with bk.action.bloks.InvalidateCachedAsyncComponents or a new fetch.
  • What the pager's key 42 and Flexbox keys 56 and 57 do.
  • Whether ShowToast's AFFIRMATIVE draws a check.
  • The width of a Briefing card on the Display.

To use this from an app, without the protocol: Briefing cards.