@mentra/crust 0.1.0-dev.0
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.
- package/README.md +35 -0
- package/android/build.gradle +146 -0
- package/android/src/internal/AndroidManifest.xml +9 -0
- package/android/src/internal/java/com/mentra/crust/receivers/CaptionsTesterIncidentReceiver.kt +46 -0
- package/android/src/main/AndroidManifest.xml +19 -0
- package/android/src/main/java/com/mentra/crust/CrustModule.kt +882 -0
- package/android/src/main/java/com/mentra/crust/CrustView.kt +30 -0
- package/android/src/main/java/com/mentra/crust/heading/HeadingManager.kt +150 -0
- package/android/src/main/java/com/mentra/crust/jsc/JSCDispatcher.kt +189 -0
- package/android/src/main/java/com/mentra/crust/jsc/JSCPolyfillBridge.kt +246 -0
- package/android/src/main/java/com/mentra/crust/jsc/JSCRuntime.kt +593 -0
- package/android/src/main/java/com/mentra/crust/navigation/NavigationManager.kt +1445 -0
- package/android/src/main/java/com/mentra/crust/services/NotificationListener.kt +319 -0
- package/android/src/main/java/com/mentra/crust/utils/ImageProcessor.java +452 -0
- package/android/src/main/java/com/mentra/crust/utils/VideoStabilizer.kt +556 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/app.plugin.js +3 -0
- package/build/Crust.types.d.ts +148 -0
- package/build/Crust.types.d.ts.map +1 -0
- package/build/Crust.types.js +2 -0
- package/build/Crust.types.js.map +1 -0
- package/build/CrustModule.d.ts +175 -0
- package/build/CrustModule.d.ts.map +1 -0
- package/build/CrustModule.js +4 -0
- package/build/CrustModule.js.map +1 -0
- package/build/CrustModule.web.d.ts +26 -0
- package/build/CrustModule.web.d.ts.map +1 -0
- package/build/CrustModule.web.js +54 -0
- package/build/CrustModule.web.js.map +1 -0
- package/build/CrustView.d.ts +4 -0
- package/build/CrustView.d.ts.map +1 -0
- package/build/CrustView.js +7 -0
- package/build/CrustView.js.map +1 -0
- package/build/CrustView.web.d.ts +4 -0
- package/build/CrustView.web.d.ts.map +1 -0
- package/build/CrustView.web.js +7 -0
- package/build/CrustView.web.js.map +1 -0
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +6 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/Crust.podspec +65 -0
- package/ios/CrustModule.swift +544 -0
- package/ios/CrustView.swift +38 -0
- package/ios/Resources/startup.js +814 -0
- package/ios/Source/JSCDispatcher.swift +226 -0
- package/ios/Source/JSCPolyfillBridge.swift +378 -0
- package/ios/Source/JSCRuntime.swift +673 -0
- package/ios/Source/utils/ImageProcessor.swift +392 -0
- package/ios/Source/utils/SystemGestures.swift +53 -0
- package/ios/Source/utils/VideoStabilizer.swift +374 -0
- package/ios/heading/HeadingManager.swift +74 -0
- package/ios/navigation/NavPayloads.swift +62 -0
- package/ios/navigation/NavigationManager.swift +720 -0
- package/package.json +69 -0
- package/plugin/build/index.d.ts +19 -0
- package/plugin/build/index.js +23 -0
- package/plugin/build/withAndroid.d.ts +2 -0
- package/plugin/build/withAndroid.js +78 -0
- package/src/Crust.types.ts +157 -0
- package/src/CrustModule.ts +186 -0
- package/src/CrustModule.web.ts +57 -0
- package/src/CrustView.tsx +10 -0
- package/src/CrustView.web.tsx +11 -0
- package/src/index.ts +5 -0
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# crust
|
|
2
|
+
|
|
3
|
+
Mentra Native Module
|
|
4
|
+
|
|
5
|
+
# API documentation
|
|
6
|
+
|
|
7
|
+
- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/crust/)
|
|
8
|
+
- [Documentation for the main branch](https://docs.expo.dev/versions/unversioned/sdk/crust/)
|
|
9
|
+
|
|
10
|
+
# Installation in managed Expo projects
|
|
11
|
+
|
|
12
|
+
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
|
|
13
|
+
|
|
14
|
+
# Installation in bare React Native projects
|
|
15
|
+
|
|
16
|
+
For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
|
|
17
|
+
|
|
18
|
+
### Add the package to your npm dependencies
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
npm install crust
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Configure for Android
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Configure for iOS
|
|
30
|
+
|
|
31
|
+
Run `npx pod-install` after installing the npm package.
|
|
32
|
+
|
|
33
|
+
# Contributing
|
|
34
|
+
|
|
35
|
+
Contributions are very welcome! Please refer to guidelines described in the [contributing guide]( https://github.com/expo/expo#contributing).
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
|
|
3
|
+
group = 'com.mentra.crust'
|
|
4
|
+
version = '0.1.0'
|
|
5
|
+
|
|
6
|
+
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
|
+
apply from: expoModulesCorePlugin
|
|
8
|
+
applyKotlinExpoModulesCorePlugin()
|
|
9
|
+
useCoreDependencies()
|
|
10
|
+
useExpoPublishing()
|
|
11
|
+
|
|
12
|
+
// MentraJS Android runtime: QuickJS via dokar3/quickjs-kt.
|
|
13
|
+
//
|
|
14
|
+
// Zipline's `bind(name, service)` registers services in an internal Kotlin
|
|
15
|
+
// map keyed by name for the Kotlin/JS-compiled `Zipline.take()` API; it does
|
|
16
|
+
// not install JS globals on globalThis. Our polyfill is hand-written JS that
|
|
17
|
+
// reads `globalThis.__mentraNativeBridge`, so the Zipline path silently
|
|
18
|
+
// dropped every JS→host dispatch on Android.
|
|
19
|
+
//
|
|
20
|
+
// dokar3/quickjs-kt exposes `QuickJs.function(name) { args -> ... }` which
|
|
21
|
+
// installs the lambda directly as a property of globalThis via QuickJS's
|
|
22
|
+
// `JS_SetPropertyStr(JS_NewCFunction(...))`. This matches iOS Apple JSC's
|
|
23
|
+
// `ctx.setObject(closure, forKeyedSubscript: ...)` pattern point-for-point.
|
|
24
|
+
|
|
25
|
+
// If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
|
|
26
|
+
// The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
|
|
27
|
+
// Most of the time, you may like to manage the Android SDK versions yourself.
|
|
28
|
+
def useManagedAndroidSdkVersions = false
|
|
29
|
+
if (useManagedAndroidSdkVersions) {
|
|
30
|
+
useDefaultAndroidSdkVersions()
|
|
31
|
+
} else {
|
|
32
|
+
buildscript {
|
|
33
|
+
// Simple helper that allows the root project to override versions declared by this library.
|
|
34
|
+
ext.safeExtGet = { prop, fallback ->
|
|
35
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
project.android {
|
|
39
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 36)
|
|
40
|
+
defaultConfig {
|
|
41
|
+
minSdkVersion safeExtGet("minSdkVersion", 24)
|
|
42
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 36)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
android {
|
|
48
|
+
namespace "com.mentra.crust"
|
|
49
|
+
defaultConfig {
|
|
50
|
+
versionCode 1
|
|
51
|
+
versionName "0.1.0"
|
|
52
|
+
multiDexEnabled true
|
|
53
|
+
}
|
|
54
|
+
// Pull the MentraJS polyfill bundle from the sibling @mentra/jspolyfill
|
|
55
|
+
// module's `assets/` directory — single committed source of truth. The
|
|
56
|
+
// file is read at runtime via `appContext.assets.open("startup.js")`.
|
|
57
|
+
// Cross-module sourceSet entry beats checking the same artifact into git
|
|
58
|
+
// multiple times.
|
|
59
|
+
sourceSets {
|
|
60
|
+
main {
|
|
61
|
+
assets.srcDirs += '../../jspolyfill/assets'
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
compileOptions {
|
|
65
|
+
coreLibraryDesugaringEnabled true
|
|
66
|
+
}
|
|
67
|
+
buildTypes {
|
|
68
|
+
internal {
|
|
69
|
+
initWith release
|
|
70
|
+
matchingFallbacks = ['release']
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
buildTypes {
|
|
74
|
+
internal {
|
|
75
|
+
initWith release
|
|
76
|
+
matchingFallbacks = ['release']
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
lintOptions {
|
|
80
|
+
abortOnError false
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
dependencies {
|
|
85
|
+
// Mapbox Navigation SDK v3 (replaces Google Navigation SDK).
|
|
86
|
+
// Drives headless turn-by-turn nav in NavigationManager.kt: route
|
|
87
|
+
// progress, off-route + automatic rerouting, enhanced (map-matched)
|
|
88
|
+
// location, and the MapboxReplayer simulation harness for dev trips.
|
|
89
|
+
// Resolved from the authenticated Mapbox Downloads Maven repo, which is
|
|
90
|
+
// injected into the root project's allprojects.repositories at prebuild by
|
|
91
|
+
// mobile/plugins/android.ts (withProjectBuildGradleModifications), using the
|
|
92
|
+
// MAPBOX_DOWNLOADS_TOKEN (Downloads:Read sk.… token) from the env/gradle.properties.
|
|
93
|
+
//
|
|
94
|
+
// We depend on the headless modules directly, NOT the umbrella
|
|
95
|
+
// `navigationcore:android` artifact — that one also drags in `ui-maps`,
|
|
96
|
+
// `voice`, and `copilot`, which a custom glasses HUD doesn't use (dead
|
|
97
|
+
// APK weight). `:navigation` is the core engine; `:tripdata` carries the
|
|
98
|
+
// banner/maneuver formatting used to label turns.
|
|
99
|
+
// Version pinned to 3.25.0 — re-check https://docs.mapbox.com/android/navigation/releases/
|
|
100
|
+
def isChinaBuild = System.getenv("EXPO_PUBLIC_DEPLOYMENT_REGION") == "china"
|
|
101
|
+
if (isChinaBuild) {
|
|
102
|
+
compileOnly 'com.mapbox.navigationcore:navigation:3.25.0'
|
|
103
|
+
compileOnly 'com.mapbox.navigationcore:tripdata:3.25.0'
|
|
104
|
+
} else {
|
|
105
|
+
implementation 'com.mapbox.navigationcore:navigation:3.25.0'
|
|
106
|
+
implementation 'com.mapbox.navigationcore:tripdata:3.25.0'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Required for Java 8+ APIs on minSdk < 26 (was needed by Google Nav SDK;
|
|
110
|
+
// Mapbox Nav SDK likewise targets desugared core libs).
|
|
111
|
+
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.4'
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
dependencies {
|
|
115
|
+
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
|
116
|
+
implementation 'com.google.android.gms:play-services-base:18.2.0'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
dependencies {
|
|
120
|
+
// MentraJS — QuickJS for per-miniapp JS contexts. dokar3/quickjs-kt is a
|
|
121
|
+
// KMP wrapper around Bellard QuickJS that exposes `function(name) { ... }`
|
|
122
|
+
// for installing Kotlin lambdas as JS globals via `JS_SetPropertyStr`.
|
|
123
|
+
// Mirrors iOS Apple JSC's `setObject(_, forKeyedSubscript:)` pattern.
|
|
124
|
+
//
|
|
125
|
+
// Version pin: this Expo SDK 55 build uses Kotlin 2.1.20, which can read
|
|
126
|
+
// metadata up to 2.2.0. dokar3 1.0.1+ ships classes with metadata 2.3.0
|
|
127
|
+
// (compiled with Kotlin 2.3.x) and is unreadable here. 1.0.0-alpha13 is
|
|
128
|
+
// the last release compiled with Kotlin 2.0 (metadata 2.0.0) — its API
|
|
129
|
+
// (`QuickJs.create`, `evaluate`, `function` extension) matches 1.0.5 1:1.
|
|
130
|
+
// Bump only when the host Kotlin compiler clears 2.3.0 metadata.
|
|
131
|
+
implementation 'io.github.dokar3:quickjs-kt-android:1.0.0-alpha13'
|
|
132
|
+
|
|
133
|
+
// OkHttp for fetch / WebSocket — already used elsewhere in MentraOS;
|
|
134
|
+
// pinned here so the gradle plugin doesn't downgrade us.
|
|
135
|
+
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
|
136
|
+
|
|
137
|
+
// Tink for X25519 (Android stdlib X25519 is API 33+ only; minSdk is 24).
|
|
138
|
+
// ~1.2 MB AAR. Crypto.subtle's SHA / AES-GCM / HMAC stay on javax.crypto
|
|
139
|
+
// which ships on the platform.
|
|
140
|
+
implementation 'com.google.crypto.tink:tink-android:1.14.1'
|
|
141
|
+
|
|
142
|
+
// Kotlin coroutines: dokar3's `evaluate()` is suspend; we bridge it via
|
|
143
|
+
// `runBlocking(dispatcher)` from the per-miniapp single-thread executor.
|
|
144
|
+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1'
|
|
145
|
+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1'
|
|
146
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<application>
|
|
3
|
+
<receiver android:name="com.mentra.crust.receivers.CaptionsTesterIncidentReceiver" android:exported="true">
|
|
4
|
+
<intent-filter>
|
|
5
|
+
<action android:name="com.mentra.CAPTIONS_TESTER_INCIDENT"/>
|
|
6
|
+
</intent-filter>
|
|
7
|
+
</receiver>
|
|
8
|
+
</application>
|
|
9
|
+
</manifest>
|
package/android/src/internal/java/com/mentra/crust/receivers/CaptionsTesterIncidentReceiver.kt
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
package com.mentra.crust.receivers
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import com.mentra.crust.CrustModule
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Receives broadcasts from the external captions tester and forwards them into React Native so
|
|
11
|
+
* the app can file a normal incident through the existing mobile incident pipeline.
|
|
12
|
+
*/
|
|
13
|
+
class CaptionsTesterIncidentReceiver : BroadcastReceiver() {
|
|
14
|
+
@Suppress("DEPRECATION")
|
|
15
|
+
override fun onReceive(context: Context?, intent: Intent?) {
|
|
16
|
+
if (intent == null) {
|
|
17
|
+
Log.w("CaptionsTesterIncident", "Received null intent")
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
val body =
|
|
22
|
+
hashMapOf<String, Any>(
|
|
23
|
+
"action" to (intent.action ?: "unknown"),
|
|
24
|
+
"timestamp" to System.currentTimeMillis(),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
intent.getStringExtra("failure_code")?.let { body["failure_code"] = it }
|
|
28
|
+
intent.getStringExtra("failure_message")?.let { body["failure_message"] = it }
|
|
29
|
+
intent.getStringExtra("test_run_id")?.let { body["test_run_id"] = it }
|
|
30
|
+
intent.getStringExtra("scenario_name")?.let { body["scenario_name"] = it }
|
|
31
|
+
intent.getStringExtra("source")?.let { body["source"] = it }
|
|
32
|
+
|
|
33
|
+
intent.extras?.keySet()?.forEach { key ->
|
|
34
|
+
if (body.containsKey(key)) {
|
|
35
|
+
return@forEach
|
|
36
|
+
}
|
|
37
|
+
val value = intent.extras?.get(key) ?: return@forEach
|
|
38
|
+
when (value) {
|
|
39
|
+
is String, is Int, is Long, is Boolean, is Double, is Float -> body[key] = value
|
|
40
|
+
else -> body[key] = value.toString()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
CrustModule.emitCaptionsTesterIncident(body)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<application>
|
|
3
|
+
<service
|
|
4
|
+
android:name="com.mentra.crust.services.NotificationListenerServiceImpl"
|
|
5
|
+
android:label="@string/mentra_crust_notification_listener_label"
|
|
6
|
+
android:exported="false"
|
|
7
|
+
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
|
8
|
+
<intent-filter>
|
|
9
|
+
<action android:name="android.service.notification.NotificationListenerService" />
|
|
10
|
+
</intent-filter>
|
|
11
|
+
<meta-data android:name="android.service.notification.default_filter_types" android:value="conversations|alerting" />
|
|
12
|
+
<meta-data android:name="android.service.notification.disabled_filter_types" android:value="ongoing|silent" />
|
|
13
|
+
</service>
|
|
14
|
+
|
|
15
|
+
<!-- The Mapbox Navigation SDK delivers turn-by-turn steps inline via
|
|
16
|
+
RouteProgress (no Messenger-IPC service), so the Google-era
|
|
17
|
+
NavInfoReceiverService is gone. Nothing to register here for nav. -->
|
|
18
|
+
</application>
|
|
19
|
+
</manifest>
|