@mentra/engine 3.4.0-dev.1207 → 3.4.0-dev.1209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/build/facades/glasses.d.ts.map +1 -1
  2. package/build/facades/glasses.js +5 -3
  3. package/build/facades/glasses.js.map +1 -1
  4. package/build/generated/releaseMetadata.js +5 -5
  5. package/build/generated/releaseMetadata.js.map +1 -1
  6. package/build/services/AppRegistry.d.ts +2 -0
  7. package/build/services/AppRegistry.d.ts.map +1 -1
  8. package/build/services/AppRegistry.js.map +1 -1
  9. package/build/services/LocalMiniappRuntime.d.ts +2 -0
  10. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  11. package/build/services/LocalMiniappRuntime.js +18 -1
  12. package/build/services/LocalMiniappRuntime.js.map +1 -1
  13. package/build/services/MentraJSCrashController.d.ts +2 -0
  14. package/build/services/MentraJSCrashController.d.ts.map +1 -1
  15. package/build/services/MentraJSCrashController.js +4 -0
  16. package/build/services/MentraJSCrashController.js.map +1 -1
  17. package/build/services/MentraJSRouter.d.ts.map +1 -1
  18. package/build/services/MentraJSRouter.js +14 -3
  19. package/build/services/MentraJSRouter.js.map +1 -1
  20. package/build/services/MiniappLauncher.d.ts +6 -0
  21. package/build/services/MiniappLauncher.d.ts.map +1 -1
  22. package/build/services/MiniappLauncher.js +20 -3
  23. package/build/services/MiniappLauncher.js.map +1 -1
  24. package/build/services/fleet/FleetReporter.d.ts.map +1 -1
  25. package/build/services/fleet/FleetReporter.js +43 -0
  26. package/build/services/fleet/FleetReporter.js.map +1 -1
  27. package/build/services/fleet/fleetCollector.d.ts +1 -1
  28. package/build/services/fleet/fleetCollector.d.ts.map +1 -1
  29. package/build/services/fleet/fleetCollector.js +146 -5
  30. package/build/services/fleet/fleetCollector.js.map +1 -1
  31. package/build/services/fleet/fleetEvents.d.ts +39 -3
  32. package/build/services/fleet/fleetEvents.d.ts.map +1 -1
  33. package/build/services/fleet/fleetEvents.js +66 -22
  34. package/build/services/fleet/fleetEvents.js.map +1 -1
  35. package/build/services/fleet/fleetQueue.d.ts +26 -0
  36. package/build/services/fleet/fleetQueue.d.ts.map +1 -1
  37. package/build/services/fleet/fleetQueue.js +94 -8
  38. package/build/services/fleet/fleetQueue.js.map +1 -1
  39. package/build/services/fleet/telemetryLimits.d.ts +16 -0
  40. package/build/services/fleet/telemetryLimits.d.ts.map +1 -0
  41. package/build/services/fleet/telemetryLimits.js +69 -0
  42. package/build/services/fleet/telemetryLimits.js.map +1 -0
  43. package/build/services/installMiniapp.d.ts +13 -0
  44. package/build/services/installMiniapp.d.ts.map +1 -1
  45. package/build/services/installMiniapp.js +64 -1
  46. package/build/services/installMiniapp.js.map +1 -1
  47. package/build/services/miniappReleaseInstall.js +1 -1
  48. package/build/services/miniappReleaseInstall.js.map +1 -1
  49. package/build/stores/apps.d.ts.map +1 -1
  50. package/build/stores/apps.js +16 -1
  51. package/build/stores/apps.js.map +1 -1
  52. package/package.json +8 -8
  53. package/src/facades/glasses.ts +5 -3
  54. package/src/generated/releaseMetadata.ts +5 -5
  55. package/src/services/AppRegistry.ts +2 -0
  56. package/src/services/LocalMiniappRuntime.ts +20 -1
  57. package/src/services/MentraJSCrashController.ts +5 -0
  58. package/src/services/MentraJSRouter.ts +15 -3
  59. package/src/services/MiniappLauncher.ts +18 -2
  60. package/src/services/fleet/FleetReporter.ts +40 -0
  61. package/src/services/fleet/fleetCollector.ts +160 -6
  62. package/src/services/fleet/fleetEvents.ts +104 -20
  63. package/src/services/fleet/fleetQueue.ts +100 -7
  64. package/src/services/fleet/telemetryLimits.ts +78 -0
  65. package/src/services/installMiniapp.ts +78 -2
  66. package/src/services/miniappReleaseInstall.ts +1 -1
  67. package/src/stores/apps.ts +19 -2
