Repository navigation
Conversation
…nected to last and keeps each pair's MobileConfig, settings, feature switches, languages, wake word and readings apart; the home swipes between pairs, each shown as Meta pictures it with its name, batteries and Connect, then a page to set up another; a name given on the home reaches the glasses at their next connection (#15)
…ever connected or looked at, to try the pair pages with one pair
… does (parameters 27 to the glasses' 31), gets one HKDF key for AES and HMAC, which ended its link at the first frame with a MAC failure; the peer's EndLinkSetup is taken on a channel of its own, 0x9001 on the band; the LE transport takes a default PSM; debug builds trace small DataX payloads whole
…ityResponse field 5, as the Meta app sends it (the Neural Band has one, and Meta's pair answered 500 without it); provisioning hands back the device certificate and the device_ec_public_key of Meta's final receipt, and AirShield key hints can be checked against a key
…ate, the common state under field 1, which read as battery 0% and no case; it is unwrapped for the Display, and state that comes before svc100 names the model waits for it
… device type (resolution, video length, EIS and capture audio shown, aspect ratio and landscape hidden); conversation focus, hearing correction and group conversations are left out on the Display, whose firmware ships none of their code
…r its own PSM and a key of its own, then its battery on the home and in Settings and its wrist set from there; Visor answers the Display's lease on the band (svc150) as the Meta app does and steps back from it while the Display holds it; setup no longer offers the band as glasses, and the Display's settings show again (they looked for hypernova in a fingerprint that says greatwhite)
… sends its own credential, refuses ours and never ends link setup, so svc100 is never asked) count as a refused key, and the home offers Set up again instead of calling them asleep or out of reach
…lasses' own square at the size they draw it, size, speed (as a multiple of the glasses' default) and scroll or pages, then Show on glasses, Update and Close; started as the Meta app starts it, svc28 StartApp 2000 for app 35 with the text and its look as intent data, closed with StopApp 2002
…t (select, back, scroll, Meta AI, wake and sleep, apps), each counted three times as the band hears it; the page takes the band from the Display, turns on its gesture streams (StreamControl, the map by stream type with priority 90 and GenericC50, the old bool too) and acks each gesture (GestureAck, MWA_ANDROID, direct) as the Meta app does, then gives it back. A single tap waits 420 ms for the double the band reports right after it. Settings > Neural Band can buzz the band (Haptics vibrate, units unknown). The home's Display cards are an icon, a name and a status
… the Display while the Display is connected and takes it only for the Gestures page or one errand (the wrist, a buzz); its battery, how tight it sits and which way round it is come from the Display's own device state (svc28 fields 23, 30, 34), on the home, the Gestures card and Settings
…s the other Meta product ids: Ray-Ban Display 270 and 271, and the Neural Band 1538 in setup. Topic choice rows drop hidden options unless the stored value is one of them.
…nds GlassesPresence, a CompanionDeviceService with the background permissions the Meta app holds, and it starts the connection for the stored pair from the background, where a foreground service may not start otherwise. Visor asks the system to observe each association on every resume, which also covers the return from Android's association dialog; API 36 matches the association by id, 33 to 35 and 31 to 32 by address. Nothing is done when the glasses disappear.
…removed on the glasses too, as the sent one is named by its key, provider and uuid; the glasses' app icon requests are answered with a 78 x 78 JPEG icon, or "unknown package"; the glasses' acks are logged; and chat messages say they are text, so the glasses offer smart replies. Co-Authored-By: Claude Haiku 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018hwZC33my6atwfE1RxLLja
…ough the service's reconnect, so a second pair coming into range does not take over the connection
…o a Display's Glasses page lists the saved ones, removes them, and adds one with the phone's current network name prefilled; the glasses check a new network and say whether the password was wrong.
…he Display shelf. Visor sets the glasses' hn_demos.enable_hn_screencast switch if it is off, opens the screencast on svc23464 with the Meta app's encoder defaults, and decodes the H.264 frames from svc23463 into a square black page with Start and Stop. Leaving the page stops the stream; the card says idle or live.
Glasses that no longer know this phone's key still send their own svc36 credential, refuse ours and then withhold EndLinkSetup. The link never reaches READY, the canary is never asked, and every attempt ended as LINK_DOWN: "nothing answered", "The glasses are not answering". Their credential arriving is an answer, so a refused key with it is now EVICTED. The verdict is kept through the reconnect ladder until a link is READY, so the notification keeps saying the key is refused. - The trust result is reset at each attempt, so a verdict never reads the last attempt's exchange. - The bundle state is compared with what is stored, not start()'s copy: a refused key is judged on every retry, and a pair forgotten in the middle of one must not be saved back. - The canary deadline no longer cancels itself through judge(), which dropped a verdict that had a state to save. - The glasses' refusal status goes into the event log.
Glasses nearby that keep refusing the key looked asleep on the home, the same pill as a pair folded on the table, with nothing to do about it. While the verdict is EVICTED and the link is not up, the pill on the home and in Settings reads "Key refused. Set them up again", and a tap opens the login for Change owner.
In the field case the Meta AI app had taken the glasses back, and it takes them again after Change owner unless it is gone first: it is relaunched as the glasses' companion device service and reconnects. With it installed the refused pill now says Meta AI may have taken them, and opens a sheet with both steps in order: uninstall it (the system's app page), then set the glasses up again.
…are not ready (they refuse every service), so the verdict holds instead of the home saying Ready; the refused message is the status pill's capsule with the error dot; and setting the pair up again takes those glasses as soon as they are heard in pairing mode, with nothing to pick
…sence, REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE, without which the observing was refused
…age and goes straight to linking, and one heard nearby is taken whether or not it is in pairing mode
# Conflicts: # app/src/main/kotlin/com/macedonga/visor/home/HomeScreen.kt
# Conflicts: # app/src/main/res/values-it/strings.xml # app/src/main/res/values/strings.xml
…e captions or translation as the Meta app does (svc28 StartApp for app 31 with the action and the two languages) and lists each turn as the glasses send it back on svc72, in the text they show. Captions run only with Meta's pack for the language: the page offers it with its size, downloads it and installs it through the glasses' OTA service (svc29 start, install request, the zip on airship ota, then the feature change that turns it on), as the Meta app does; a pack pushed on airship language_resource arrives and turns nothing on.
… the Meta app does: web app management (type 15: create, update, delete, list and the developer mode status, answered with 16) against Visor's own list, cookies (11, answered with 9) and Web Bluetooth scans (17, answered with 20 and no devices). The list goes to the glasses as dev_mode_web_app_<n> entries of the partner_app_settings setting (a PartnerAppSettings map: title and URL), with developer_mode on. The Display's settings get a Web apps page: add a page by name and https address, remove it, open it on the glasses (a svc56 lease for the browser's service, then OPEN on svc55074), and a row that turns on the browser's MobileConfig switches for web apps (web_on_hn web_app and web_app_connections) when they are off, which needs a restart. The settings catalogue now names partner_app_settings' item fields. Not tried on the Display yet.
…lease that needs Wi-Fi is now granted when the phone can take it (Wi-Fi on, Wi-Fi Direct allowed, the Live view not using Wi-Fi): Visor answers OK, then moves to a Wi-Fi Direct session with the glasses the way media and the Mirror do, pushes the internet switch's state (svc41108) on a channel it opens there so the Display's apps take the tunnel over Wi-Fi, and comes back to Bluetooth once no lease is held and the tunnel has been idle for two minutes, or when the Live view starts or the Wi-Fi link drops; the state is pushed again on Bluetooth. Otherwise the lease is refused as before, with the reason logged. Not tried on the Display yet.
…he Accounts page gets Facebook and Instagram rows. Linking one mints the accounts app's token from the user's Meta login, finds the account linked in the user's Accounts Center (MetaLinkedAccounts) and its tokens for the glasses (MetaLinkedAccountAccessAndFirstPartyTokensQuery, as com.facebook.stella), and sends MetaLinkedAccountSyncRequest (type 6: session, account type, obfuscated id, login, the access and first-party tokens), answered by 14. The account metadata the Meta app adds from per-provider queries is not sent. Messenger and Instagram DM media are fetched by those apps on the phone through their own IPC in the Meta app, so the data fetcher still turns them down; WhatsApp's encrypted media was already served. Not tried on the Display yet.
…es now wait for one of eight send slots, so the link's own replies (the delivery check, the canary, the device state) queue behind at most eight of them; a TCP retransmit resends only the oldest unacknowledged segment instead of the whole window every 1.5 s while holding the flow's lock; and tunnels built on an earlier connection are closed when the glasses come back, where they kept writing under the old link's keys and retransmitting for up to ten minutes. These are code faults that fit "the link dropped every few seconds with internet sharing on, right after a Display reboot"; that they were its cause is not proven.
…took a band already bonded as "Meta Band", and nothing in Visor bonded one, so on a new phone it always ended in "pair the band with this phone first". It now listens 15 s for a Meta band's advertisement (company 0x01AB, product 1537 or 1538), prefers one in pairing mode, and bonds it before the change of owner. A failure while linking an account on the Accounts page is logged there instead of taking the app down. The rest of the clean-install path for the Display and the band was read through without other faults found. Not tried on the band yet.
…se: Visor asks Meta's app store (WearablesAppStoreCatalogQuery, with the user's token, for the Display's serial and its wearables release version, which the glasses report in svc100 field 9) and lists the entries that are web apps (those with a web_app_url), each with Add, or "On the glasses" when it is there already. A catalogue app goes to the glasses like a developer one, as a dev_mode_web_app_<n> entry of partner_app_settings, with Meta's signed manifest in DisplayConfig field 3. An empty catalogue and a failed fetch each have their own state. Icons are not shown. Not tried on the Display yet.
…s only H.264, where the Ray-Ban Meta streams HEVC, and Visor decoded HEVC only. The stream's codec is now read from its parameter sets (or its first pictures) and every user follows it: the Live view's decoder, the still frame Live AI hands the model, the recording and the replay ring, and the broadcast, which sends H.264 as it is. The event log names the codec once per stream. An HEVC stream takes the same path as before. Not tried on the Display yet.
… a provider that exists and is enabled (fused, GPS when precise, network, passive) and answers ERROR_OTHER when there is none or the request fails, where it threw and left the glasses waiting. A caption pack is downloaded only when the glasses are connected. The L2CAP open's watchdog and a connect that has just succeeded no longer both win: before, the watchdog could close a socket that had opened and Visor kept the closed one. A bands file that cannot be read is logged and kept aside as bands.json.bad instead of being overwritten.
… found Display behaviour reaching other glasses; each is now gated to the Display: the Live AI keep-alive's interactionId (ev392 field 4), mirroring the SMS app's notifications (other glasses get texts over Bluetooth, so they came twice) and keeping their conversations, the notification removal (svc46 type 1022), and opening svc26 with the sharing service first among airship's takers. AirShield's Multikey stays on when the peer leaves EnableEncryption field 5 out, as it always was. A Meta call answered with OAuth error 190 now forgets the token and tries once more with a fresh one everywhere (firmware, band and pack offers, the frame look, account linking), not only in the login's own GraphQL. Device state held while svc100 is unanswered is applied after 5 s, as before the hold.
…anting the lease moved the whole session to Wi-Fi Direct, and the app then took the glasses for disconnected: "out of reach" while Meta AI still answered, no notifications, Mirror and the Display's pages unavailable, and the session stayed on Wi-Fi after the lease ended. A Wi-Fi link lease is refused again (WIFI_DIRECT_NOT_AVAILABLE). This reverts af0b76c.
…Display but not in Visor showed "Not set up" while its battery was known. The band's summary and page now show the battery and fit the Display reports; Set up stays for Visor's own link to the band (wrist, buzz, firmware).
…ected they went to the glasses as a remote turn (ev337 then ev52), but the Display skips StartRemoteInteraction when no assistant session runs, which is whenever the wearer has not just spoken to it (seen in its log), so the turn never started there. This reverts bf30bb0.
…coder found nothing for the Maps app's searches ("cafe", "park", "attraction" all came back with 0 places). Searches now go to Nominatim within the asked radius around the phone, nearest first, and farther when nothing is that close; it reads a kind of place as one and also finds names and addresses. Results carry the address, the kind of place, the phone number when known, and the walking distance. As the Meta app does, a prewarm is answered at once with no places and its search fills a five-minute cache; requests are spaced a second apart, as Nominatim asks. A search without a known position takes a fresh fix first.
…and wrote it over every dev_mode_web_app entry of partner_app_settings, each time the page opened: a web app added with the Meta app was deleted, and none of those were ever listed. The page now lists the glasses' setting as it is (title, page and icon) and changes only the entry it adds, removes or renames, refusing to write a value it cannot read. The "Turn on web apps" row is gone: it read stale MobileConfig values, asked to enable switches that were on, and the glasses need no restart. Developer mode is written only when it is off.
…MetaLinkedAccounts answers data.wearable_linked_accounts with obfuscated_id, account_type, display_name and is_enabled_for_wearable (seen today); Visor looked for obfuscated_account_id, so every account came back "not linked" and nothing was sent to the glasses. The Accounts page now reads the list when it opens and shows each provider as linked, with its name, or turned off for glasses, before anything is tapped.
…y's cloud configuration service knows only that request; it answered the Meta app's newer SaveNetworkList (type 18) with 0xD001, unknown type, so no network could be added. The list stays as the fallback.
…to the Display; the page now asks the Display over svc41109 (GET_BLE_PAIRING_INFO) whether a band is paired and connected, and shows its battery and fit from the Display's state. The phone-side rows are gone: Vibrate, Wrist, Firmware and Set up worked only on a band the phone owned, which a band paired with the Display is not.
…king button sends svc70 type 28 (TriggerProviderLinking: provider, request id, source, scenario), which Visor did not serve, so the button did nothing. As the Meta app does, the phone now posts a notification (link or reconnect WhatsApp, Instagram, Messenger, Facebook or Threads) that opens Visor's Accounts page, and answers type 29 with whether it was shown.
…he Display's log shows the card arriving and parsed as a dialog card (SimpleTemplate {title, subtitle}), which shows the title only: with the question there, the wearer saw the question and no answer. The title is now the answer; the Display shows the question from the turn itself.
…sion. WhatsApp and Instagram on the Display wait for a svc41107 link lease that needs Wi-Fi; refused, WhatsApp showed "loading chats" forever. As the Meta app's link manager does, the one session now moves to Wi-Fi while a lease holds it: the main connection itself reconnects on the Wi-Fi link, so every service, notifications and the app's state go with it (the earlier attempt ran a second session and left the app thinking the glasses were gone). The link is the network the phone is on when the glasses keep its passphrase (JoinAccessPoint with it, so they stay on that network and its internet), else a Wi-Fi Direct group of the phone's. The session comes back to Bluetooth 30 s after the last lease ends, when it does not come up on Wi-Fi in 20 s, or when it drops there. The glasses page says when the link is Wi-Fi. A debug command (WIFI_LINK) holds and lets go of a lease for testing. Not tried on the Display yet.
…rvice moves a session that is not on LE onto LE, and a session on Wi-Fi is not on LE either: within a minute it would have reopened the session on the same Wi-Fi link and lost the Bluetooth one to come back to. That move and the tile's retry now leave Wi-Fi alone, the retry going back on Bluetooth. The Wi-Fi link is refused while the Live or a media import uses Wi-Fi, and when the session is reopened on Bluetooth some other way the link's own Wi-Fi Direct group is removed, unless the Live or an import paused the session and took the glasses on a group of its own.
…s shoot landscape only with their own landscape_mode_enabled and Meta's mwa_ios_landscape_mode.enabled both on, and Meta's server had turned its switch off: the Landscape mode switch did nothing. With the switch on, Visor now writes Meta's switch on in the glasses' configuration (reading it first if this run has not); the camera reads it at boot, so the glasses need a restart after. Not tried on the glasses.
…n firmware 7238 the camera takes the orientation from capture_aspect_ratio (1 landscape, 0 portrait), which the glasses keep at portrait while only landscape_mode_enabled is on: their log shows the camera app watching it, and a photo taken with the switch on, Meta's flag on and two restarts still came out tagged portrait. The switch now sets capture_aspect_ratio to landscape, and back to portrait when it is turned off; Media orientation keeps its own row. The settings table gets the key's namespace and default (individual_device_settings, 0). Meta's configuration flag still goes on for the older path. Not tried on the glasses yet.
…andscape (#35). With Media orientation at landscape (capture_aspect_ratio 1) the glasses still take the whole portrait frame and only mark the capture, a byte in its metadata (slot 34 of the capture's info): the Meta app crops it on the phone (LandscapePhotoCropEngine for photos, its native import for videos). Visor now reads that mark and, as it brings a capture over, keeps the middle 4:3 band across the whole width, which is the Meta app's crop when it has nothing to follow: a photo's JPEG is cut from the developed still, a video is re-encoded once with Media3 Transformer (HEVC, the sound as it was), and a video this phone cannot crop is kept whole. Media orientation is now the one control: Landscape mode leaves the camera page, and it and Meta's landscape flag follow Media orientation. Measured on the Gen 2 (7238): photos and a video taken at landscape came marked, a test video came out 2448x1836 and upright.
…rmware 7238 steadies only 1080p (its camera app watches the two-stage settings, none of the 3K or 60 fps ones), so 3K, and any video with two-stage stabilization off, came over unsteadied; the Meta app stabilizes those in its own import from the motion log each video carries. Visor now does the same as it saves a video: the gyro gives the head's rotation at each frame, the path is smoothed, and each frame is turned by the difference inside a crop margin, one GL pass in the Media3 re-encode that also cuts landscape captures. A video whose size is one of the glasses' own two-stage outputs is left alone. The capture's own stabilization (Auto, High, Medium, Low, read from its metadata) picks margin and smoothing: 15%/0.2 s, 20%/0.3 s, 15%/0.2 s, 10%/0.12 s. Calibrated against a shaky 1080p walk from this pair: the IMU's axes are Android's, a frame's moment is its mid-exposure plus 10 ms, the focal length 0.78 of the width; on the phone that walk lost 44% of its sideways shake, 66% of its vertical and 39% of its roll. Where a frame would leave the margin, the smoothed path is drawn toward the head there and smoothed again, which kept the shake removal that scaling the turn down threw away. 3K's focal length is assumed to scale with width; not yet checked on a moving 3K video. A debug action, STEADY, runs it again on a pushed file.
# Conflicts: # app/src/main/res/values-it/strings.xml # app/src/main/res/values/strings.xml # core/assistant/src/main/kotlin/com/macedonga/visor/core/assistant/Assistant.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support for the Meta Ray-Ban Display and its Neural Band, and for more than one pair on a phone.
Done
instagram://,sgmessaging://linksconnection_monitor(4),wearables_ping(76),motion_activity_service(101): the delivery check is confirmed (seen on the Display), the ping says whether the phone is online, motion activity answers as the Meta app does with driving detection offphone_book_sync11006)To do for full Display support
Phone services the Display asks for and Visor does not answer yet
maps_constellation11004,smartglasses_maps_persistent_store87)media_backsync(1999) andmedia_capture_state(2000)lease_service41107)partner_ecosystem9012): the playing app and its album art are served; playlists, likes and app launch are notMessaging and accounts
Web apps (#13)
partner_app_settings)Meta AI
Captions
Neural Band
Firmware
Mirror
Bugs
Not possible on firmware 6995
Before merging
Closes #15. Part of #13.
🤖 Generated with Claude Code
https://claude.ai/code/session_01C9CnuyERf89oTF9Lhz1g79