@@ -1 +1 @@
1
- {"version":3,"file":"fleetCollector.js","sourceRoot":"","sources":["../../../src/services/fleet/fleetCollector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The Fleet collector: what the engine observes about the phone, its glasses and its miniapps, as Fleet records in\n * the durable queue.\n *\n * It listens to the engine's own state (the glasses store, the running-miniapp registry, the native built-ins\n * executing, the app state) and to `fleetEvents` (launches and photo stages, emitted by lifecycle hooks), never to UI\n * screens. It writes records; the uploader (a separate piece) delivers them. One collector run belongs to one\n * `start()`: its partition and collector-session ID are fixed for its life, and everything it holds is dropped by\n * `stop()`.\n *\n * Usage is measured as sessions: an activity (the engine running, the Mentra App in the foreground, glasses\n * connected, one miniapp executing) opens a session when it begins and closes it when it ends; the foreground with\n * hysteresis (see FOREGROUND_SETTLE_MS), so the app state's blips are not sessions of their own. A session's\n * `elapsedMs` is cumulative monotonic time, and each checkpoint packs every open session, so a session that is\n * cut off simply ends at its last checkpoint. Checkpoints come every 60 s while glasses are connected or the Mentra\n * App is in the foreground, every 15 minutes otherwise (only the engine active, or miniapps executing in the\n * background without glasses, such as Notify), and at once when a session ends. The slower cadence reports the same\n * time, only less often; what it risks is the time since the last checkpoint if the process dies. A session also\n * ends when it reaches the longest time one record may carry (7 days), and a new one carries on from there.\n *\n * Snapshots come at start, after a change worth one (glasses connecting or disconnecting, and while they are connected\n * a battery move of 5 points, a charging change or a new version), and with the first checkpoint 15 minutes or more\n * after the last snapshot, so the two share a wake-up and an upload. On the 15-minute cadence that snapshot is\n * written only if it would say something new. A phone retrying glasses that are away moves between scanning,\n * connecting and disconnected every few seconds, all day: none of that is a change worth a snapshot, or something\n * new. A phone with no glasses connected and the Mentra App in the background so writes about 100 records a day, a\n * checkpoint every 15 minutes, whether or not miniapps execute in the background or its glasses are being retried.\n *\n * Every snapshot carries the phone's own battery. The collector asks its source (`PhoneBatterySource`) for a new reading\n * only at start and on each checkpoint wake-up, and a reading is worth a snapshot of its own on the same terms as the\n * glasses' battery: once it is first known or stops being known, after a move of 5 points, or a charging change. A\n * phone draining all day so adds about 20 snapshots, not one per reading.\n *\n * The installed miniapps are reported as a `miniapp_inventory` record: once when a run starts (a new run is a new\n * account's or a new process's, which has never been told), and again, after a short settle, whenever the inventory\n * source says it changed and what it lists is not what the last record said. Never in a snapshot. The source is\n * injected (`InventorySource`); until the app wires one the collector sends no inventory, as it cannot tell an empty\n * phone from an unwired one.\n *\n * Time counts only while the collector was watching. The monotonic clock (React Native's `performance.now()`, the C++\n * steady clock) runs while the device is awake on both platforms, but not the same way through sleep, and the rules\n * below handle both:\n * - On Android it is CLOCK_MONOTONIC, which pauses in deep sleep. A sleep shows as the wall clock running ahead of\n * it: the sessions end at the monotonic time that was observed, and the jump is a gap.\n * - On iOS libc++'s steady clock reads CLOCK_MONOTONIC_RAW, which keeps counting through sleep. A sleep shows as a\n * checkpoint overdue by the monotonic clock: nothing ran, so the sessions end at their last checkpoint, and the\n * span since it is a gap.\n * On either platform, a checkpoint overdue by the monotonic clock means the process was suspended while that clock\n * ran, and a wall-clock jump the monotonic clock did not share is a clock that was changed.\n *\n * Nothing here may break or slow the paths it watches: every entry point catches its own failures, and nothing\n * thrown by the queue, the clock or a store reaches a caller.\n */\nimport * as Application from \"expo-application\"\nimport Constants from \"expo-constants\"\nimport * as Device from \"expo-device\"\nimport {AppState, Platform} from \"react-native\"\nimport {\n FLEET_CAPABILITIES,\n FLEET_INSTALL_REASONS,\n FLEET_LIMITS,\n FLEET_SCHEMA_VERSION,\n FleetMiniappInventoryPayloadSchema,\n type FleetActivity,\n type FleetDeviceBinding,\n type FleetInstallReason,\n type FleetMiniappInventoryPayload,\n type FleetRecord,\n} from \"@mentra/cloud-protocol\"\n\nimport {useGlassesStore} from \"../../stores/glasses\"\nimport {BgTimer} from \"../../utils/timers\"\nimport {miniappRunningRegistry} from \"../MiniappRunningRegistry\"\nimport {nativeMiniappExecution} from \"../NativeMiniappExecution\"\nimport {fleetEvents, type FleetLaunchEvent, type FleetPhotoEvent} from \"./fleetEvents\"\nimport {newId, phoneDeviceId} from \"./fleetIds\"\nimport type {FleetQueue} from \"./fleetQueue\"\nimport {appPhoneBattery} from \"./phoneBatterySource\"\nimport {\n glassesProduct,\n isSimulatedGlasses,\n provisionalBinding,\n serialBinding,\n usableSerial,\n type GlassesIdentitySource,\n} from \"./glassesIdentity\"\n\nexport interface FleetCollector {\n /**\n * Opens the engine session, the glasses and running miniapps, and the foreground session once the app has been\n * active long enough to count, and takes a snapshot.\n */\n start(ctx: {partition: string; collectorSessionId: string}): void\n /** Checkpoints every open session as ended, into the partition `start` was given, and stops listening. */\n stop(reason: \"engine_stopped\" | \"account_changed\" | \"not_installed\"): void\n /** Writes one packed `usage_checkpoint` for every open session. */\n flushCheckpoint(): void\n}\n\n/** One installed miniapp, as the inventory source reports it. Its reasons are why it is installed, not where it came from. */\nexport interface InstalledMiniapp {\n packageName: string\n versionName: string\n /** The installed release's digest. */\n digest: string\n /** Why the phone holds it: `bundled`, `explicit`, `manifest` and `assignment`, which can hold together. At least one. */\n reasons: readonly FleetInstallReason[]\n}\n\n/**\n * Where the collector learns what is installed. The app's registry implements it (the wiring is the registry's side);\n * tests fake it.\n */\nexport interface InventorySource {\n /** The miniapps installed now, or null while that is not known yet (nothing is reported then). Must be cheap. */\n list(): readonly InstalledMiniapp[] | null\n /** `listener` is called, on any stack, after the installed set or any miniapp's version, digest or reasons changed. */\n subscribe(listener: () => void): () => void\n}\n\n/** One reading of the phone's battery: `level` a whole percent from 0 to 100. */\nexport interface PhoneBatteryReading {\n level: number\n charging: boolean\n}\n\n/**\n * Where the collector learns the phone's battery. The app's is `appPhoneBattery` (expo-battery); tests fake it.\n */\nexport interface PhoneBatterySource {\n /** The last reading; `unsupported` for a phone that cannot report one; null while none is known. Must be cheap. */\n read(): PhoneBatteryReading | \"unsupported\" | null\n /** Asks for a new reading, which arrives later through `subscribe`. Must be cheap. */\n refresh(): void\n /** `listener` is called, on any stack, after the reading changed. */\n subscribe(listener: () => void): () => void\n}\n\ntype Capability = (typeof FLEET_CAPABILITIES)[number]\ntype UsageSession = Extract<FleetRecord, {kind: \"usage_checkpoint\"}>[\"payload\"][\"sessions\"][number]\ntype SnapshotPayload = Extract<FleetRecord, {kind: \"snapshot\"}>[\"payload\"]\ntype GlassesPayload = NonNullable<SnapshotPayload[\"glasses\"]>\ntype PhoneBatteryPayload = NonNullable<SnapshotPayload[\"phone\"][\"battery\"]>\ntype ConnectionState = GlassesPayload[\"connection\"][\"state\"]\ntype BatteryPayload = NonNullable<GlassesPayload[\"battery\"]>\ntype Firmware = NonNullable<GlassesPayload[\"firmware\"]>\ntype GapReason = \"clock_untrusted\" | \"reporter_stopped\"\n\ninterface RecordBase {\n schemaVersion: typeof FLEET_SCHEMA_VERSION\n recordId: string\n phoneDeviceId: string\n collectorSessionId: string\n sequence: number\n observedAt: string\n capabilities: Capability[]\n}\n\nconst FAST_CHECKPOINT_MS = 60_000\nconst IDLE_CHECKPOINT_MS = 15 * 60_000\nconst SNAPSHOT_INTERVAL_MS = 15 * 60_000\n/** State changes this close together are one snapshot. */\nconst SNAPSHOT_DEBOUNCE_MS = 2_000\n/**\n * How far the wall clock may part from the monotonic clock between checkpoints, and how late a checkpoint may be,\n * before the collector stops believing the span between two checkpoints.\n */\nconst CLOCK_DRIFT_LIMIT_MS = 2 * 60_000\nconst BATTERY_SNAPSHOT_STEP = 5\n/** Inventory changes this close together are one record: an install changes the set, then its reasons, then its digest. */\nconst INVENTORY_DEBOUNCE_MS = 2_000\n/**\n * How long connected glasses may go without showing a serial number before they are identified without one. They send\n * it, with their Bluetooth address, within a second or two of connecting; this leaves ample room for a slow answer\n * while still identifying a pair that has none well before its first 60-second checkpoint.\n */\nconst IDENTITY_SETTLE_MS = 15_000\n/**\n * The Mentra App is in the foreground, to Fleet, from the moment it becomes active, once it has been active for\n * FOREGROUND_SETTLE_MS since then; and it stays there through a departure shorter than FOREGROUND_GRACE_MS, which, if\n * the app does not come back, ends the visit when the app left. The app state flaps: Android reports the activities\n * around a launch, such as a permission dialog, as the app going to the background, and iOS goes inactive for\n * Control Center, a notification pulled down, Face ID or a system alert. A third of foreground sessions in the device\n * evidence lasted under a second, and a foreground session makes its account active.\n *\n * 2 s is longer than any of those flickers and shorter than a person's look at the app. 5 s spans a dialog or an\n * overlay a person dismisses, which is still one visit; a departure that long is counted in it, at most 5 s a time.\n */\nconst FOREGROUND_SETTLE_MS = 2_000\nconst FOREGROUND_GRACE_MS = 5_000\nconst FOREGROUND_KEY = \"app_foreground\"\n/** At most this many photo stages wait for glasses being identified; a burst beyond it in those seconds is dropped. */\nconst MAX_HELD_PHOTOS = 32\nconst MAX_TEXT = 128\n/** A session cannot outlast several caps between two checkpoints; this only bounds a loop. */\nconst MAX_CAP_TURNS = 8\nconst FLEET_ID = /^[A-Za-z0-9._:-]+$/\n\n/**\n * Glasses models that have no battery reporting. Their battery is `unsupported`, not `unknown`, and a record made\n * while they are connected does not claim `glasses_battery`. Every model the Bluetooth SDK connects today reports one\n * (G1, G2, Mentra Live, Mentra Display, Mach1, Z100, NIMO and AR99 all set the glasses' `batteryLevel`), so the list\n * is empty; a model that comes without one is named here, as `deviceModel` names it.\n */\nconst MODELS_WITHOUT_BATTERY: ReadonlySet<string> = new Set<string>()\n\n/**\n * What the phone measures without glasses. With glasses connected it measures all of them, less the battery of glasses\n * that cannot report one. A phone that cannot report its own battery does not claim `phone_battery`.\n */\nconst PHONE_CAPABILITIES: Capability[] = [\n \"glasses_connection\",\n \"miniapp_execution\",\n \"app_foreground\",\n \"engine_active\",\n \"photo_operations\",\n \"phone_battery\",\n]\n\nfunction warn(what: string, error: unknown): void {\n // Only the failure's message: an error from here must never carry a package, a serial or a record into the logs.\n console.warn(`FleetCollector: ${what} failed:`, error instanceof Error ? error.message : \"unknown error\")\n}\n\nfunction text(value: string | null | undefined): string | undefined {\n const trimmed = value?.trim().slice(0, MAX_TEXT)\n return trimmed ? trimmed : undefined\n}\n\nfunction iso(wall: number): string {\n return new Date(wall).toISOString()\n}\n\n/**\n * The inventory record's payload for what the source lists, or null when there is nothing to send: the source does not\n * know yet, or what it listed cannot make a valid record. A miniapp that cannot be described (no package, version or\n * digest, or no known reason) is left out and counted in the warning, not allowed to sink the rest. The list is sorted\n * by package, one entry per package, and a listing past the contract's 500 keeps the first 500, so the same phone always\n * says the same thing.\n */\nfunction inventoryPayload(listed: readonly InstalledMiniapp[] | null): FleetMiniappInventoryPayload | null {\n if (listed === null) return null\n const byPackage = new Map<string, FleetMiniappInventoryPayload[\"miniapps\"][number]>()\n let skipped = 0\n for (const app of listed) {\n const packageName = text(app?.packageName)\n const versionName = text(app?.versionName)\n const digest = text(app?.digest)\n const reasons = FLEET_INSTALL_REASONS.filter((reason) => app?.reasons?.includes(reason))\n if (!packageName || !versionName || !digest || reasons.length === 0) {\n skipped += 1\n continue\n }\n byPackage.set(packageName, {packageName, versionName, digest, reasons})\n }\n const miniapps = [...byPackage.values()]\n .sort((a, b) => (a.packageName < b.packageName ? -1 : a.packageName > b.packageName ? 1 : 0))\n .slice(0, FLEET_LIMITS.maxInventoryMiniapps)\n if (skipped > 0 || byPackage.size > miniapps.length) {\n console.warn(\n `FleetCollector: the inventory left out ${skipped} undescribable and ${\n byPackage.size - miniapps.length\n } surplus miniapp(s)`,\n )\n }\n const parsed = FleetMiniappInventoryPayloadSchema.safeParse({miniapps})\n if (!parsed.success) {\n console.warn(\"FleetCollector: no inventory, what the source listed is not a valid record\")\n return null\n }\n return parsed.data\n}\n\nfunction isForeground(): boolean {\n return AppState.currentState === \"active\"\n}\n\n/** Glasses are connected, and they are not the simulated ones, which are no part of any fleet. */\nfunction realGlassesConnected(): boolean {\n const s = useGlassesStore.getState()\n return s.connection.state === \"connected\" && !isSimulatedGlasses(s.deviceModel)\n}\n\n/** Glasses connected or the Mentra App in the foreground: checkpoints every 60 s. */\nfunction isFastActivity(activity: FleetActivity): boolean {\n return activity === \"glasses_connection\" || activity === \"app_foreground\"\n}\n\nfunction mapConnection(state: string): ConnectionState {\n if (state === \"connected\") return \"connected\"\n if (state === \"disconnected\") return \"disconnected\"\n if (state === \"scanning\" || state === \"connecting\" || state === \"bonding\") return \"connecting\"\n return \"unknown\"\n}\n\nlet packageVersionCache: {engine?: string; sdk?: string} | undefined\nfunction packageVersions(): {engine?: string; sdk?: string} {\n if (packageVersionCache) return packageVersionCache\n const versions: {engine?: string; sdk?: string} = {}\n try {\n versions.engine = text((require(\"../../../package.json\") as {version?: string}).version)\n } catch {\n // Left out of the snapshot.\n }\n try {\n versions.sdk = text((require(\"@mentra/bluetooth-sdk/package.json\") as {version?: string}).version)\n } catch {\n // Left out of the snapshot.\n }\n return (packageVersionCache = versions)\n}\n\n/** The phone's part of a snapshot, or null where the contract has no value for this platform. */\nfunction phoneInfo(): SnapshotPayload[\"phone\"] | null {\n const os = Platform.OS\n if (os !== \"ios\" && os !== \"android\") return null\n const osVersion =\n os === \"android\"\n ? String((Platform.constants as {Release?: string} | undefined)?.Release ?? Platform.Version)\n : String(Platform.Version)\n const model = text(Device.modelName)\n const {engine, sdk} = packageVersions()\n return {\n ...(model ? {model} : {}),\n os,\n osVersion: text(osVersion) ?? \"unknown\",\n // The native application's own version and build number: expo-constants no longer has them.\n appVersion: text(Application.nativeApplicationVersion ?? Constants.expoConfig?.version) ?? \"unknown\",\n appBuild: text(Application.nativeBuildVersion) ?? \"unknown\",\n ...(engine ? {engineVersion: engine} : {}),\n ...(sdk ? {sdkVersion: sdk} : {}),\n }\n}\n\ntype GlassesState = ReturnType<typeof useGlassesStore.getState>\n\n/** The glasses fields the collector reacts to, as one string so the store only calls back when one of them changes. */\nfunction glassesFingerprint(s: GlassesState): string {\n // The store runs this on every update, inside the update: it must not throw into whoever is updating the store.\n try {\n return [\n s.connection.state,\n s.connection.state === \"connected\" && s.connection.fullyBooted ? \"1\" : \"0\",\n s.deviceModel,\n s.serialNumber,\n s.bluetoothMacAddress,\n s.leftMacAddress,\n s.bluetoothName,\n s.appVersion,\n s.buildNumber,\n s.mtkFirmwareVersion,\n s.besFirmwareVersion,\n s.androidVersion,\n s.firmwareVersion,\n s.batteryLevel,\n s.charging ? \"1\" : \"0\",\n ].join(\"\\u0001\")\n } catch {\n return \"\"\n }\n}\n\n/** The glasses' versions that are known (blank ones are left out). The APK version carries its build number. */\nfunction firmwareOf(s: GlassesState): Firmware {\n const apkVersion = text(s.appVersion)\n const apkBuild = text(s.buildNumber)\n const apk = apkVersion && apkBuild ? `${apkVersion} (${apkBuild})` : apkVersion || apkBuild\n const mtk = text(s.mtkFirmwareVersion)\n const bes = text(s.besFirmwareVersion)\n const os = text(s.androidVersion) ?? text(s.firmwareVersion)\n return {\n ...(apk ? {apk: apk.slice(0, MAX_TEXT)} : {}),\n ...(mtk ? {mtk} : {}),\n ...(bes ? {bes} : {}),\n ...(os ? {os} : {}),\n }\n}\n\n/**\n * The glasses as last seen in this run. The native layer clears a pair's identity when it disconnects, so the\n * collector keeps what it saw while the glasses were there: a disconnected pair is still described, and still the\n * same device.\n *\n * A pair is identified, and its binding fixed for the run, once it has shown its serial number, or once it has been\n * connected for IDENTITY_SETTLE_MS without one; until then nothing is attributed to it, and a photo stage waits for\n * it. Glasses are connected a moment before they send their serial and their own Bluetooth address, so a binding\n * fixed sooner would make a provisional device of every pair that has a serial, and key one that has none by its\n * Bluetooth name on some connections and by its address on others. A pair that leaves sooner is identified by what\n * it showed.\n */\ninterface KnownGlasses {\n /** The product (see `glassesProduct`): one pair is one model whatever model string it reports. */\n model: string\n /** What the pair has shown of who it is, each null until it has. */\n identity: PairIdentity\n /** When the pair was first seen connected in this run (monotonic); null while it has only been looked for. */\n connectedSinceMono: number | null\n /** Fixed once the pair is identified. A serial that comes later still replaces a provisional binding. */\n binding: FleetDeviceBinding | null\n firmware: Firmware\n}\n\n/** What tells one pair from another of its model, strongest first: its serial, its own Bluetooth address, its name. */\ninterface PairIdentity {\n serial: string | null\n address: string | null\n name: string | null\n}\n\nconst IDENTIFIERS = [\"serial\", \"address\", \"name\"] as const\n\nfunction lowered(value: string | null | undefined): string | null {\n const trimmed = typeof value === \"string\" ? value.trim().toLowerCase() : \"\"\n return trimmed ? trimmed : null\n}\n\nfunction pairIdentity(s: GlassesIdentitySource): PairIdentity {\n return {\n serial: usableSerial(s),\n // The address the glasses report as their own, the same on every phone; the left arm's for glasses in two.\n address: lowered(s.bluetoothMacAddress) ?? lowered(s.leftMacAddress),\n name: lowered(s.bluetoothName),\n }\n}\n\n/**\n * Whether glasses showing `now` are the pair that showed `before`. The strongest identifier both show decides. One\n * that went blank says nothing (the native layer clears the serial and the address when the link drops), and neither\n * does showing nothing yet: only a difference tells another pair.\n */\nfunction samePair(before: PairIdentity, now: PairIdentity): boolean {\n for (const field of IDENTIFIERS) {\n const a = before[field]\n const b = now[field]\n if (a !== null && b !== null) return a === b\n }\n const shows = (identity: PairIdentity) => IDENTIFIERS.some((field) => identity[field] !== null)\n return !shows(before) || !shows(now)\n}\n\n/** A photo stage seen while the glasses were being identified, kept to be written against them once they are. */\ninterface HeldPhoto {\n observedAt: number\n operationId: string\n payload: Extract<FleetRecord, {kind: \"photo_operation\"}>[\"payload\"]\n}\n\n/** The battery of the pair `known` describes: it goes when a new connection starts or another pair is identified. */\ninterface BatteryReading {\n level: number\n charging: boolean\n /** When the collector saw this value. It is not refreshed by later snapshots or uploads. */\n observedAt: number\n}\n\ntype PhoneBatteryValue =\n | {state: \"measured\"; level: number; charging: boolean}\n | {state: \"unsupported\" | \"unknown\"; level?: undefined; charging?: undefined}\n/** The phone's battery as last read, and when the collector first saw it so. It is not refreshed by later snapshots. */\ntype PhoneBatteryHeld = PhoneBatteryValue & {observedAt: number}\n\n/** A source's reading as a battery state: a level outside 0 to 100, or not a number, is unknown, never a number. */\nfunction phoneBatteryState(read: PhoneBatteryReading | \"unsupported\" | null): PhoneBatteryValue {\n if (read === \"unsupported\") return {state: \"unsupported\"}\n const level = read?.level\n if (typeof level !== \"number\" || !Number.isFinite(level) || level < 0 || level > 100) return {state: \"unknown\"}\n return {state: \"measured\", level: Math.round(level), charging: read?.charging === true}\n}\n\n/** What the last snapshot said, so a change worth a new snapshot can be told from one that is not. */\ninterface SnapshotMarks {\n phoneBattery: PhoneBatteryValue\n /** The binding of the glasses, once they are identified, as a key; \"\" before. */\n identity: string\n /** The glasses were connected. The states short of it (scanning, connecting, disconnected) are all \"not\". */\n linked: boolean\n batteryMeasured: boolean\n level: number\n charging: boolean\n versions: string\n}\n\ninterface Instant {\n wall: number\n mono: number\n}\n\ninterface Session {\n key: string\n activity: FleetActivity\n id: string\n packageName?: string\n /** Glasses sessions: fixed when the session is first reported, and never changed after. */\n binding?: FleetDeviceBinding\n startedWall: number\n startedMono: number\n /** The elapsed time at the last checkpoint that carried this session; null until it has been reported. */\n reportedElapsedMs: number | null\n /** Its activity stopped then: the session is counted up to there, and ends there unless it resumes in its grace. */\n endAt?: Instant\n}\n\ninterface SessionSpec {\n activity: FleetActivity\n packageName?: string\n /** When the activity began, if before the session opens. */\n since?: Instant\n}\n\ninterface Env {\n queue: FleetQueue\n now: () => number\n monotonic: () => number\n modelsWithoutBattery: ReadonlySet<string>\n inventory: InventorySource\n phoneBattery: PhoneBatterySource\n}\n\nconst NONE: ReadonlySet<string> = new Set()\n\n/**\n * The app's inventory source: the registry's side registers itself with `setFleetInventorySource`, and every collector\n * the app creates reads through this. Until one is set it lists nothing known, so no inventory is sent. Setting one\n * counts as a change.\n */\nconst inventoryListeners = new Set<() => void>()\nlet appInventorySource: InventorySource | null = null\nlet stopFollowingSource: (() => void) | null = null\n\nfunction notifyInventory(): void {\n for (const listener of [...inventoryListeners]) {\n try {\n listener()\n } catch (error) {\n warn(\"inventory listener\", error)\n }\n }\n}\n\n/** Wires (or, with null, unwires) the source of what is installed. */\nexport function setFleetInventorySource(source: InventorySource | null): void {\n stopFollowingSource?.()\n stopFollowingSource = null\n appInventorySource = source\n if (source) {\n try {\n stopFollowingSource = source.subscribe(notifyInventory)\n } catch (error) {\n warn(\"following the inventory source\", error)\n }\n }\n notifyInventory()\n}\n\nconst appInventory: InventorySource = {\n list: () => appInventorySource?.list() ?? null,\n subscribe(listener) {\n inventoryListeners.add(listener)\n return () => void inventoryListeners.delete(listener)\n },\n}\n\n/** One collector run: everything a `start()` opens, and everything `stop()` closes. */\nclass CollectorRun {\n private readonly sessions = new Map<string, Session>()\n private readonly cleanups: Array<() => void> = []\n private stopped = false\n private phoneId = \"\"\n\n /** The wall and monotonic clocks at the last checkpoint; the clocks are compared across this span. */\n private anchorWall = 0\n private anchorMono = 0\n /** The Mentra App left the foreground since the anchor: a silent gap then looks like suspension. */\n private leftForeground = false\n\n /** The visit to the Mentra App going on: when it began, and when the app left it, within the grace. */\n private visitStart: Instant | null = null\n private visitLeftAt: Instant | null = null\n /** The visit has settled into a foreground session (see FOREGROUND_SETTLE_MS). */\n private foreground = false\n private foregroundTimer: number | null = null\n private foregroundDueMono = 0\n\n private checkpointTimer: number | null = null\n private checkpointDueMono = 0\n private snapshotDebounce: number | null = null\n private inventoryDebounce: number | null = null\n /** What the last inventory record of this run said, so a change that left the listing as it was writes nothing. */\n private lastInventoryKey: string | null = null\n /** When the last snapshot was written (monotonic), and what it said, so a repeat of it can be skipped. */\n private lastSnapshotMono = 0\n private lastSnapshotKey: string | null = null\n\n private known: KnownGlasses | null = null\n private heldPhotos: HeldPhoto[] = []\n private battery: BatteryReading | null = null\n private phoneBattery: PhoneBatteryHeld | null = null\n private connection: {state: ConnectionState; observedAt: number} = {state: \"disconnected\", observedAt: 0}\n private marks: SnapshotMarks | null = null\n\n constructor(\n private readonly env: Env,\n private readonly partition: string,\n private readonly collectorSessionId: string,\n ) {}\n\n // --- lifecycle -----------------------------------------------------------------------------------------------\n\n begin(): void {\n this.phoneId = phoneDeviceId()\n const wall = this.env.now()\n this.anchorWall = wall\n this.anchorMono = this.env.monotonic()\n this.leftForeground = !isForeground()\n this.followForeground()\n this.connection = {state: mapConnection(useGlassesStore.getState().connection.state), observedAt: wall}\n this.trackGlasses(wall)\n this.openMissing()\n\n this.cleanups.push(\n useGlassesStore.subscribe(glassesFingerprint, () => this.guard(\"glasses change\", () => this.onStateChange())),\n miniappRunningRegistry.subscribe(() => this.guard(\"miniapp change\", () => this.onStateChange())),\n nativeMiniappExecution.subscribe(() => this.guard(\"miniapp change\", () => this.onStateChange())),\n fleetEvents.subscribe({\n launch: (event) => this.guard(\"launch\", () => this.onLaunch(event)),\n photo: (event) => this.guard(\"photo\", () => this.onPhoto(event)),\n }),\n )\n const appState = AppState.addEventListener(\"change\", (state) =>\n this.guard(\"app state\", () => {\n if (state !== \"active\") this.leftForeground = true\n this.onStateChange()\n // In the background the process may be suspended or killed before the visit's grace is over: the visit is\n // checkpointed now, up to when the app left, so that time is not lost with it. A blip that stays short of\n // the background (iOS inactive) writes nothing.\n if (state === \"background\" && this.sessions.get(FOREGROUND_KEY)?.endAt) this.flush()\n }),\n )\n this.cleanups.push(() => appState.remove())\n this.cleanups.push(this.env.phoneBattery.subscribe(() => this.guard(\"phone battery\", () => this.onPhoneBattery())))\n this.refreshPhoneBattery()\n\n this.takeSnapshot()\n this.cleanups.push(\n this.env.inventory.subscribe(() => this.guard(\"inventory change\", () => this.scheduleInventory())),\n )\n this.takeInventory(true)\n // Launches the engine made before this run could listen: it restores miniapps while the account may still be\n // being resolved, and the reporter discards them when the account changes, so these are this run's account's.\n for (const {event, observedAt} of fleetEvents.takeUndeliveredLaunches()) {\n this.guard(\"launch\", () => this.onLaunch(event, observedAt))\n }\n this.arm(this.cadence())\n }\n\n /** Ends every session in the partition, then stops listening. */\n end(): void {\n if (this.stopped) return\n try {\n if (this.checkClock()) {\n // Whatever the jump left open was just reopened and has nothing confirmed to close.\n this.sessions.clear()\n } else {\n this.writeCheckpoint(new Set(this.sessions.keys()))\n }\n } catch (error) {\n warn(\"final checkpoint\", error)\n }\n this.guard(\"photos\", () => this.releasePhotos(true))\n this.abort()\n }\n\n /** Stops listening and drops the timers, without writing anything. */\n abort(): void {\n this.stopped = true\n if (this.checkpointTimer !== null) BgTimer.clearTimeout(this.checkpointTimer)\n if (this.snapshotDebounce !== null) BgTimer.clearTimeout(this.snapshotDebounce)\n if (this.foregroundTimer !== null) BgTimer.clearTimeout(this.foregroundTimer)\n if (this.inventoryDebounce !== null) BgTimer.clearTimeout(this.inventoryDebounce)\n this.checkpointTimer = this.snapshotDebounce = this.foregroundTimer = this.inventoryDebounce = null\n for (const cleanup of this.cleanups.splice(0)) {\n try {\n cleanup()\n } catch (error) {\n warn(\"cleanup\", error)\n }\n }\n }\n\n flush(): void {\n this.guard(\"checkpoint\", () => {\n if (!this.checkClock()) this.writeCheckpoint(NONE)\n })\n }\n\n private guard(what: string, run: () => void): void {\n if (this.stopped) return\n try {\n run()\n } catch (error) {\n warn(what, error)\n }\n }\n\n // --- reacting to the engine ----------------------------------------------------------------------------------\n\n private onStateChange(): void {\n this.followForeground()\n this.trackGlasses(this.env.now())\n if (!this.checkClock()) this.reconcileSessions()\n this.releasePhotos()\n this.evaluateSnapshotTriggers()\n }\n\n /** Notes what the glasses store says now: the connection, the glasses' identity and versions, and the battery. */\n private trackGlasses(wall: number): void {\n const s = useGlassesStore.getState()\n const state = mapConnection(s.connection.state)\n if (state !== this.connection.state) {\n // Glasses that start connecting are not assumed to be the pair that was last here: a new connection is\n // identified afresh, from what the glasses say, before anything is attributed to a device. Only a new\n // connection forgets: while one is tearing down the native layer clears the identity (model first) before it\n // reports disconnected, and the departing pair is still the pair its last records are about.\n if (this.connection.state === \"disconnected\") this.forgetGlasses()\n this.connection = {state, observedAt: wall}\n }\n // The pair first: a battery reading belongs to the pair it was seen on, and another pair starts without one.\n this.rememberGlasses(s)\n const simulated = isSimulatedGlasses(s.deviceModel)\n if (this.batteryUnsupported()) {\n // Glasses that cannot report a battery have no reading: a level in the store is not theirs.\n this.battery = null\n } else if (\n // A battery value in the store is only believed while real glasses are connected; afterwards the last reading\n // keeps the time it was seen.\n s.connection.state === \"connected\" &&\n !simulated &&\n (!this.battery || this.battery.level !== s.batteryLevel || this.battery.charging !== s.charging)\n ) {\n this.battery = {level: s.batteryLevel, charging: s.charging, observedAt: wall}\n }\n }\n\n /** Notes the phone's battery as its source holds it; a value that did not change keeps the time it was first seen. */\n private trackPhoneBattery(wall: number): void {\n let read: PhoneBatteryReading | \"unsupported\" | null = null\n try {\n read = this.env.phoneBattery.read()\n } catch (error) {\n warn(\"reading the phone battery\", error)\n }\n const next = phoneBatteryState(read)\n const held = this.phoneBattery\n if (held && held.state === next.state && held.level === next.level && held.charging === next.charging) return\n this.phoneBattery = {...next, observedAt: wall}\n }\n\n private refreshPhoneBattery(): void {\n try {\n this.env.phoneBattery.refresh()\n } catch (error) {\n warn(\"refreshing the phone battery\", error)\n }\n }\n\n private onPhoneBattery(): void {\n this.trackPhoneBattery(this.env.now())\n this.evaluateSnapshotTriggers()\n }\n\n /** Nothing seen of the glasses so far is about the pair that comes next: not its identity, versions or battery. */\n private forgetGlasses(): void {\n // A photo still waiting for the pair that was here is that pair's.\n this.releasePhotos(true)\n this.known = null\n this.battery = null\n }\n\n private rememberGlasses(s: GlassesState): void {\n const reported = text(s.deviceModel)\n if (!reported) return\n if (isSimulatedGlasses(reported)) {\n // The store names glasses that are no device (the simulated ones): the pair remembered before is not them.\n this.forgetGlasses()\n return\n }\n const model = glassesProduct(reported)\n const now = pairIdentity(s)\n // What was learned about the pair before this carries over only if it is the same pair (see `samePair`). A second\n // pair of the same model starts from nothing.\n const before = this.known\n const same = before !== null && before.model === model && samePair(before.identity, now)\n if (before !== null && !same) {\n // Another pair, swapped in with no disconnect between: what waited for the first pair is the first pair's, and\n // the last reading was its battery.\n this.releasePhotos(true)\n this.battery = null\n }\n const kept = same ? before : null\n const identity: PairIdentity = {\n serial: now.serial ?? kept?.identity.serial ?? null,\n address: now.address ?? kept?.identity.address ?? null,\n name: now.name ?? kept?.identity.name ?? null,\n }\n // The serial, whenever the pair shows one, is its identity, and replaces a provisional stand-in.\n const binding =\n identity.serial !== null && kept?.binding?.kind !== \"serial\"\n ? serialBinding(model, identity.serial)\n : (kept?.binding ?? null)\n this.known = {\n model,\n identity,\n connectedSinceMono:\n kept?.connectedSinceMono ?? (this.connection.state === \"connected\" ? this.env.monotonic() : null),\n binding,\n firmware: kept ? {...kept.firmware, ...firmwareOf(s)} : firmwareOf(s),\n }\n }\n\n /** The pair known here is a model without battery reporting. */\n private batteryUnsupported(): boolean {\n return this.known !== null && this.env.modelsWithoutBattery.has(this.known.model)\n }\n\n /** The binding of the glasses the store describes now, once they are identified (see `identified`). */\n private currentBinding(final = false): FleetDeviceBinding | null {\n this.rememberGlasses(useGlassesStore.getState())\n return this.identified(final)\n }\n\n /**\n * The binding of the glasses known here, or null while they are being identified (see KnownGlasses) or were only\n * ever looked for. Glasses that have left are identified by what they showed; so are they with `final`, for what\n * cannot wait.\n */\n private identified(final = false): FleetDeviceBinding | null {\n const known = this.known\n if (!known || known.binding) return known?.binding ?? null\n const since = known.connectedSinceMono\n if (since === null) return null\n const departed = this.connection.state !== \"connected\"\n if (final || departed || this.env.monotonic() - since >= IDENTITY_SETTLE_MS) {\n known.binding = provisionalBinding(known.model, known.identity.address ?? known.identity.name)\n }\n return known.binding\n }\n\n // --- the foreground ------------------------------------------------------------------------------------------\n\n private instant(): Instant {\n return {wall: this.env.now(), mono: this.env.monotonic()}\n }\n\n /**\n * Follows the app state into the foreground as Fleet counts it (see FOREGROUND_SETTLE_MS): a visit begins when the\n * app becomes active, becomes a foreground session once the app is active 2 s after that, and is over once the app\n * has been away for 5 s, ending when it left. Writes nothing: the sessions follow it.\n */\n private followForeground(): void {\n const now = this.instant()\n const active = isForeground()\n // Away for the grace, the visit is over, even if the app is back by now: back that late (the process was\n // suspended in between, and the timer could not fire), it is a new visit.\n if (this.visitLeftAt && now.mono - this.visitLeftAt.mono >= FOREGROUND_GRACE_MS) {\n this.visitStart = this.visitLeftAt = null\n this.foreground = false\n }\n const session = this.sessions.get(FOREGROUND_KEY)\n if (active) {\n if (this.visitLeftAt) {\n // Back within the grace: the same visit, the time away included.\n this.visitLeftAt = null\n if (session) delete session.endAt\n }\n this.visitStart ??= now\n if (!this.foreground && now.mono - this.visitStart.mono >= FOREGROUND_SETTLE_MS) this.foreground = true\n } else if (this.visitStart && !this.visitLeftAt) {\n this.visitLeftAt = now\n if (session) session.endAt = now\n }\n this.armForegroundTimer(now, active)\n }\n\n /** When the foreground can next change with the app state unchanged: the visit settling, or its grace ending. */\n private armForegroundTimer(now: Instant, active: boolean): void {\n let due: number | null = null\n if (this.visitLeftAt) due = this.visitLeftAt.mono + FOREGROUND_GRACE_MS\n else if (active && this.visitStart && !this.foreground) due = this.visitStart.mono + FOREGROUND_SETTLE_MS\n if (due !== null && this.foregroundTimer !== null && due === this.foregroundDueMono) return\n if (this.foregroundTimer !== null) BgTimer.clearTimeout(this.foregroundTimer)\n this.foregroundTimer = null\n if (due === null) return\n this.foregroundDueMono = due\n const timer: number = BgTimer.setTimeout(\n () =>\n this.guard(\"app state\", () => {\n if (this.foregroundTimer !== timer) return\n this.foregroundTimer = null\n this.onStateChange()\n }),\n Math.max(0, due - now.mono),\n )\n this.foregroundTimer = timer\n }\n\n // --- sessions ------------------------------------------------------------------------------------------------\n\n private desiredSessions(): Map<string, SessionSpec> {\n const wanted = new Map<string, SessionSpec>()\n wanted.set(\"engine_active\", {activity: \"engine_active\"})\n // From when the visit began, which is before it settled.\n if (this.foreground) {\n wanted.set(FOREGROUND_KEY, {activity: \"app_foreground\", ...(this.visitStart ? {since: this.visitStart} : {})})\n }\n if (realGlassesConnected()) wanted.set(\"glasses_connection\", {activity: \"glasses_connection\"})\n // Local miniapps execute while their JS context runs; native built-ins as the apps store derives it.\n for (const name of [...miniappRunningRegistry.getAll(), ...nativeMiniappExecution.getAll()]) {\n const packageName = text(name)\n if (packageName) wanted.set(`miniapp_execution:${packageName}`, {activity: \"miniapp_execution\", packageName})\n }\n return wanted\n }\n\n private open(key: string, spec: SessionSpec): Session {\n const session: Session = {\n key,\n activity: spec.activity,\n id: newId(),\n ...(spec.packageName ? {packageName: spec.packageName} : {}),\n startedWall: spec.since?.wall ?? this.env.now(),\n startedMono: spec.since?.mono ?? this.env.monotonic(),\n reportedElapsedMs: null,\n }\n this.sessions.set(key, session)\n return session\n }\n\n private openMissing(): void {\n for (const [key, spec] of this.desiredSessions()) if (!this.sessions.has(key)) this.open(key, spec)\n }\n\n /** Makes the open sessions match what is happening now: ends the ones that stopped (checkpointing at once), opens new ones. */\n private reconcileSessions(): void {\n const wanted = this.desiredSessions()\n const ending = new Set<string>()\n for (const key of this.sessions.keys()) if (!wanted.has(key)) ending.add(key)\n // Close first: a session opened in the same breath is not reported until a checkpoint after its identity settles.\n if (ending.size > 0) this.writeCheckpoint(ending)\n let fastSince: number | null = null\n for (const [key, spec] of wanted) {\n if (this.sessions.has(key)) continue\n const session = this.open(key, spec)\n if (isFastActivity(session.activity)) fastSince = Math.min(fastSince ?? Infinity, session.startedMono)\n }\n this.ensureCadence(fastSince)\n }\n\n /** 60-second checkpoints while glasses are connected or the Mentra App is in the foreground; 15 minutes otherwise. */\n private isFast(): boolean {\n for (const session of this.sessions.values()) if (isFastActivity(session.activity)) return true\n return false\n }\n\n private cadence(): number {\n return this.isFast() ? FAST_CHECKPOINT_MS : IDLE_CHECKPOINT_MS\n }\n\n /** The next checkpoint is `delay` from now, replacing any that is pending. */\n private arm(delay: number): void {\n if (this.checkpointTimer !== null) BgTimer.clearTimeout(this.checkpointTimer)\n this.checkpointDueMono = this.env.monotonic() + delay\n const timer: number = BgTimer.setTimeout(() => this.onCheckpointTimer(timer), delay)\n this.checkpointTimer = timer\n }\n\n private onCheckpointTimer(fired: number): void {\n if (this.stopped || this.checkpointTimer !== fired) return\n try {\n this.flush()\n // The phone's battery is read on the wake-ups the collector already has; the reading arrives later.\n this.refreshPhoneBattery()\n // Glasses connected long enough are identified by now, without a change in the store to say so.\n this.guard(\"photos\", () => this.releasePhotos())\n this.guard(\"snapshot\", () => {\n this.evaluateSnapshotTriggers()\n this.periodicSnapshot()\n })\n } finally {\n // A checkpoint that failed part-way must not end the cadence.\n if (!this.stopped && this.checkpointTimer === fired) this.arm(this.cadence())\n }\n }\n\n /**\n * Activity that needs a 60 s checkpoint brings the next one forward, to 60 s after it began (`fastSince`, by default\n * now); a 15-minute wait does not outlast it.\n */\n private ensureCadence(fastSince: number | null = null): void {\n if (this.checkpointTimer === null) {\n this.arm(this.cadence())\n return\n }\n if (!this.isFast()) return\n const now = this.env.monotonic()\n const due = Math.max(now, (fastSince ?? now) + FAST_CHECKPOINT_MS)\n if (this.checkpointDueMono > due) this.arm(due - now)\n }\n\n // --- checkpoints ---------------------------------------------------------------------------------------------\n\n /**\n * Reports every open session, those in `ending` as ended and removed. Writes at once and sets the next checkpoint.\n * A session that has run for the longest time one record may carry ends there, and a new one carries on.\n */\n private writeCheckpoint(ending: ReadonlySet<string>): void {\n const wall = this.env.now()\n const mono = this.env.monotonic()\n const entries: UsageSession[] = []\n for (const open of [...this.sessions.values()]) {\n let session = open\n for (\n let turn = 0;\n turn < MAX_CAP_TURNS && mono - session.startedMono >= FLEET_LIMITS.maxSessionElapsedMs;\n turn += 1\n ) {\n const capped = this.entryFor(session, mono, wall, true)\n if (capped) entries.push(capped)\n session = this.successorOf(session)\n this.sessions.set(session.key, session)\n }\n const entry = this.entryFor(session, mono, wall, ending.has(session.key))\n if (entry) entries.push(entry)\n }\n for (const key of ending) this.sessions.delete(key)\n this.anchorWall = wall\n this.anchorMono = mono\n this.leftForeground = !isForeground()\n // A close that closed nothing reportable (a connection that was never identified) is not worth a record.\n if (ending.size === 0 || entries.some((entry) => entry.ended)) this.emitCheckpoints(entries, wall)\n this.arm(this.cadence())\n }\n\n /** The session that carries on from one that reached the cap: the same activity, from the cap on. */\n private successorOf(session: Session): Session {\n const cap = FLEET_LIMITS.maxSessionElapsedMs\n return {\n ...session,\n id: newId(),\n startedWall: session.startedWall + cap,\n startedMono: session.startedMono + cap,\n reportedElapsedMs: null,\n }\n }\n\n /**\n * The session as a checkpoint entry, `ended` or not, or null if it cannot be reported yet (glasses not identified).\n * Its time is what the monotonic clock measured, never less than it already reported, never more than the wall\n * clock had given it by `wallLimit`, and never more than a session may report.\n */\n private entryFor(session: Session, mono: number, wallLimit: number, ended: boolean): UsageSession | null {\n if (session.endAt) {\n // The activity stopped then: no time after it is the session's, whether or not it ends now.\n mono = Math.min(mono, session.endAt.mono)\n wallLimit = Math.min(wallLimit, session.endAt.wall)\n }\n let binding: FleetDeviceBinding | undefined\n if (session.activity === \"glasses_connection\") {\n // Fixed at the first report, so a serial that arrives later never splits a connection into two devices. Not\n // reported before the glasses are identified, unless the session ends first.\n binding = session.binding ??= this.currentBinding(ended) ?? undefined\n if (!binding) return null\n }\n const floor = session.reportedElapsedMs ?? 0\n let elapsedMs = Math.floor(mono - session.startedMono)\n if (!Number.isFinite(elapsedMs)) elapsedMs = floor\n const wallSinceStart = Math.floor(wallLimit - session.startedWall)\n if (Number.isFinite(wallSinceStart)) elapsedMs = Math.min(elapsedMs, Math.max(wallSinceStart, 0))\n elapsedMs = Math.min(Math.max(elapsedMs, floor), FLEET_LIMITS.maxSessionElapsedMs)\n session.reportedElapsedMs = elapsedMs\n return this.describe(session, elapsedMs, ended, binding)\n }\n\n private describe(session: Session, elapsedMs: number, ended: boolean, binding?: FleetDeviceBinding): UsageSession {\n return {\n activity: session.activity,\n activitySessionId: session.id,\n ...(session.packageName ? {packageName: session.packageName} : {}),\n ...(binding ? {deviceBinding: binding} : {}),\n startedAt: iso(session.startedWall),\n elapsedMs,\n ended,\n }\n }\n\n private emitCheckpoints(entries: UsageSession[], observedAt: number): void {\n const size = FLEET_LIMITS.maxSessionsPerCheckpoint\n for (let index = 0; index < entries.length; index += size) {\n const sessions = entries.slice(index, index + size)\n this.emit(observedAt, (base) => ({...base, kind: \"usage_checkpoint\", payload: {sessions}}))\n }\n }\n\n // --- clock changes and suspension ----------------------------------------------------------------------------\n\n /**\n * Whether the span since the last checkpoint can be believed, and what to do if it cannot. Returns true if it\n * handled a break (the sessions have then been closed and started again).\n *\n * The monotonic clock runs while the device is awake; through sleep it pauses on Android and keeps counting on iOS\n * (see the file header). A timer that was due by it and did not fire means the process was not running. Two things\n * can be wrong with the span:\n * - The checkpoint is overdue by the monotonic clock: nothing here was running while that clock ran (the process\n * was suspended, or on iOS the device also slept). None of it was observed, so the sessions end at their last\n * checkpoint.\n * - The wall clock parted from the monotonic clock: the device slept with a clock that pauses in sleep (Android),\n * or somebody changed the clock. The monotonic time was observed and counts, so the sessions end at it; only the\n * jump itself is a gap.\n * The first wins: a reporter that was not running observed nothing, whatever the wall clock did.\n */\n private checkClock(): boolean {\n const wall = this.env.now()\n const mono = this.env.monotonic()\n if (this.checkpointTimer !== null && mono - this.checkpointDueMono > CLOCK_DRIFT_LIMIT_MS) {\n this.closeAtLastCheckpoint(wall, mono)\n return true\n }\n const monoDelta = mono - this.anchorMono\n const drift = wall - this.anchorWall - monoDelta\n if (Math.abs(drift) > CLOCK_DRIFT_LIMIT_MS) {\n this.closeAtObservedTime(wall, mono, monoDelta, drift)\n return true\n }\n return false\n }\n\n /** The reporter was silent: only what it had reported before counts, and everything since is a gap. */\n private closeAtLastCheckpoint(wall: number, mono: number): void {\n const from = this.anchorWall\n const closed: UsageSession[] = []\n for (const session of this.sessions.values()) {\n // A session that was never reported has nothing to close.\n if (session.reportedElapsedMs === null) continue\n if (session.activity === \"glasses_connection\" && !session.binding) continue\n closed.push(this.describe(session, session.reportedElapsedMs, true, session.binding))\n }\n this.sessions.clear()\n this.emitCheckpoints(closed, from)\n this.emitGap(\"reporter_stopped\", from, Math.max(wall, from), wall)\n this.startAgain(wall, mono)\n }\n\n /** The wall clock jumped: the awake time counts, ending where the monotonic clock says it did, and the jump is the gap. */\n private closeAtObservedTime(wall: number, mono: number, monoDelta: number, drift: number): void {\n // Where the observation ended on the timeline the last checkpoint was written on.\n const observedUntil = this.anchorWall + Math.max(monoDelta, 0)\n const closed: UsageSession[] = []\n for (const session of this.sessions.values()) {\n const entry = this.entryFor(session, mono, observedUntil, true)\n if (entry) closed.push(entry)\n }\n this.sessions.clear()\n this.emitCheckpoints(closed, observedUntil)\n // Sleep shows as the wall clock running ahead while the app was away; anything else is the clock being changed.\n const reason: GapReason = drift > 0 && this.leftForeground ? \"reporter_stopped\" : \"clock_untrusted\"\n this.emitGap(reason, Math.min(observedUntil, wall), Math.max(observedUntil, wall), wall)\n this.startAgain(wall, mono)\n }\n\n private emitGap(reason: GapReason, from: number, to: number, observedAt: number): void {\n this.emit(observedAt, (base) => ({\n ...base,\n kind: \"coverage_gap\",\n payload: {reason, from: iso(from), to: iso(to)},\n }))\n }\n\n /** After a break: the clocks are re-anchored, and the activities still going on start again as new sessions. */\n private startAgain(wall: number, mono: number): void {\n this.anchorWall = wall\n this.anchorMono = mono\n this.leftForeground = !isForeground()\n // The break closed the visit: one the app had left is over, and one still going on starts again from now.\n if (this.visitLeftAt) {\n this.visitStart = this.visitLeftAt = null\n this.foreground = false\n } else if (this.visitStart) {\n this.visitStart = {wall, mono}\n }\n this.armForegroundTimer({wall, mono}, isForeground())\n this.openMissing()\n this.arm(this.cadence())\n this.scheduleSnapshot()\n }\n\n // --- snapshots -----------------------------------------------------------------------------------------------\n\n private batteryPayload(wall: number): BatteryPayload {\n if (this.batteryUnsupported()) return {state: \"unsupported\", observedAt: iso(wall)}\n const reading = this.battery\n if (!reading || !Number.isFinite(reading.level) || reading.level < 0) {\n return {state: \"unknown\", observedAt: iso(reading?.observedAt ?? wall)}\n }\n return {\n state: \"measured\",\n observedAt: iso(reading.observedAt),\n level: Math.min(100, Math.round(reading.level)),\n charging: reading.charging,\n }\n }\n\n private phoneBatteryPayload(wall: number): PhoneBatteryPayload {\n const held = this.phoneBattery ?? {state: \"unknown\", observedAt: wall}\n if (held.state !== \"measured\") return {state: held.state, observedAt: iso(held.observedAt)}\n return {state: \"measured\", observedAt: iso(held.observedAt), level: held.level, charging: held.charging}\n }\n\n private versionKey(): string {\n const firmware = this.known?.firmware\n return firmware ? [firmware.apk, firmware.mtk, firmware.bes, firmware.os].join(\"|\") : \"\"\n }\n\n private currentMarks(): SnapshotMarks {\n const reading = this.battery\n const measured = !!reading && Number.isFinite(reading.level) && reading.level >= 0\n const binding = this.identified()\n const phone = this.phoneBattery\n return {\n phoneBattery: phone ?? {state: \"unknown\"},\n identity: binding ? JSON.stringify(binding) : \"\",\n linked: this.connection.state === \"connected\",\n batteryMeasured: measured,\n level: measured ? reading.level : -1,\n charging: measured ? reading.charging : false,\n versions: this.versionKey(),\n }\n }\n\n /** Asks for a snapshot once the changes around this moment have settled. */\n private scheduleSnapshot(): void {\n if (this.snapshotDebounce !== null) return\n const timer: number = BgTimer.setTimeout(\n () =>\n this.guard(\"snapshot\", () => {\n if (this.snapshotDebounce === timer) this.snapshotDebounce = null\n this.takeSnapshot()\n }),\n SNAPSHOT_DEBOUNCE_MS,\n )\n this.snapshotDebounce = timer\n }\n\n /**\n * The 15-minute snapshot. It has no timer of its own: it is written with the checkpoint that falls due 15 minutes or\n * more after the last snapshot, so the two share a wake-up and an upload. On the 15-minute cadence it is written\n * only if it would say something the last snapshot did not.\n */\n private periodicSnapshot(): void {\n if (this.env.monotonic() - this.lastSnapshotMono < SNAPSHOT_INTERVAL_MS) return\n this.takeSnapshot(!this.isFast())\n }\n\n /**\n * Glasses connecting or disconnecting is worth a snapshot; while they are connected, so are their identification (or\n * a serial replacing a provisional binding), a battery move of 5 points or a charging change, and a new version.\n *\n * Moves among the states short of connected are not: a phone retrying glasses that are away goes scanning,\n * connecting and disconnected every few seconds, all day, and forgets and finds the glasses' identity with each\n * attempt. Their battery and versions are only read while they are connected.\n *\n * A disconnect is written at once, while what is known is still the pair that left: the retry that follows within\n * moments starts a new connection, which forgets them. Only a snapshot in the last two seconds holds it back to the\n * usual debounce, so a link that flaps is still one snapshot every two seconds at most.\n *\n * The phone's battery is worth one on the same terms, with or without glasses: once it is first known or stops being\n * known, a move of 5 points, or a charging change.\n */\n private evaluateSnapshotTriggers(): void {\n const last = this.marks\n if (!last) return\n const now = this.currentMarks()\n const phoneNow = now.phoneBattery\n const phoneLast = last.phoneBattery\n if (\n phoneNow.state !== phoneLast.state ||\n (phoneNow.state === \"measured\" &&\n (Math.abs(phoneNow.level - (phoneLast.level ?? 0)) >= BATTERY_SNAPSHOT_STEP ||\n phoneNow.charging !== phoneLast.charging))\n ) {\n this.scheduleSnapshot()\n }\n if (now.linked !== last.linked) {\n const disconnected = !now.linked\n if (disconnected && this.env.monotonic() - this.lastSnapshotMono >= SNAPSHOT_DEBOUNCE_MS) this.takeSnapshot()\n else this.scheduleSnapshot()\n return\n }\n if (!now.linked) return\n const changed =\n now.identity !== last.identity ||\n (now.identity !== \"\" &&\n (now.batteryMeasured !== last.batteryMeasured ||\n (now.batteryMeasured &&\n (Math.abs(now.level - last.level) >= BATTERY_SNAPSHOT_STEP || now.charging !== last.charging)) ||\n (now.versions !== \"\" && now.versions !== last.versions)))\n if (changed) this.scheduleSnapshot()\n }\n\n /** Writes a snapshot; with `onlyIfNew`, only if it would say something the last one did not. */\n private takeSnapshot(onlyIfNew = false): void {\n const phone = phoneInfo()\n if (!phone) {\n if (this.snapshotDebounce !== null) BgTimer.clearTimeout(this.snapshotDebounce)\n this.snapshotDebounce = null\n console.warn(\"FleetCollector: no snapshot, this platform has no value in the Fleet contract\")\n return\n }\n const wall = this.env.now()\n this.trackGlasses(wall)\n this.trackPhoneBattery(wall)\n const binding = this.currentBinding()\n const known = this.known\n const glasses: GlassesPayload | null =\n binding && known\n ? {\n model: known.model,\n ...(Object.keys(known.firmware).length > 0 ? {firmware: known.firmware} : {}),\n connection: {state: this.connection.state, observedAt: iso(this.connection.observedAt)},\n battery: this.batteryPayload(wall),\n }\n : null\n // What the snapshot says, leaving out the time a battery with no reading is stamped with (it is now): an unknown\n // one, or one the glasses cannot report. Of glasses that are not connected only that is new: retrying them changes\n // the state short of connected, its time, and what is known of them, with every attempt. The phone's battery is\n // left out: a move worth a snapshot schedules one, and a smaller one is not new enough to write.\n const key = JSON.stringify([\n phone,\n this.connection.state !== \"connected\"\n ? \"not connected\"\n : [\n binding && glasses ? binding : null,\n glasses && !this.battery ? {...glasses, battery: {state: glasses.battery?.state}} : glasses,\n ],\n ])\n if (onlyIfNew && key === this.lastSnapshotKey) return\n if (this.snapshotDebounce !== null) BgTimer.clearTimeout(this.snapshotDebounce)\n this.snapshotDebounce = null\n this.emit(wall, (base) => ({\n ...base,\n kind: \"snapshot\",\n ...(glasses && binding ? {deviceBinding: binding} : {}),\n payload: {phone: {...phone, battery: this.phoneBatteryPayload(wall)}, ...(glasses ? {glasses} : {})},\n }))\n this.marks = this.currentMarks()\n this.lastSnapshotMono = this.env.monotonic()\n this.lastSnapshotKey = key\n }\n\n // --- inventory -----------------------------------------------------------------------------------------------\n\n /** Asks for an inventory record once the changes around this moment have settled. */\n private scheduleInventory(): void {\n if (this.inventoryDebounce !== null) return\n const timer: number = BgTimer.setTimeout(\n () =>\n this.guard(\"inventory\", () => {\n if (this.inventoryDebounce === timer) this.inventoryDebounce = null\n this.takeInventory(false)\n }),\n INVENTORY_DEBOUNCE_MS,\n )\n this.inventoryDebounce = timer\n }\n\n /** Writes the inventory; unless `always`, only if it lists something the last record of this run did not. */\n private takeInventory(always: boolean): void {\n const wall = this.env.now()\n const payload = inventoryPayload(this.env.inventory.list())\n if (!payload) return\n const key = JSON.stringify(payload)\n if (!always && key === this.lastInventoryKey) return\n if (this.inventoryDebounce !== null) BgTimer.clearTimeout(this.inventoryDebounce)\n this.inventoryDebounce = null\n this.emit(wall, (base) => ({...base, kind: \"miniapp_inventory\", payload}))\n this.lastInventoryKey = key\n }\n\n // --- launches and photos -------------------------------------------------------------------------------------\n\n private onLaunch(event: FleetLaunchEvent, observedAt = this.env.now()): void {\n const packageName = text(event.packageName)\n if (!packageName) return\n if (event.start !== \"user\" && event.start !== \"automatic\") return\n if (event.outcome !== \"started\" && event.outcome !== \"failed\") return\n const miniappName = text(event.miniappName)\n const versionName = text(event.versionName)\n this.emit(observedAt, (base) => ({\n ...base,\n kind: \"miniapp_launch\",\n payload: {\n packageName,\n ...(miniappName ? {miniappName} : {}),\n ...(versionName ? {versionName} : {}),\n start: event.start,\n outcome: event.outcome,\n },\n }))\n }\n\n private onPhoto(event: FleetPhotoEvent): void {\n const operationId = event.operationId\n if (typeof operationId !== \"string\" || operationId.length > MAX_TEXT || !FLEET_ID.test(operationId)) return\n const stage = event.stage\n if (stage !== \"requested\" && stage !== \"captured\" && stage !== \"delivered\" && stage !== \"failed\") return\n const payload = stage === \"failed\" ? {stage, failedStage: event.failedStage ?? (\"requested\" as const)} : {stage}\n const photo: HeldPhoto = {observedAt: this.env.now(), operationId, payload}\n // A photo is always one pair of glasses' photo: of connected glasses still being identified, it waits for them.\n const binding = this.currentBinding()\n if (binding) this.emitPhoto(photo, binding)\n else if (this.known?.connectedSinceMono != null && this.heldPhotos.length < MAX_HELD_PHOTOS)\n this.heldPhotos.push(photo)\n }\n\n /** Writes the photo stages that waited for the glasses, once they are identified (or with `final`, as they are). */\n private releasePhotos(final = false): void {\n if (this.heldPhotos.length === 0) return\n const binding = this.identified(final)\n if (binding) for (const photo of this.heldPhotos.splice(0)) this.emitPhoto(photo, binding)\n else if (final) this.heldPhotos = []\n }\n\n private emitPhoto(photo: HeldPhoto, binding: FleetDeviceBinding): void {\n this.emit(photo.observedAt, (base) => ({\n ...base,\n kind: \"photo_operation\",\n operationId: photo.operationId,\n deviceBinding: binding,\n payload: photo.payload,\n }))\n }\n\n // --- records -------------------------------------------------------------------------------------------------\n\n private capabilities(): Capability[] {\n const measured: readonly Capability[] = !realGlassesConnected()\n ? PHONE_CAPABILITIES\n : // Glasses that cannot report a battery leave nothing to measure about it.\n this.batteryUnsupported()\n ? FLEET_CAPABILITIES.filter((capability) => capability !== \"glasses_battery\")\n : FLEET_CAPABILITIES\n if (this.phoneBattery?.state === \"unsupported\") return measured.filter((capability) => capability !== \"phone_battery\")\n return [...measured]\n }\n\n private base(observedAt: number): RecordBase {\n return {\n schemaVersion: FLEET_SCHEMA_VERSION,\n recordId: newId(),\n phoneDeviceId: this.phoneId,\n collectorSessionId: this.collectorSessionId,\n sequence: this.env.queue.nextSequence(this.partition, this.collectorSessionId),\n observedAt: iso(observedAt),\n capabilities: this.capabilities(),\n }\n }\n\n /** Builds a record and queues it in this run's partition. A record that cannot be built or stored is skipped. */\n private emit(observedAt: number, make: (base: RecordBase) => FleetRecord): void {\n try {\n this.env.queue.enqueue(this.partition, make(this.base(observedAt)))\n } catch (error) {\n warn(\"recording\", error)\n }\n }\n}\n\n/**\n * The collector over `deps.queue`, which must be the app's shared queue (`createFleetQueue()`); the clocks and the\n * models without battery reporting are injectable for tests. It collects nothing until `start`.\n */\nexport function createFleetCollector(deps: {\n queue: FleetQueue\n now?: () => number\n monotonic?: () => number\n modelsWithoutBattery?: ReadonlySet<string>\n /** What is installed. Defaults to the app's source (`setFleetInventorySource`), which reports nothing until wired. */\n inventory?: InventorySource\n /** The phone's battery. Defaults to the app's (`appPhoneBattery`, over expo-battery). */\n phoneBattery?: PhoneBatterySource\n}): FleetCollector {\n const env: Env = {\n queue: deps.queue,\n now: deps.now ?? Date.now,\n monotonic: deps.monotonic ?? (() => performance.now()),\n modelsWithoutBattery: deps.modelsWithoutBattery ?? MODELS_WITHOUT_BATTERY,\n inventory: deps.inventory ?? appInventory,\n phoneBattery: deps.phoneBattery ?? appPhoneBattery,\n }\n let current: CollectorRun | null = null\n\n return {\n start(ctx) {\n try {\n const previous = current\n current = null\n previous?.end()\n const run = new CollectorRun(env, ctx.partition, ctx.collectorSessionId)\n current = run\n try {\n run.begin()\n } catch (error) {\n run.abort()\n if (current === run) current = null\n throw error\n }\n } catch (error) {\n warn(\"start\", error)\n }\n },\n\n // The reason is the caller's record of why; the collector closes its sessions the same way for each.\n stop(_reason) {\n const run = current\n current = null\n if (!run) return\n try {\n run.end()\n } catch (error) {\n warn(\"stop\", error)\n }\n },\n\n flushCheckpoint() {\n try {\n current?.flush()\n } catch (error) {\n warn(\"flush\", error)\n }\n },\n }\n}\n"]}
1
+ {"version":3,"file":"fleetCollector.js","sourceRoot":"","sources":["../../../src/services/fleet/fleetCollector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The Fleet collector: what the engine observes about the phone, its glasses and its miniapps, as Fleet records in\n * the durable queue.\n *\n * It listens to the engine's own state (the glasses store, the running-miniapp registry, the native built-ins\n * executing, the app state) and to `fleetEvents` (launches and photo stages, emitted by lifecycle hooks), never to UI\n * screens. It writes records; the uploader (a separate piece) delivers them. One collector run belongs to one\n * `start()`: its partition and collector-session ID are fixed for its life, and everything it holds is dropped by\n * `stop()`.\n *\n * Usage is measured as sessions: an activity (the engine running, the Mentra App in the foreground, glasses\n * connected, one miniapp executing) opens a session when it begins and closes it when it ends; the foreground with\n * hysteresis (see FOREGROUND_SETTLE_MS), so the app state's blips are not sessions of their own. A session's\n * `elapsedMs` is cumulative monotonic time, and each checkpoint packs every open session, so a session that is\n * cut off simply ends at its last checkpoint. Checkpoints come every 60 s while glasses are connected or the Mentra\n * App is in the foreground, every 15 minutes otherwise (only the engine active, or miniapps executing in the\n * background without glasses, such as Notify), and at once when a session ends. The slower cadence reports the same\n * time, only less often; what it risks is the time since the last checkpoint if the process dies. A session also\n * ends when it reaches the longest time one record may carry (7 days), and a new one carries on from there.\n *\n * Snapshots come at start, after a change worth one (glasses connecting or disconnecting, and while they are connected\n * a battery move of 5 points, a charging change or a new version), and with the first checkpoint 15 minutes or more\n * after the last snapshot, so the two share a wake-up and an upload. On the 15-minute cadence that snapshot is\n * written only if it would say something new. A phone retrying glasses that are away moves between scanning,\n * connecting and disconnected every few seconds, all day: none of that is a change worth a snapshot, or something\n * new. A phone with no glasses connected and the Mentra App in the background so writes about 100 records a day, a\n * checkpoint every 15 minutes, whether or not miniapps execute in the background or its glasses are being retried.\n *\n * Every snapshot carries the phone's own battery. The collector asks its source (`PhoneBatterySource`) for a new reading\n * only at start and on each checkpoint wake-up, and a reading is worth a snapshot of its own on the same terms as the\n * glasses' battery: once it is first known or stops being known, after a move of 5 points, or a charging change. A\n * phone draining all day so adds about 20 snapshots, not one per reading.\n *\n * The installed miniapps are reported as a `miniapp_inventory` record: once when a run starts (a new run is a new\n * account's or a new process's, which has never been told), and again, after a short settle, whenever the inventory\n * source says it changed and what it lists is not what the last record said. Never in a snapshot. The source is\n * injected (`InventorySource`); until the app wires one the collector sends no inventory, as it cannot tell an empty\n * phone from an unwired one.\n *\n * Time counts only while the collector was watching. The monotonic clock (React Native's `performance.now()`, the C++\n * steady clock) runs while the device is awake on both platforms, but not the same way through sleep, and the rules\n * below handle both:\n * - On Android it is CLOCK_MONOTONIC, which pauses in deep sleep. A sleep shows as the wall clock running ahead of\n * it: the sessions end at the monotonic time that was observed, and the jump is a gap.\n * - On iOS libc++'s steady clock reads CLOCK_MONOTONIC_RAW, which keeps counting through sleep. A sleep shows as a\n * checkpoint overdue by the monotonic clock: nothing ran, so the sessions end at their last checkpoint, and the\n * span since it is a gap.\n * On either platform, a checkpoint overdue by the monotonic clock means the process was suspended while that clock\n * ran, and a wall-clock jump the monotonic clock did not share is a clock that was changed.\n *\n * Nothing here may break or slow the paths it watches: every entry point catches its own failures, and nothing\n * thrown by the queue, the clock or a store reaches a caller.\n */\nimport * as Application from \"expo-application\"\nimport Constants from \"expo-constants\"\nimport * as Device from \"expo-device\"\nimport {AppState, Platform} from \"react-native\"\nimport {\n FLEET_CAPABILITIES,\n FLEET_INSTALL_REASONS,\n FLEET_LIMITS,\n FLEET_SCHEMA_VERSION,\n FleetMiniappInventoryPayloadSchema,\n type FleetActivity,\n type FleetDeviceBinding,\n type FleetInstallReason,\n type FleetMiniappInventoryPayload,\n type FleetRecord,\n} from \"@mentra/cloud-protocol\"\n\nimport {useGlassesStore} from \"../../stores/glasses\"\nimport {BgTimer} from \"../../utils/timers\"\nimport {miniappRunningRegistry} from \"../MiniappRunningRegistry\"\nimport {nativeMiniappExecution} from \"../NativeMiniappExecution\"\nimport {\n fleetEvents,\n type FleetConnectionEvent,\n type FleetCrashEvent,\n type FleetInstallEvent,\n type FleetLaunchEvent,\n type FleetPhotoEvent,\n type FleetTelemetryEvent,\n} from \"./fleetEvents\"\nimport {newId, phoneDeviceId} from \"./fleetIds\"\nimport {TELEMETRY_RECORD_PREFIX, type FleetQueue} from \"./fleetQueue\"\nimport {limitEvent, TelemetryRate} from \"./telemetryLimits\"\nimport {appPhoneBattery} from \"./phoneBatterySource\"\nimport {\n glassesProduct,\n isSimulatedGlasses,\n provisionalBinding,\n serialBinding,\n usableSerial,\n type GlassesIdentitySource,\n} from \"./glassesIdentity\"\n\nexport interface FleetCollector {\n /**\n * Opens the engine session, the glasses and running miniapps, and the foreground session once the app has been\n * active long enough to count, and takes a snapshot.\n */\n start(ctx: {partition: string; collectorSessionId: string}): void\n /** Checkpoints every open session as ended, into the partition `start` was given, and stops listening. */\n stop(reason: \"engine_stopped\" | \"account_changed\" | \"not_installed\"): void\n /** Writes one packed `usage_checkpoint` for every open session. */\n flushCheckpoint(): void\n}\n\n/** One installed miniapp, as the inventory source reports it. Its reasons are why it is installed, not where it came from. */\nexport interface InstalledMiniapp {\n packageName: string\n versionName: string\n /** The installed release's digest. */\n digest: string\n /** Why the phone holds it: `bundled`, `explicit`, `manifest` and `assignment`, which can hold together. At least one. */\n reasons: readonly FleetInstallReason[]\n}\n\n/**\n * Where the collector learns what is installed. The app's registry implements it (the wiring is the registry's side);\n * tests fake it.\n */\nexport interface InventorySource {\n /** The miniapps installed now, or null while that is not known yet (nothing is reported then). Must be cheap. */\n list(): readonly InstalledMiniapp[] | null\n /** `listener` is called, on any stack, after the installed set or any miniapp's version, digest or reasons changed. */\n subscribe(listener: () => void): () => void\n}\n\n/** One reading of the phone's battery: `level` a whole percent from 0 to 100. */\nexport interface PhoneBatteryReading {\n level: number\n charging: boolean\n}\n\n/**\n * Where the collector learns the phone's battery. The app's is `appPhoneBattery` (expo-battery); tests fake it.\n */\nexport interface PhoneBatterySource {\n /** The last reading; `unsupported` for a phone that cannot report one; null while none is known. Must be cheap. */\n read(): PhoneBatteryReading | \"unsupported\" | null\n /** Asks for a new reading, which arrives later through `subscribe`. Must be cheap. */\n refresh(): void\n /** `listener` is called, on any stack, after the reading changed. */\n subscribe(listener: () => void): () => void\n}\n\ntype Capability = (typeof FLEET_CAPABILITIES)[number]\ntype UsageSession = Extract<FleetRecord, {kind: \"usage_checkpoint\"}>[\"payload\"][\"sessions\"][number]\ntype SnapshotPayload = Extract<FleetRecord, {kind: \"snapshot\"}>[\"payload\"]\ntype GlassesPayload = NonNullable<SnapshotPayload[\"glasses\"]>\ntype PhoneBatteryPayload = NonNullable<SnapshotPayload[\"phone\"][\"battery\"]>\ntype ConnectionState = GlassesPayload[\"connection\"][\"state\"]\ntype BatteryPayload = NonNullable<GlassesPayload[\"battery\"]>\ntype Firmware = NonNullable<GlassesPayload[\"firmware\"]>\ntype GapReason = \"clock_untrusted\" | \"reporter_stopped\"\n\ninterface RecordBase {\n schemaVersion: typeof FLEET_SCHEMA_VERSION\n recordId: string\n phoneDeviceId: string\n collectorSessionId: string\n sequence: number\n observedAt: string\n capabilities: Capability[]\n}\n\nconst FAST_CHECKPOINT_MS = 60_000\nconst IDLE_CHECKPOINT_MS = 15 * 60_000\nconst SNAPSHOT_INTERVAL_MS = 15 * 60_000\n/** State changes this close together are one snapshot. */\nconst SNAPSHOT_DEBOUNCE_MS = 2_000\n/**\n * How far the wall clock may part from the monotonic clock between checkpoints, and how late a checkpoint may be,\n * before the collector stops believing the span between two checkpoints.\n */\nconst CLOCK_DRIFT_LIMIT_MS = 2 * 60_000\nconst BATTERY_SNAPSHOT_STEP = 5\n/** Inventory changes this close together are one record: an install changes the set, then its reasons, then its digest. */\nconst INVENTORY_DEBOUNCE_MS = 2_000\n/**\n * How long connected glasses may go without showing a serial number before they are identified without one. They send\n * it, with their Bluetooth address, within a second or two of connecting; this leaves ample room for a slow answer\n * while still identifying a pair that has none well before its first 60-second checkpoint.\n */\nconst IDENTITY_SETTLE_MS = 15_000\n/**\n * The Mentra App is in the foreground, to Fleet, from the moment it becomes active, once it has been active for\n * FOREGROUND_SETTLE_MS since then; and it stays there through a departure shorter than FOREGROUND_GRACE_MS, which, if\n * the app does not come back, ends the visit when the app left. The app state flaps: Android reports the activities\n * around a launch, such as a permission dialog, as the app going to the background, and iOS goes inactive for\n * Control Center, a notification pulled down, Face ID or a system alert. A third of foreground sessions in the device\n * evidence lasted under a second, and a foreground session makes its account active.\n *\n * 2 s is longer than any of those flickers and shorter than a person's look at the app. 5 s spans a dialog or an\n * overlay a person dismisses, which is still one visit; a departure that long is counted in it, at most 5 s a time.\n */\nconst FOREGROUND_SETTLE_MS = 2_000\nconst FOREGROUND_GRACE_MS = 5_000\nconst FOREGROUND_KEY = \"app_foreground\"\n/** At most this many photo stages wait for glasses being identified; a burst beyond it in those seconds is dropped. */\nconst MAX_HELD_PHOTOS = 32\nconst MAX_TEXT = 128\n/** A session cannot outlast several caps between two checkpoints; this only bounds a loop. */\nconst MAX_CAP_TURNS = 8\nconst FLEET_ID = /^[A-Za-z0-9._:-]+$/\n\n/**\n * Glasses models that have no battery reporting. Their battery is `unsupported`, not `unknown`, and a record made\n * while they are connected does not claim `glasses_battery`. Every model the Bluetooth SDK connects today reports one\n * (G1, G2, Mentra Live, Mentra Display, Mach1, Z100, NIMO and AR99 all set the glasses' `batteryLevel`), so the list\n * is empty; a model that comes without one is named here, as `deviceModel` names it.\n */\nconst MODELS_WITHOUT_BATTERY: ReadonlySet<string> = new Set<string>()\n\n/**\n * What the phone measures without glasses. With glasses connected it measures all of them, less the battery of glasses\n * that cannot report one. A phone that cannot report its own battery does not claim `phone_battery`.\n */\n/** A disconnect this soon after the person asked for one is theirs. */\nconst USER_DISCONNECT_WINDOW_MS = 10_000\n\nconst PHONE_CAPABILITIES: Capability[] = [\n \"glasses_connection\",\n \"miniapp_execution\",\n \"app_foreground\",\n \"engine_active\",\n \"photo_operations\",\n \"phone_battery\",\n // Phase 12: what this Mentra App measures whatever is connected.\n \"miniapp_failures\",\n \"glasses_connectivity\",\n \"miniapp_telemetry\",\n]\n\nfunction warn(what: string, error: unknown): void {\n // Only the failure's message: an error from here must never carry a package, a serial or a record into the logs.\n console.warn(`FleetCollector: ${what} failed:`, error instanceof Error ? error.message : \"unknown error\")\n}\n\nfunction text(value: string | null | undefined): string | undefined {\n const trimmed = value?.trim().slice(0, MAX_TEXT)\n return trimmed ? trimmed : undefined\n}\n\nfunction iso(wall: number): string {\n return new Date(wall).toISOString()\n}\n\n/**\n * The inventory record's payload for what the source lists, or null when there is nothing to send: the source does not\n * know yet, or what it listed cannot make a valid record. A miniapp that cannot be described (no package, version or\n * digest, or no known reason) is left out and counted in the warning, not allowed to sink the rest. The list is sorted\n * by package, one entry per package, and a listing past the contract's 500 keeps the first 500, so the same phone always\n * says the same thing.\n */\nfunction inventoryPayload(listed: readonly InstalledMiniapp[] | null): FleetMiniappInventoryPayload | null {\n if (listed === null) return null\n const byPackage = new Map<string, FleetMiniappInventoryPayload[\"miniapps\"][number]>()\n let skipped = 0\n for (const app of listed) {\n const packageName = text(app?.packageName)\n const versionName = text(app?.versionName)\n const digest = text(app?.digest)\n const reasons = FLEET_INSTALL_REASONS.filter((reason) => app?.reasons?.includes(reason))\n if (!packageName || !versionName || !digest || reasons.length === 0) {\n skipped += 1\n continue\n }\n byPackage.set(packageName, {packageName, versionName, digest, reasons})\n }\n const miniapps = [...byPackage.values()]\n .sort((a, b) => (a.packageName < b.packageName ? -1 : a.packageName > b.packageName ? 1 : 0))\n .slice(0, FLEET_LIMITS.maxInventoryMiniapps)\n if (skipped > 0 || byPackage.size > miniapps.length) {\n console.warn(\n `FleetCollector: the inventory left out ${skipped} undescribable and ${\n byPackage.size - miniapps.length\n } surplus miniapp(s)`,\n )\n }\n const parsed = FleetMiniappInventoryPayloadSchema.safeParse({miniapps})\n if (!parsed.success) {\n console.warn(\"FleetCollector: no inventory, what the source listed is not a valid record\")\n return null\n }\n return parsed.data\n}\n\nfunction isForeground(): boolean {\n return AppState.currentState === \"active\"\n}\n\n/** Glasses are connected, and they are not the simulated ones, which are no part of any fleet. */\nfunction realGlassesConnected(): boolean {\n const s = useGlassesStore.getState()\n return s.connection.state === \"connected\" && !isSimulatedGlasses(s.deviceModel)\n}\n\n/** Glasses connected or the Mentra App in the foreground: checkpoints every 60 s. */\nfunction isFastActivity(activity: FleetActivity): boolean {\n return activity === \"glasses_connection\" || activity === \"app_foreground\"\n}\n\nfunction mapConnection(state: string): ConnectionState {\n if (state === \"connected\") return \"connected\"\n if (state === \"disconnected\") return \"disconnected\"\n if (state === \"scanning\" || state === \"connecting\" || state === \"bonding\") return \"connecting\"\n return \"unknown\"\n}\n\nlet packageVersionCache: {engine?: string; sdk?: string} | undefined\nfunction packageVersions(): {engine?: string; sdk?: string} {\n if (packageVersionCache) return packageVersionCache\n const versions: {engine?: string; sdk?: string} = {}\n try {\n versions.engine = text((require(\"../../../package.json\") as {version?: string}).version)\n } catch {\n // Left out of the snapshot.\n }\n try {\n versions.sdk = text((require(\"@mentra/bluetooth-sdk/package.json\") as {version?: string}).version)\n } catch {\n // Left out of the snapshot.\n }\n return (packageVersionCache = versions)\n}\n\n/** The phone's part of a snapshot, or null where the contract has no value for this platform. */\nfunction phoneInfo(): SnapshotPayload[\"phone\"] | null {\n const os = Platform.OS\n if (os !== \"ios\" && os !== \"android\") return null\n const osVersion =\n os === \"android\"\n ? String((Platform.constants as {Release?: string} | undefined)?.Release ?? Platform.Version)\n : String(Platform.Version)\n const model = text(Device.modelName)\n const {engine, sdk} = packageVersions()\n return {\n ...(model ? {model} : {}),\n os,\n osVersion: text(osVersion) ?? \"unknown\",\n // The native application's own version and build number: expo-constants no longer has them.\n appVersion: text(Application.nativeApplicationVersion ?? Constants.expoConfig?.version) ?? \"unknown\",\n appBuild: text(Application.nativeBuildVersion) ?? \"unknown\",\n ...(engine ? {engineVersion: engine} : {}),\n ...(sdk ? {sdkVersion: sdk} : {}),\n }\n}\n\ntype GlassesState = ReturnType<typeof useGlassesStore.getState>\n\n/** The glasses fields the collector reacts to, as one string so the store only calls back when one of them changes. */\nfunction glassesFingerprint(s: GlassesState): string {\n // The store runs this on every update, inside the update: it must not throw into whoever is updating the store.\n try {\n return [\n s.connection.state,\n s.connection.state === \"connected\" && s.connection.fullyBooted ? \"1\" : \"0\",\n s.deviceModel,\n s.serialNumber,\n s.bluetoothMacAddress,\n s.leftMacAddress,\n s.bluetoothName,\n s.appVersion,\n s.buildNumber,\n s.mtkFirmwareVersion,\n s.besFirmwareVersion,\n s.androidVersion,\n s.firmwareVersion,\n s.batteryLevel,\n s.charging ? \"1\" : \"0\",\n ].join(\"\\u0001\")\n } catch {\n return \"\"\n }\n}\n\n/** The glasses' versions that are known (blank ones are left out). The APK version carries its build number. */\nfunction firmwareOf(s: GlassesState): Firmware {\n const apkVersion = text(s.appVersion)\n const apkBuild = text(s.buildNumber)\n const apk = apkVersion && apkBuild ? `${apkVersion} (${apkBuild})` : apkVersion || apkBuild\n const mtk = text(s.mtkFirmwareVersion)\n const bes = text(s.besFirmwareVersion)\n const os = text(s.androidVersion) ?? text(s.firmwareVersion)\n return {\n ...(apk ? {apk: apk.slice(0, MAX_TEXT)} : {}),\n ...(mtk ? {mtk} : {}),\n ...(bes ? {bes} : {}),\n ...(os ? {os} : {}),\n }\n}\n\n/**\n * The glasses as last seen in this run. The native layer clears a pair's identity when it disconnects, so the\n * collector keeps what it saw while the glasses were there: a disconnected pair is still described, and still the\n * same device.\n *\n * A pair is identified, and its binding fixed for the run, once it has shown its serial number, or once it has been\n * connected for IDENTITY_SETTLE_MS without one; until then nothing is attributed to it, and a photo stage waits for\n * it. Glasses are connected a moment before they send their serial and their own Bluetooth address, so a binding\n * fixed sooner would make a provisional device of every pair that has a serial, and key one that has none by its\n * Bluetooth name on some connections and by its address on others. A pair that leaves sooner is identified by what\n * it showed.\n */\ninterface KnownGlasses {\n /** The product (see `glassesProduct`): one pair is one model whatever model string it reports. */\n model: string\n /** What the pair has shown of who it is, each null until it has. */\n identity: PairIdentity\n /** When the pair was first seen connected in this run (monotonic); null while it has only been looked for. */\n connectedSinceMono: number | null\n /** Fixed once the pair is identified. A serial that comes later still replaces a provisional binding. */\n binding: FleetDeviceBinding | null\n firmware: Firmware\n}\n\n/** What tells one pair from another of its model, strongest first: its serial, its own Bluetooth address, its name. */\ninterface PairIdentity {\n serial: string | null\n address: string | null\n name: string | null\n}\n\nconst IDENTIFIERS = [\"serial\", \"address\", \"name\"] as const\n\nfunction lowered(value: string | null | undefined): string | null {\n const trimmed = typeof value === \"string\" ? value.trim().toLowerCase() : \"\"\n return trimmed ? trimmed : null\n}\n\nfunction pairIdentity(s: GlassesIdentitySource): PairIdentity {\n return {\n serial: usableSerial(s),\n // The address the glasses report as their own, the same on every phone; the left arm's for glasses in two.\n address: lowered(s.bluetoothMacAddress) ?? lowered(s.leftMacAddress),\n name: lowered(s.bluetoothName),\n }\n}\n\n/**\n * Whether glasses showing `now` are the pair that showed `before`. The strongest identifier both show decides. One\n * that went blank says nothing (the native layer clears the serial and the address when the link drops), and neither\n * does showing nothing yet: only a difference tells another pair.\n */\nfunction samePair(before: PairIdentity, now: PairIdentity): boolean {\n for (const field of IDENTIFIERS) {\n const a = before[field]\n const b = now[field]\n if (a !== null && b !== null) return a === b\n }\n const shows = (identity: PairIdentity) => IDENTIFIERS.some((field) => identity[field] !== null)\n return !shows(before) || !shows(now)\n}\n\n/** A photo stage seen while the glasses were being identified, kept to be written against them once they are. */\ninterface HeldPhoto {\n observedAt: number\n operationId: string\n payload: Extract<FleetRecord, {kind: \"photo_operation\"}>[\"payload\"]\n}\n\n/** The battery of the pair `known` describes: it goes when a new connection starts or another pair is identified. */\ninterface BatteryReading {\n level: number\n charging: boolean\n /** When the collector saw this value. It is not refreshed by later snapshots or uploads. */\n observedAt: number\n}\n\ntype PhoneBatteryValue =\n | {state: \"measured\"; level: number; charging: boolean}\n | {state: \"unsupported\" | \"unknown\"; level?: undefined; charging?: undefined}\n/** The phone's battery as last read, and when the collector first saw it so. It is not refreshed by later snapshots. */\ntype PhoneBatteryHeld = PhoneBatteryValue & {observedAt: number}\n\n/** A source's reading as a battery state: a level outside 0 to 100, or not a number, is unknown, never a number. */\nfunction phoneBatteryState(read: PhoneBatteryReading | \"unsupported\" | null): PhoneBatteryValue {\n if (read === \"unsupported\") return {state: \"unsupported\"}\n const level = read?.level\n if (typeof level !== \"number\" || !Number.isFinite(level) || level < 0 || level > 100) return {state: \"unknown\"}\n return {state: \"measured\", level: Math.round(level), charging: read?.charging === true}\n}\n\n/** What the last snapshot said, so a change worth a new snapshot can be told from one that is not. */\ninterface SnapshotMarks {\n phoneBattery: PhoneBatteryValue\n /** The binding of the glasses, once they are identified, as a key; \"\" before. */\n identity: string\n /** The glasses were connected. The states short of it (scanning, connecting, disconnected) are all \"not\". */\n linked: boolean\n batteryMeasured: boolean\n level: number\n charging: boolean\n versions: string\n}\n\ninterface Instant {\n wall: number\n mono: number\n}\n\ninterface Session {\n key: string\n activity: FleetActivity\n id: string\n packageName?: string\n /** Glasses sessions: fixed when the session is first reported, and never changed after. */\n binding?: FleetDeviceBinding\n startedWall: number\n startedMono: number\n /** The elapsed time at the last checkpoint that carried this session; null until it has been reported. */\n reportedElapsedMs: number | null\n /** Its activity stopped then: the session is counted up to there, and ends there unless it resumes in its grace. */\n endAt?: Instant\n}\n\ninterface SessionSpec {\n activity: FleetActivity\n packageName?: string\n /** When the activity began, if before the session opens. */\n since?: Instant\n}\n\ninterface Env {\n queue: FleetQueue\n now: () => number\n monotonic: () => number\n modelsWithoutBattery: ReadonlySet<string>\n inventory: InventorySource\n phoneBattery: PhoneBatterySource\n}\n\nconst NONE: ReadonlySet<string> = new Set()\n\n/**\n * The app's inventory source: the registry's side registers itself with `setFleetInventorySource`, and every collector\n * the app creates reads through this. Until one is set it lists nothing known, so no inventory is sent. Setting one\n * counts as a change.\n */\nconst inventoryListeners = new Set<() => void>()\nlet appInventorySource: InventorySource | null = null\nlet stopFollowingSource: (() => void) | null = null\n\nfunction notifyInventory(): void {\n for (const listener of [...inventoryListeners]) {\n try {\n listener()\n } catch (error) {\n warn(\"inventory listener\", error)\n }\n }\n}\n\n/** Wires (or, with null, unwires) the source of what is installed. */\nexport function setFleetInventorySource(source: InventorySource | null): void {\n stopFollowingSource?.()\n stopFollowingSource = null\n appInventorySource = source\n if (source) {\n try {\n stopFollowingSource = source.subscribe(notifyInventory)\n } catch (error) {\n warn(\"following the inventory source\", error)\n }\n }\n notifyInventory()\n}\n\nconst appInventory: InventorySource = {\n list: () => appInventorySource?.list() ?? null,\n subscribe(listener) {\n inventoryListeners.add(listener)\n return () => void inventoryListeners.delete(listener)\n },\n}\n\n/** One collector run: everything a `start()` opens, and everything `stop()` closes. */\nclass CollectorRun {\n private readonly sessions = new Map<string, Session>()\n private readonly cleanups: Array<() => void> = []\n private stopped = false\n private phoneId = \"\"\n\n /** The wall and monotonic clocks at the last checkpoint; the clocks are compared across this span. */\n private anchorWall = 0\n private anchorMono = 0\n /** The Mentra App left the foreground since the anchor: a silent gap then looks like suspension. */\n private leftForeground = false\n\n /** The visit to the Mentra App going on: when it began, and when the app left it, within the grace. */\n private visitStart: Instant | null = null\n private visitLeftAt: Instant | null = null\n /** The visit has settled into a foreground session (see FOREGROUND_SETTLE_MS). */\n private foreground = false\n private foregroundTimer: number | null = null\n private foregroundDueMono = 0\n\n private checkpointTimer: number | null = null\n private checkpointDueMono = 0\n private snapshotDebounce: number | null = null\n private inventoryDebounce: number | null = null\n /** What the last inventory record of this run said, so a change that left the listing as it was writes nothing. */\n private lastInventoryKey: string | null = null\n /** When the last snapshot was written (monotonic), and what it said, so a repeat of it can be skipped. */\n private lastSnapshotMono = 0\n private lastSnapshotKey: string | null = null\n\n private known: KnownGlasses | null = null\n /** The store's last connection state, and when the glasses last dropped (for a reconnect's time). */\n private rawConnection: string | null = null\n private disconnectedAt: number | null = null\n private connectFailed = false\n /** Each miniapp's telemetry rate on this phone, for this run. */\n private readonly telemetryRate = new TelemetryRate()\n private heldPhotos: HeldPhoto[] = []\n private battery: BatteryReading | null = null\n private phoneBattery: PhoneBatteryHeld | null = null\n private connection: {state: ConnectionState; observedAt: number} = {state: \"disconnected\", observedAt: 0}\n private marks: SnapshotMarks | null = null\n\n constructor(\n private readonly env: Env,\n private readonly partition: string,\n private readonly collectorSessionId: string,\n ) {}\n\n // --- lifecycle -----------------------------------------------------------------------------------------------\n\n begin(): void {\n this.phoneId = phoneDeviceId()\n const wall = this.env.now()\n this.anchorWall = wall\n this.anchorMono = this.env.monotonic()\n this.leftForeground = !isForeground()\n this.followForeground()\n this.connection = {state: mapConnection(useGlassesStore.getState().connection.state), observedAt: wall}\n this.trackGlasses(wall)\n this.openMissing()\n\n this.cleanups.push(\n useGlassesStore.subscribe(glassesFingerprint, () => this.guard(\"glasses change\", () => this.onStateChange())),\n miniappRunningRegistry.subscribe(() => this.guard(\"miniapp change\", () => this.onStateChange())),\n nativeMiniappExecution.subscribe(() => this.guard(\"miniapp change\", () => this.onStateChange())),\n fleetEvents.subscribe({\n launch: (event) => this.guard(\"launch\", () => this.onLaunch(event)),\n photo: (event) => this.guard(\"photo\", () => this.onPhoto(event)),\n telemetry: (event) => this.guard(\"telemetry\", () => this.onTelemetry(event)),\n crash: (event) => this.guard(\"crash\", () => this.onCrash(event)),\n install: (event) => this.guard(\"install\", () => this.onInstall(event)),\n connection: (event) => this.guard(\"connection\", () => this.onConnection(event)),\n }),\n )\n const appState = AppState.addEventListener(\"change\", (state) =>\n this.guard(\"app state\", () => {\n if (state !== \"active\") this.leftForeground = true\n this.onStateChange()\n // In the background the process may be suspended or killed before the visit's grace is over: the visit is\n // checkpointed now, up to when the app left, so that time is not lost with it. A blip that stays short of\n // the background (iOS inactive) writes nothing.\n if (state === \"background\" && this.sessions.get(FOREGROUND_KEY)?.endAt) this.flush()\n }),\n )\n this.cleanups.push(() => appState.remove())\n this.cleanups.push(this.env.phoneBattery.subscribe(() => this.guard(\"phone battery\", () => this.onPhoneBattery())))\n this.refreshPhoneBattery()\n\n this.takeSnapshot()\n this.cleanups.push(\n this.env.inventory.subscribe(() => this.guard(\"inventory change\", () => this.scheduleInventory())),\n )\n this.takeInventory(true)\n // Launches the engine made before this run could listen: it restores miniapps while the account may still be\n // being resolved, and the reporter discards them when the account changes, so these are this run's account's.\n for (const {event, observedAt} of fleetEvents.takeUndeliveredLaunches()) {\n this.guard(\"launch\", () => this.onLaunch(event, observedAt))\n }\n this.arm(this.cadence())\n }\n\n /** Ends every session in the partition, then stops listening. */\n end(): void {\n if (this.stopped) return\n try {\n if (this.checkClock()) {\n // Whatever the jump left open was just reopened and has nothing confirmed to close.\n this.sessions.clear()\n } else {\n this.writeCheckpoint(new Set(this.sessions.keys()))\n }\n } catch (error) {\n warn(\"final checkpoint\", error)\n }\n this.guard(\"photos\", () => this.releasePhotos(true))\n this.abort()\n }\n\n /** Stops listening and drops the timers, without writing anything. */\n abort(): void {\n this.stopped = true\n if (this.checkpointTimer !== null) BgTimer.clearTimeout(this.checkpointTimer)\n if (this.snapshotDebounce !== null) BgTimer.clearTimeout(this.snapshotDebounce)\n if (this.foregroundTimer !== null) BgTimer.clearTimeout(this.foregroundTimer)\n if (this.inventoryDebounce !== null) BgTimer.clearTimeout(this.inventoryDebounce)\n this.checkpointTimer = this.snapshotDebounce = this.foregroundTimer = this.inventoryDebounce = null\n for (const cleanup of this.cleanups.splice(0)) {\n try {\n cleanup()\n } catch (error) {\n warn(\"cleanup\", error)\n }\n }\n }\n\n flush(): void {\n this.guard(\"checkpoint\", () => {\n if (!this.checkClock()) this.writeCheckpoint(NONE)\n })\n }\n\n private guard(what: string, run: () => void): void {\n if (this.stopped) return\n try {\n run()\n } catch (error) {\n warn(what, error)\n }\n }\n\n // --- reacting to the engine ----------------------------------------------------------------------------------\n\n private onStateChange(): void {\n this.followForeground()\n this.trackGlasses(this.env.now())\n if (!this.checkClock()) this.reconcileSessions()\n this.releasePhotos()\n this.evaluateSnapshotTriggers()\n }\n\n /**\n * Phase 12's connection events, from the store's own states: connected to disconnected is a disconnect (the\n * person's own within 10 s of their asking, otherwise a lost link); connecting or bonding to disconnected without\n * connecting is a failed connection, once until the glasses connect again and never while a lost link waits to come\n * back; connected again after a disconnect is a reconnect, with the time it took.\n * Simulated glasses have none.\n */\n private noteConnectionChange(raw: string, simulated: boolean, wall: number): void {\n const previous = this.rawConnection\n this.rawConnection = raw\n if (previous === null || previous === raw || simulated) return\n if (raw === \"disconnected\" && previous === \"connected\") {\n const theirs = wall - fleetEvents.lastUserDisconnect() < USER_DISCONNECT_WINDOW_MS\n this.onConnection({event: \"disconnected\", category: theirs ? \"user_action\" : \"link_lost\"})\n this.disconnectedAt = theirs ? null : wall\n } else if (raw === \"disconnected\" && (previous === \"connecting\" || previous === \"bonding\")) {\n // Glasses away retry all the time: a lost link waiting to come back is its disconnect, and only the first failed\n // connection between two connected spells is one, so an hour of retries is not an hour of records.\n if (this.disconnectedAt === null && !this.connectFailed) {\n this.connectFailed = true\n this.onConnection({event: \"connect_failed\", category: \"unknown\"})\n }\n } else if (raw === \"connected\") {\n this.connectFailed = false\n if (this.disconnectedAt !== null) {\n this.onConnection({event: \"reconnected\", category: \"unknown\", reconnectMs: wall - this.disconnectedAt})\n this.disconnectedAt = null\n }\n }\n }\n\n /** Notes what the glasses store says now: the connection, the glasses' identity and versions, and the battery. */\n private trackGlasses(wall: number): void {\n const s = useGlassesStore.getState()\n const state = mapConnection(s.connection.state)\n this.noteConnectionChange(s.connection.state, isSimulatedGlasses(s.deviceModel), wall)\n if (state !== this.connection.state) {\n // Glasses that start connecting are not assumed to be the pair that was last here: a new connection is\n // identified afresh, from what the glasses say, before anything is attributed to a device. Only a new\n // connection forgets: while one is tearing down the native layer clears the identity (model first) before it\n // reports disconnected, and the departing pair is still the pair its last records are about.\n if (this.connection.state === \"disconnected\") this.forgetGlasses()\n this.connection = {state, observedAt: wall}\n }\n // The pair first: a battery reading belongs to the pair it was seen on, and another pair starts without one.\n this.rememberGlasses(s)\n const simulated = isSimulatedGlasses(s.deviceModel)\n if (this.batteryUnsupported()) {\n // Glasses that cannot report a battery have no reading: a level in the store is not theirs.\n this.battery = null\n } else if (\n // A battery value in the store is only believed while real glasses are connected; afterwards the last reading\n // keeps the time it was seen.\n s.connection.state === \"connected\" &&\n !simulated &&\n (!this.battery || this.battery.level !== s.batteryLevel || this.battery.charging !== s.charging)\n ) {\n this.battery = {level: s.batteryLevel, charging: s.charging, observedAt: wall}\n }\n }\n\n /** Notes the phone's battery as its source holds it; a value that did not change keeps the time it was first seen. */\n private trackPhoneBattery(wall: number): void {\n let read: PhoneBatteryReading | \"unsupported\" | null = null\n try {\n read = this.env.phoneBattery.read()\n } catch (error) {\n warn(\"reading the phone battery\", error)\n }\n const next = phoneBatteryState(read)\n const held = this.phoneBattery\n if (held && held.state === next.state && held.level === next.level && held.charging === next.charging) return\n this.phoneBattery = {...next, observedAt: wall}\n }\n\n private refreshPhoneBattery(): void {\n try {\n this.env.phoneBattery.refresh()\n } catch (error) {\n warn(\"refreshing the phone battery\", error)\n }\n }\n\n private onPhoneBattery(): void {\n this.trackPhoneBattery(this.env.now())\n this.evaluateSnapshotTriggers()\n }\n\n /** Nothing seen of the glasses so far is about the pair that comes next: not its identity, versions or battery. */\n private forgetGlasses(): void {\n // A photo still waiting for the pair that was here is that pair's.\n this.releasePhotos(true)\n this.known = null\n this.battery = null\n }\n\n private rememberGlasses(s: GlassesState): void {\n const reported = text(s.deviceModel)\n if (!reported) return\n if (isSimulatedGlasses(reported)) {\n // The store names glasses that are no device (the simulated ones): the pair remembered before is not them.\n this.forgetGlasses()\n return\n }\n const model = glassesProduct(reported)\n const now = pairIdentity(s)\n // What was learned about the pair before this carries over only if it is the same pair (see `samePair`). A second\n // pair of the same model starts from nothing.\n const before = this.known\n const same = before !== null && before.model === model && samePair(before.identity, now)\n if (before !== null && !same) {\n // Another pair, swapped in with no disconnect between: what waited for the first pair is the first pair's, and\n // the last reading was its battery.\n this.releasePhotos(true)\n this.battery = null\n }\n const kept = same ? before : null\n const identity: PairIdentity = {\n serial: now.serial ?? kept?.identity.serial ?? null,\n address: now.address ?? kept?.identity.address ?? null,\n name: now.name ?? kept?.identity.name ?? null,\n }\n // The serial, whenever the pair shows one, is its identity, and replaces a provisional stand-in.\n const binding =\n identity.serial !== null && kept?.binding?.kind !== \"serial\"\n ? serialBinding(model, identity.serial)\n : (kept?.binding ?? null)\n this.known = {\n model,\n identity,\n connectedSinceMono:\n kept?.connectedSinceMono ?? (this.connection.state === \"connected\" ? this.env.monotonic() : null),\n binding,\n firmware: kept ? {...kept.firmware, ...firmwareOf(s)} : firmwareOf(s),\n }\n }\n\n /** The pair known here is a model without battery reporting. */\n private batteryUnsupported(): boolean {\n return this.known !== null && this.env.modelsWithoutBattery.has(this.known.model)\n }\n\n /** The binding of the glasses the store describes now, once they are identified (see `identified`). */\n private currentBinding(final = false): FleetDeviceBinding | null {\n this.rememberGlasses(useGlassesStore.getState())\n return this.identified(final)\n }\n\n /**\n * The binding of the glasses known here, or null while they are being identified (see KnownGlasses) or were only\n * ever looked for. Glasses that have left are identified by what they showed; so are they with `final`, for what\n * cannot wait.\n */\n private identified(final = false): FleetDeviceBinding | null {\n const known = this.known\n if (!known || known.binding) return known?.binding ?? null\n const since = known.connectedSinceMono\n if (since === null) return null\n const departed = this.connection.state !== \"connected\"\n if (final || departed || this.env.monotonic() - since >= IDENTITY_SETTLE_MS) {\n known.binding = provisionalBinding(known.model, known.identity.address ?? known.identity.name)\n }\n return known.binding\n }\n\n // --- the foreground ------------------------------------------------------------------------------------------\n\n private instant(): Instant {\n return {wall: this.env.now(), mono: this.env.monotonic()}\n }\n\n /**\n * Follows the app state into the foreground as Fleet counts it (see FOREGROUND_SETTLE_MS): a visit begins when the\n * app becomes active, becomes a foreground session once the app is active 2 s after that, and is over once the app\n * has been away for 5 s, ending when it left. Writes nothing: the sessions follow it.\n */\n private followForeground(): void {\n const now = this.instant()\n const active = isForeground()\n // Away for the grace, the visit is over, even if the app is back by now: back that late (the process was\n // suspended in between, and the timer could not fire), it is a new visit.\n if (this.visitLeftAt && now.mono - this.visitLeftAt.mono >= FOREGROUND_GRACE_MS) {\n this.visitStart = this.visitLeftAt = null\n this.foreground = false\n }\n const session = this.sessions.get(FOREGROUND_KEY)\n if (active) {\n if (this.visitLeftAt) {\n // Back within the grace: the same visit, the time away included.\n this.visitLeftAt = null\n if (session) delete session.endAt\n }\n this.visitStart ??= now\n if (!this.foreground && now.mono - this.visitStart.mono >= FOREGROUND_SETTLE_MS) this.foreground = true\n } else if (this.visitStart && !this.visitLeftAt) {\n this.visitLeftAt = now\n if (session) session.endAt = now\n }\n this.armForegroundTimer(now, active)\n }\n\n /** When the foreground can next change with the app state unchanged: the visit settling, or its grace ending. */\n private armForegroundTimer(now: Instant, active: boolean): void {\n let due: number | null = null\n if (this.visitLeftAt) due = this.visitLeftAt.mono + FOREGROUND_GRACE_MS\n else if (active && this.visitStart && !this.foreground) due = this.visitStart.mono + FOREGROUND_SETTLE_MS\n if (due !== null && this.foregroundTimer !== null && due === this.foregroundDueMono) return\n if (this.foregroundTimer !== null) BgTimer.clearTimeout(this.foregroundTimer)\n this.foregroundTimer = null\n if (due === null) return\n this.foregroundDueMono = due\n const timer: number = BgTimer.setTimeout(\n () =>\n this.guard(\"app state\", () => {\n if (this.foregroundTimer !== timer) return\n this.foregroundTimer = null\n this.onStateChange()\n }),\n Math.max(0, due - now.mono),\n )\n this.foregroundTimer = timer\n }\n\n // --- sessions ------------------------------------------------------------------------------------------------\n\n private desiredSessions(): Map<string, SessionSpec> {\n const wanted = new Map<string, SessionSpec>()\n wanted.set(\"engine_active\", {activity: \"engine_active\"})\n // From when the visit began, which is before it settled.\n if (this.foreground) {\n wanted.set(FOREGROUND_KEY, {activity: \"app_foreground\", ...(this.visitStart ? {since: this.visitStart} : {})})\n }\n if (realGlassesConnected()) wanted.set(\"glasses_connection\", {activity: \"glasses_connection\"})\n // Local miniapps execute while their JS context runs; native built-ins as the apps store derives it.\n for (const name of [...miniappRunningRegistry.getAll(), ...nativeMiniappExecution.getAll()]) {\n const packageName = text(name)\n if (packageName) wanted.set(`miniapp_execution:${packageName}`, {activity: \"miniapp_execution\", packageName})\n }\n return wanted\n }\n\n private open(key: string, spec: SessionSpec): Session {\n const session: Session = {\n key,\n activity: spec.activity,\n id: newId(),\n ...(spec.packageName ? {packageName: spec.packageName} : {}),\n startedWall: spec.since?.wall ?? this.env.now(),\n startedMono: spec.since?.mono ?? this.env.monotonic(),\n reportedElapsedMs: null,\n }\n this.sessions.set(key, session)\n return session\n }\n\n private openMissing(): void {\n for (const [key, spec] of this.desiredSessions()) if (!this.sessions.has(key)) this.open(key, spec)\n }\n\n /** Makes the open sessions match what is happening now: ends the ones that stopped (checkpointing at once), opens new ones. */\n private reconcileSessions(): void {\n const wanted = this.desiredSessions()\n const ending = new Set<string>()\n for (const key of this.sessions.keys()) if (!wanted.has(key)) ending.add(key)\n // Close first: a session opened in the same breath is not reported until a checkpoint after its identity settles.\n if (ending.size > 0) this.writeCheckpoint(ending)\n let fastSince: number | null = null\n for (const [key, spec] of wanted) {\n if (this.sessions.has(key)) continue\n const session = this.open(key, spec)\n if (isFastActivity(session.activity)) fastSince = Math.min(fastSince ?? Infinity, session.startedMono)\n }\n this.ensureCadence(fastSince)\n }\n\n /** 60-second checkpoints while glasses are connected or the Mentra App is in the foreground; 15 minutes otherwise. */\n private isFast(): boolean {\n for (const session of this.sessions.values()) if (isFastActivity(session.activity)) return true\n return false\n }\n\n private cadence(): number {\n return this.isFast() ? FAST_CHECKPOINT_MS : IDLE_CHECKPOINT_MS\n }\n\n /** The next checkpoint is `delay` from now, replacing any that is pending. */\n private arm(delay: number): void {\n if (this.checkpointTimer !== null) BgTimer.clearTimeout(this.checkpointTimer)\n this.checkpointDueMono = this.env.monotonic() + delay\n const timer: number = BgTimer.setTimeout(() => this.onCheckpointTimer(timer), delay)\n this.checkpointTimer = timer\n }\n\n private onCheckpointTimer(fired: number): void {\n if (this.stopped || this.checkpointTimer !== fired) return\n try {\n this.flush()\n // The phone's battery is read on the wake-ups the collector already has; the reading arrives later.\n this.refreshPhoneBattery()\n // Glasses connected long enough are identified by now, without a change in the store to say so.\n this.guard(\"photos\", () => this.releasePhotos())\n this.guard(\"snapshot\", () => {\n this.evaluateSnapshotTriggers()\n this.periodicSnapshot()\n })\n } finally {\n // A checkpoint that failed part-way must not end the cadence.\n if (!this.stopped && this.checkpointTimer === fired) this.arm(this.cadence())\n }\n }\n\n /**\n * Activity that needs a 60 s checkpoint brings the next one forward, to 60 s after it began (`fastSince`, by default\n * now); a 15-minute wait does not outlast it.\n */\n private ensureCadence(fastSince: number | null = null): void {\n if (this.checkpointTimer === null) {\n this.arm(this.cadence())\n return\n }\n if (!this.isFast()) return\n const now = this.env.monotonic()\n const due = Math.max(now, (fastSince ?? now) + FAST_CHECKPOINT_MS)\n if (this.checkpointDueMono > due) this.arm(due - now)\n }\n\n // --- checkpoints ---------------------------------------------------------------------------------------------\n\n /**\n * Reports every open session, those in `ending` as ended and removed. Writes at once and sets the next checkpoint.\n * A session that has run for the longest time one record may carry ends there, and a new one carries on.\n */\n private writeCheckpoint(ending: ReadonlySet<string>): void {\n const wall = this.env.now()\n const mono = this.env.monotonic()\n const entries: UsageSession[] = []\n for (const open of [...this.sessions.values()]) {\n let session = open\n for (\n let turn = 0;\n turn < MAX_CAP_TURNS && mono - session.startedMono >= FLEET_LIMITS.maxSessionElapsedMs;\n turn += 1\n ) {\n const capped = this.entryFor(session, mono, wall, true)\n if (capped) entries.push(capped)\n session = this.successorOf(session)\n this.sessions.set(session.key, session)\n }\n const entry = this.entryFor(session, mono, wall, ending.has(session.key))\n if (entry) entries.push(entry)\n }\n for (const key of ending) this.sessions.delete(key)\n this.anchorWall = wall\n this.anchorMono = mono\n this.leftForeground = !isForeground()\n // A close that closed nothing reportable (a connection that was never identified) is not worth a record.\n if (ending.size === 0 || entries.some((entry) => entry.ended)) this.emitCheckpoints(entries, wall)\n this.arm(this.cadence())\n }\n\n /** The session that carries on from one that reached the cap: the same activity, from the cap on. */\n private successorOf(session: Session): Session {\n const cap = FLEET_LIMITS.maxSessionElapsedMs\n return {\n ...session,\n id: newId(),\n startedWall: session.startedWall + cap,\n startedMono: session.startedMono + cap,\n reportedElapsedMs: null,\n }\n }\n\n /**\n * The session as a checkpoint entry, `ended` or not, or null if it cannot be reported yet (glasses not identified).\n * Its time is what the monotonic clock measured, never less than it already reported, never more than the wall\n * clock had given it by `wallLimit`, and never more than a session may report.\n */\n private entryFor(session: Session, mono: number, wallLimit: number, ended: boolean): UsageSession | null {\n if (session.endAt) {\n // The activity stopped then: no time after it is the session's, whether or not it ends now.\n mono = Math.min(mono, session.endAt.mono)\n wallLimit = Math.min(wallLimit, session.endAt.wall)\n }\n let binding: FleetDeviceBinding | undefined\n if (session.activity === \"glasses_connection\") {\n // Fixed at the first report, so a serial that arrives later never splits a connection into two devices. Not\n // reported before the glasses are identified, unless the session ends first.\n binding = session.binding ??= this.currentBinding(ended) ?? undefined\n if (!binding) return null\n }\n const floor = session.reportedElapsedMs ?? 0\n let elapsedMs = Math.floor(mono - session.startedMono)\n if (!Number.isFinite(elapsedMs)) elapsedMs = floor\n const wallSinceStart = Math.floor(wallLimit - session.startedWall)\n if (Number.isFinite(wallSinceStart)) elapsedMs = Math.min(elapsedMs, Math.max(wallSinceStart, 0))\n elapsedMs = Math.min(Math.max(elapsedMs, floor), FLEET_LIMITS.maxSessionElapsedMs)\n session.reportedElapsedMs = elapsedMs\n return this.describe(session, elapsedMs, ended, binding)\n }\n\n private describe(session: Session, elapsedMs: number, ended: boolean, binding?: FleetDeviceBinding): UsageSession {\n return {\n activity: session.activity,\n activitySessionId: session.id,\n ...(session.packageName ? {packageName: session.packageName} : {}),\n ...(binding ? {deviceBinding: binding} : {}),\n startedAt: iso(session.startedWall),\n elapsedMs,\n ended,\n }\n }\n\n private emitCheckpoints(entries: UsageSession[], observedAt: number): void {\n const size = FLEET_LIMITS.maxSessionsPerCheckpoint\n for (let index = 0; index < entries.length; index += size) {\n const sessions = entries.slice(index, index + size)\n this.emit(observedAt, (base) => ({...base, kind: \"usage_checkpoint\", payload: {sessions}}))\n }\n }\n\n // --- clock changes and suspension ----------------------------------------------------------------------------\n\n /**\n * Whether the span since the last checkpoint can be believed, and what to do if it cannot. Returns true if it\n * handled a break (the sessions have then been closed and started again).\n *\n * The monotonic clock runs while the device is awake; through sleep it pauses on Android and keeps counting on iOS\n * (see the file header). A timer that was due by it and did not fire means the process was not running. Two things\n * can be wrong with the span:\n * - The checkpoint is overdue by the monotonic clock: nothing here was running while that clock ran (the process\n * was suspended, or on iOS the device also slept). None of it was observed, so the sessions end at their last\n * checkpoint.\n * - The wall clock parted from the monotonic clock: the device slept with a clock that pauses in sleep (Android),\n * or somebody changed the clock. The monotonic time was observed and counts, so the sessions end at it; only the\n * jump itself is a gap.\n * The first wins: a reporter that was not running observed nothing, whatever the wall clock did.\n */\n private checkClock(): boolean {\n const wall = this.env.now()\n const mono = this.env.monotonic()\n if (this.checkpointTimer !== null && mono - this.checkpointDueMono > CLOCK_DRIFT_LIMIT_MS) {\n this.closeAtLastCheckpoint(wall, mono)\n return true\n }\n const monoDelta = mono - this.anchorMono\n const drift = wall - this.anchorWall - monoDelta\n if (Math.abs(drift) > CLOCK_DRIFT_LIMIT_MS) {\n this.closeAtObservedTime(wall, mono, monoDelta, drift)\n return true\n }\n return false\n }\n\n /** The reporter was silent: only what it had reported before counts, and everything since is a gap. */\n private closeAtLastCheckpoint(wall: number, mono: number): void {\n const from = this.anchorWall\n const closed: UsageSession[] = []\n for (const session of this.sessions.values()) {\n // A session that was never reported has nothing to close.\n if (session.reportedElapsedMs === null) continue\n if (session.activity === \"glasses_connection\" && !session.binding) continue\n closed.push(this.describe(session, session.reportedElapsedMs, true, session.binding))\n }\n this.sessions.clear()\n this.emitCheckpoints(closed, from)\n this.emitGap(\"reporter_stopped\", from, Math.max(wall, from), wall)\n this.startAgain(wall, mono)\n }\n\n /** The wall clock jumped: the awake time counts, ending where the monotonic clock says it did, and the jump is the gap. */\n private closeAtObservedTime(wall: number, mono: number, monoDelta: number, drift: number): void {\n // Where the observation ended on the timeline the last checkpoint was written on.\n const observedUntil = this.anchorWall + Math.max(monoDelta, 0)\n const closed: UsageSession[] = []\n for (const session of this.sessions.values()) {\n const entry = this.entryFor(session, mono, observedUntil, true)\n if (entry) closed.push(entry)\n }\n this.sessions.clear()\n this.emitCheckpoints(closed, observedUntil)\n // Sleep shows as the wall clock running ahead while the app was away; anything else is the clock being changed.\n const reason: GapReason = drift > 0 && this.leftForeground ? \"reporter_stopped\" : \"clock_untrusted\"\n this.emitGap(reason, Math.min(observedUntil, wall), Math.max(observedUntil, wall), wall)\n this.startAgain(wall, mono)\n }\n\n private emitGap(reason: GapReason, from: number, to: number, observedAt: number): void {\n this.emit(observedAt, (base) => ({\n ...base,\n kind: \"coverage_gap\",\n payload: {reason, from: iso(from), to: iso(to)},\n }))\n }\n\n /** After a break: the clocks are re-anchored, and the activities still going on start again as new sessions. */\n private startAgain(wall: number, mono: number): void {\n this.anchorWall = wall\n this.anchorMono = mono\n this.leftForeground = !isForeground()\n // The break closed the visit: one the app had left is over, and one still going on starts again from now.\n if (this.visitLeftAt) {\n this.visitStart = this.visitLeftAt = null\n this.foreground = false\n } else if (this.visitStart) {\n this.visitStart = {wall, mono}\n }\n this.armForegroundTimer({wall, mono}, isForeground())\n this.openMissing()\n this.arm(this.cadence())\n this.scheduleSnapshot()\n }\n\n // --- snapshots -----------------------------------------------------------------------------------------------\n\n private batteryPayload(wall: number): BatteryPayload {\n if (this.batteryUnsupported()) return {state: \"unsupported\", observedAt: iso(wall)}\n const reading = this.battery\n if (!reading || !Number.isFinite(reading.level) || reading.level < 0) {\n return {state: \"unknown\", observedAt: iso(reading?.observedAt ?? wall)}\n }\n return {\n state: \"measured\",\n observedAt: iso(reading.observedAt),\n level: Math.min(100, Math.round(reading.level)),\n charging: reading.charging,\n }\n }\n\n private phoneBatteryPayload(wall: number): PhoneBatteryPayload {\n const held = this.phoneBattery ?? {state: \"unknown\", observedAt: wall}\n if (held.state !== \"measured\") return {state: held.state, observedAt: iso(held.observedAt)}\n return {state: \"measured\", observedAt: iso(held.observedAt), level: held.level, charging: held.charging}\n }\n\n private versionKey(): string {\n const firmware = this.known?.firmware\n return firmware ? [firmware.apk, firmware.mtk, firmware.bes, firmware.os].join(\"|\") : \"\"\n }\n\n private currentMarks(): SnapshotMarks {\n const reading = this.battery\n const measured = !!reading && Number.isFinite(reading.level) && reading.level >= 0\n const binding = this.identified()\n const phone = this.phoneBattery\n return {\n phoneBattery: phone ?? {state: \"unknown\"},\n identity: binding ? JSON.stringify(binding) : \"\",\n linked: this.connection.state === \"connected\",\n batteryMeasured: measured,\n level: measured ? reading.level : -1,\n charging: measured ? reading.charging : false,\n versions: this.versionKey(),\n }\n }\n\n /** Asks for a snapshot once the changes around this moment have settled. */\n private scheduleSnapshot(): void {\n if (this.snapshotDebounce !== null) return\n const timer: number = BgTimer.setTimeout(\n () =>\n this.guard(\"snapshot\", () => {\n if (this.snapshotDebounce === timer) this.snapshotDebounce = null\n this.takeSnapshot()\n }),\n SNAPSHOT_DEBOUNCE_MS,\n )\n this.snapshotDebounce = timer\n }\n\n /**\n * The 15-minute snapshot. It has no timer of its own: it is written with the checkpoint that falls due 15 minutes or\n * more after the last snapshot, so the two share a wake-up and an upload. On the 15-minute cadence it is written\n * only if it would say something the last snapshot did not.\n */\n private periodicSnapshot(): void {\n if (this.env.monotonic() - this.lastSnapshotMono < SNAPSHOT_INTERVAL_MS) return\n this.takeSnapshot(!this.isFast())\n }\n\n /**\n * Glasses connecting or disconnecting is worth a snapshot; while they are connected, so are their identification (or\n * a serial replacing a provisional binding), a battery move of 5 points or a charging change, and a new version.\n *\n * Moves among the states short of connected are not: a phone retrying glasses that are away goes scanning,\n * connecting and disconnected every few seconds, all day, and forgets and finds the glasses' identity with each\n * attempt. Their battery and versions are only read while they are connected.\n *\n * A disconnect is written at once, while what is known is still the pair that left: the retry that follows within\n * moments starts a new connection, which forgets them. Only a snapshot in the last two seconds holds it back to the\n * usual debounce, so a link that flaps is still one snapshot every two seconds at most.\n *\n * The phone's battery is worth one on the same terms, with or without glasses: once it is first known or stops being\n * known, a move of 5 points, or a charging change.\n */\n private evaluateSnapshotTriggers(): void {\n const last = this.marks\n if (!last) return\n const now = this.currentMarks()\n const phoneNow = now.phoneBattery\n const phoneLast = last.phoneBattery\n if (\n phoneNow.state !== phoneLast.state ||\n (phoneNow.state === \"measured\" &&\n (Math.abs(phoneNow.level - (phoneLast.level ?? 0)) >= BATTERY_SNAPSHOT_STEP ||\n phoneNow.charging !== phoneLast.charging))\n ) {\n this.scheduleSnapshot()\n }\n if (now.linked !== last.linked) {\n const disconnected = !now.linked\n if (disconnected && this.env.monotonic() - this.lastSnapshotMono >= SNAPSHOT_DEBOUNCE_MS) this.takeSnapshot()\n else this.scheduleSnapshot()\n return\n }\n if (!now.linked) return\n const changed =\n now.identity !== last.identity ||\n (now.identity !== \"\" &&\n (now.batteryMeasured !== last.batteryMeasured ||\n (now.batteryMeasured &&\n (Math.abs(now.level - last.level) >= BATTERY_SNAPSHOT_STEP || now.charging !== last.charging)) ||\n (now.versions !== \"\" && now.versions !== last.versions)))\n if (changed) this.scheduleSnapshot()\n }\n\n /** Writes a snapshot; with `onlyIfNew`, only if it would say something the last one did not. */\n private takeSnapshot(onlyIfNew = false): void {\n const phone = phoneInfo()\n if (!phone) {\n if (this.snapshotDebounce !== null) BgTimer.clearTimeout(this.snapshotDebounce)\n this.snapshotDebounce = null\n console.warn(\"FleetCollector: no snapshot, this platform has no value in the Fleet contract\")\n return\n }\n const wall = this.env.now()\n this.trackGlasses(wall)\n this.trackPhoneBattery(wall)\n const binding = this.currentBinding()\n const known = this.known\n const glasses: GlassesPayload | null =\n binding && known\n ? {\n model: known.model,\n ...(Object.keys(known.firmware).length > 0 ? {firmware: known.firmware} : {}),\n connection: {state: this.connection.state, observedAt: iso(this.connection.observedAt)},\n battery: this.batteryPayload(wall),\n }\n : null\n // What the snapshot says, leaving out the time a battery with no reading is stamped with (it is now): an unknown\n // one, or one the glasses cannot report. Of glasses that are not connected only that is new: retrying them changes\n // the state short of connected, its time, and what is known of them, with every attempt. The phone's battery is\n // left out: a move worth a snapshot schedules one, and a smaller one is not new enough to write.\n const key = JSON.stringify([\n phone,\n this.connection.state !== \"connected\"\n ? \"not connected\"\n : [\n binding && glasses ? binding : null,\n glasses && !this.battery ? {...glasses, battery: {state: glasses.battery?.state}} : glasses,\n ],\n ])\n if (onlyIfNew && key === this.lastSnapshotKey) return\n if (this.snapshotDebounce !== null) BgTimer.clearTimeout(this.snapshotDebounce)\n this.snapshotDebounce = null\n this.emit(wall, (base) => ({\n ...base,\n kind: \"snapshot\",\n ...(glasses && binding ? {deviceBinding: binding} : {}),\n payload: {phone: {...phone, battery: this.phoneBatteryPayload(wall)}, ...(glasses ? {glasses} : {})},\n }))\n this.marks = this.currentMarks()\n this.lastSnapshotMono = this.env.monotonic()\n this.lastSnapshotKey = key\n }\n\n // --- inventory -----------------------------------------------------------------------------------------------\n\n /** Asks for an inventory record once the changes around this moment have settled. */\n private scheduleInventory(): void {\n if (this.inventoryDebounce !== null) return\n const timer: number = BgTimer.setTimeout(\n () =>\n this.guard(\"inventory\", () => {\n if (this.inventoryDebounce === timer) this.inventoryDebounce = null\n this.takeInventory(false)\n }),\n INVENTORY_DEBOUNCE_MS,\n )\n this.inventoryDebounce = timer\n }\n\n /** Writes the inventory; unless `always`, only if it lists something the last record of this run did not. */\n private takeInventory(always: boolean): void {\n const wall = this.env.now()\n const payload = inventoryPayload(this.env.inventory.list())\n if (!payload) return\n const key = JSON.stringify(payload)\n if (!always && key === this.lastInventoryKey) return\n if (this.inventoryDebounce !== null) BgTimer.clearTimeout(this.inventoryDebounce)\n this.inventoryDebounce = null\n this.emit(wall, (base) => ({...base, kind: \"miniapp_inventory\", payload}))\n this.lastInventoryKey = key\n }\n\n // --- launches and photos -------------------------------------------------------------------------------------\n\n private onLaunch(event: FleetLaunchEvent, observedAt = this.env.now()): void {\n const packageName = text(event.packageName)\n if (!packageName) return\n if (event.start !== \"user\" && event.start !== \"automatic\") return\n if (event.outcome !== \"started\" && event.outcome !== \"failed\") return\n const miniappName = text(event.miniappName)\n const versionName = text(event.versionName)\n this.emit(observedAt, (base) => ({\n ...base,\n kind: \"miniapp_launch\",\n payload: {\n packageName,\n ...(miniappName ? {miniappName} : {}),\n ...(versionName ? {versionName} : {}),\n start: event.start,\n outcome: event.outcome,\n ...(event.outcome === \"failed\" && event.failureReason ? {failureReason: event.failureReason} : {}),\n },\n }))\n }\n\n // --- Phase 12: a miniapp's own events, crashes, installs and connection changes -------------------------------\n\n /** The open execution session of `packageName`, which a telemetry event or crash is attributed to. */\n private executionOf(packageName: string): string | undefined {\n return this.sessions.get(`miniapp_execution:${packageName}`)?.id\n }\n\n private onTelemetry(event: FleetTelemetryEvent): void {\n const packageName = text(event.packageName)\n if (!packageName) return\n const at = this.env.now()\n const limited = limitEvent(event.event, event.properties)\n if (limited === null || !this.telemetryRate.admit(packageName, at)) {\n this.env.queue.noteTelemetryLoss(this.partition, packageName, \"overLimit\", 1, at)\n return\n }\n const versionName = text(event.versionName)\n const executionSessionId = this.executionOf(packageName)\n this.emit(\n at,\n (base) => ({\n ...base,\n kind: \"telemetry_event\",\n payload: {\n packageName,\n ...(versionName ? {versionName} : {}),\n ...(executionSessionId ? {executionSessionId} : {}),\n event: limited.event,\n properties: limited.properties,\n droppedProperties: limited.droppedProperties,\n cutValues: limited.cutValues,\n },\n }),\n TELEMETRY_RECORD_PREFIX,\n )\n }\n\n private onCrash(event: FleetCrashEvent): void {\n const packageName = text(event.packageName)\n if (!packageName) return\n const versionName = text(event.versionName)\n const executionSessionId = this.executionOf(packageName)\n this.emit(this.env.now(), (base) => ({\n ...base,\n kind: \"miniapp_crash\",\n payload: {\n packageName,\n ...(versionName ? {versionName} : {}),\n ...(executionSessionId ? {executionSessionId} : {}),\n surface: event.surface,\n category: event.category,\n outcome: event.outcome,\n crashesInWindow: Math.min(FLEET_LIMITS.maxCrashesInWindow, Math.max(1, Math.round(event.crashesInWindow))),\n },\n }))\n }\n\n private onInstall(event: FleetInstallEvent): void {\n const packageName = text(event.packageName)\n if (!packageName) return\n const fromVersion = text(event.fromVersion)\n const toVersion = text(event.toVersion)\n this.emit(this.env.now(), (base) => ({\n ...base,\n kind: \"miniapp_install\",\n payload: {\n packageName,\n operation: event.operation,\n source: event.source,\n ...(fromVersion ? {fromVersion} : {}),\n ...(toVersion ? {toVersion} : {}),\n outcome: event.outcome,\n ...(event.outcome === \"succeeded\" ? {} : {reason: event.reason ?? \"unknown\"}),\n },\n }))\n }\n\n private onConnection(event: FleetConnectionEvent): void {\n const binding = this.currentBinding() ?? this.known?.binding ?? null\n const glassesModel = this.known?.model\n const appVersion = phoneInfo()?.appVersion ?? \"unknown\"\n this.emit(this.env.now(), (base) => ({\n ...base,\n kind: \"connection_event\",\n ...(binding ? {deviceBinding: binding} : {}),\n payload: {\n event: event.event,\n category: event.category,\n ...(glassesModel ? {glassesModel} : {}),\n appVersion,\n ...(event.event === \"reconnected\" ? {reconnectMs: Math.max(0, Math.round(event.reconnectMs ?? 0))} : {}),\n },\n }))\n }\n\n private onPhoto(event: FleetPhotoEvent): void {\n const operationId = event.operationId\n if (typeof operationId !== \"string\" || operationId.length > MAX_TEXT || !FLEET_ID.test(operationId)) return\n const stage = event.stage\n if (stage !== \"requested\" && stage !== \"captured\" && stage !== \"delivered\" && stage !== \"failed\") return\n const payload = stage === \"failed\" ? {stage, failedStage: event.failedStage ?? (\"requested\" as const)} : {stage}\n const photo: HeldPhoto = {observedAt: this.env.now(), operationId, payload}\n // A photo is always one pair of glasses' photo: of connected glasses still being identified, it waits for them.\n const binding = this.currentBinding()\n if (binding) this.emitPhoto(photo, binding)\n else if (this.known?.connectedSinceMono != null && this.heldPhotos.length < MAX_HELD_PHOTOS)\n this.heldPhotos.push(photo)\n }\n\n /** Writes the photo stages that waited for the glasses, once they are identified (or with `final`, as they are). */\n private releasePhotos(final = false): void {\n if (this.heldPhotos.length === 0) return\n const binding = this.identified(final)\n if (binding) for (const photo of this.heldPhotos.splice(0)) this.emitPhoto(photo, binding)\n else if (final) this.heldPhotos = []\n }\n\n private emitPhoto(photo: HeldPhoto, binding: FleetDeviceBinding): void {\n this.emit(photo.observedAt, (base) => ({\n ...base,\n kind: \"photo_operation\",\n operationId: photo.operationId,\n deviceBinding: binding,\n payload: photo.payload,\n }))\n }\n\n // --- records -------------------------------------------------------------------------------------------------\n\n private capabilities(): Capability[] {\n const measured: readonly Capability[] = !realGlassesConnected()\n ? PHONE_CAPABILITIES\n : // Glasses that cannot report a battery leave nothing to measure about it.\n this.batteryUnsupported()\n ? FLEET_CAPABILITIES.filter((capability) => capability !== \"glasses_battery\")\n : FLEET_CAPABILITIES\n if (this.phoneBattery?.state === \"unsupported\") return measured.filter((capability) => capability !== \"phone_battery\")\n return [...measured]\n }\n\n private base(observedAt: number, idPrefix = \"\"): RecordBase {\n return {\n schemaVersion: FLEET_SCHEMA_VERSION,\n recordId: `${idPrefix}${newId()}`,\n phoneDeviceId: this.phoneId,\n collectorSessionId: this.collectorSessionId,\n sequence: this.env.queue.nextSequence(this.partition, this.collectorSessionId),\n observedAt: iso(observedAt),\n capabilities: this.capabilities(),\n }\n }\n\n /** Builds a record and queues it in this run's partition. A record that cannot be built or stored is skipped. */\n private emit(observedAt: number, make: (base: RecordBase) => FleetRecord, idPrefix = \"\"): void {\n try {\n this.env.queue.enqueue(this.partition, make(this.base(observedAt, idPrefix)))\n } catch (error) {\n warn(\"recording\", error)\n }\n }\n}\n\n/**\n * The collector over `deps.queue`, which must be the app's shared queue (`createFleetQueue()`); the clocks and the\n * models without battery reporting are injectable for tests. It collects nothing until `start`.\n */\nexport function createFleetCollector(deps: {\n queue: FleetQueue\n now?: () => number\n monotonic?: () => number\n modelsWithoutBattery?: ReadonlySet<string>\n /** What is installed. Defaults to the app's source (`setFleetInventorySource`), which reports nothing until wired. */\n inventory?: InventorySource\n /** The phone's battery. Defaults to the app's (`appPhoneBattery`, over expo-battery). */\n phoneBattery?: PhoneBatterySource\n}): FleetCollector {\n const env: Env = {\n queue: deps.queue,\n now: deps.now ?? Date.now,\n monotonic: deps.monotonic ?? (() => performance.now()),\n modelsWithoutBattery: deps.modelsWithoutBattery ?? MODELS_WITHOUT_BATTERY,\n inventory: deps.inventory ?? appInventory,\n phoneBattery: deps.phoneBattery ?? appPhoneBattery,\n }\n let current: CollectorRun | null = null\n\n return {\n start(ctx) {\n try {\n const previous = current\n current = null\n previous?.end()\n const run = new CollectorRun(env, ctx.partition, ctx.collectorSessionId)\n current = run\n try {\n run.begin()\n } catch (error) {\n run.abort()\n if (current === run) current = null\n throw error\n }\n } catch (error) {\n warn(\"start\", error)\n }\n },\n\n // The reason is the caller's record of why; the collector closes its sessions the same way for each.\n stop(_reason) {\n const run = current\n current = null\n if (!run) return\n try {\n run.end()\n } catch (error) {\n warn(\"stop\", error)\n }\n },\n\n flushCheckpoint() {\n try {\n current?.flush()\n } catch (error) {\n warn(\"flush\", error)\n }\n },\n }\n}\n"]}