@mentra/crust 0.1.0-dev.0 → 3.1.0-dev.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mentra/crust",
3
- "version": "0.1.0-dev.0",
3
+ "version": "3.1.0-dev.1",
4
4
  "description": "Mentra Native Module",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -23,7 +23,11 @@
23
23
  "crust",
24
24
  "Crust"
25
25
  ],
26
- "repository": "https://github.com/fossephate/crust",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/Mentra-Community/MentraOS.git",
29
+ "directory": "mobile/modules/crust"
30
+ },
27
31
  "bugs": {
28
32
  "url": "https://github.com/fossephate/crust/issues"
29
33
  },
@@ -31,7 +35,7 @@
31
35
  "license": "MIT",
32
36
  "homepage": "https://github.com/fossephate/crust#readme",
33
37
  "dependencies": {
34
- "@mentra/jspolyfill": "^0.1.0-dev.0"
38
+ "@mentra/jspolyfill": "3.1.0-dev.1"
35
39
  },
36
40
  "devDependencies": {
37
41
  "@expo/config-plugins": ">=8.0.0",
@@ -14,6 +14,8 @@ import { type ConfigPlugin } from "expo/config-plugins";
14
14
  * both fails the release build with duplicate classes)
15
15
  * - core-library desugaring (crust's AAR metadata requires it of embedding
16
16
  * apps — the Nav SDK uses newer core libs)
17
+ * - a generated MainApplication process guard so the notification-listener
18
+ * process never initializes React Native
17
19
  */
18
20
  declare const withCrust: ConfigPlugin;
19
21
  export default withCrust;
@@ -16,6 +16,8 @@ const withAndroid_1 = require("./withAndroid");
16
16
  * both fails the release build with duplicate classes)
17
17
  * - core-library desugaring (crust's AAR metadata requires it of embedding
18
18
  * apps — the Nav SDK uses newer core libs)
19
+ * - a generated MainApplication process guard so the notification-listener
20
+ * process never initializes React Native
19
21
  */
20
22
  const withCrust = (config) => {
21
23
  return (0, withAndroid_1.withCrustAndroidBuildContract)(config);
@@ -18,6 +18,8 @@ const MAPBOX_REPO = [
18
18
  " }",
19
19
  ].join("\n");
20
20
  const PROTOBUF_EXCLUDE = "exclude group: 'com.google.protobuf', module: 'protobuf-javalite'";
21
+ const NOTIFICATION_PROCESS_GUARD = "crust: skip React Native in notification process";
22
+ const NOTIFICATION_CONFIG_GUARD = "crust: skip Expo lifecycle in notification process";
21
23
  function withCrustProjectGradle(config) {
22
24
  return (0, config_plugins_1.withProjectBuildGradle)(config, (cfg) => {
23
25
  let gradle = cfg.modResults.contents;
@@ -71,8 +73,61 @@ function withCrustAppGradle(config) {
71
73
  return cfg;
72
74
  });
73
75
  }
76
+ function withNotificationProcessGuard(config) {
77
+ return (0, config_plugins_1.withMainApplication)(config, (cfg) => {
78
+ let source = cfg.modResults.contents;
79
+ const isJava = cfg.modResults.language === "java";
80
+ if (!source.includes(NOTIFICATION_PROCESS_GUARD)) {
81
+ const pattern = isJava
82
+ ? /public void onCreate\(\)\s*\{\s*super\.onCreate\(\);/
83
+ : /override fun onCreate\(\)\s*\{\s*super\.onCreate\(\)/;
84
+ const replacement = isJava
85
+ ? `public void onCreate() {
86
+ super.onCreate();
87
+ // ${NOTIFICATION_PROCESS_GUARD}
88
+ if (com.mentra.crust.services.NotificationProcess.isCurrent(this)) {
89
+ return;
90
+ }`
91
+ : `override fun onCreate() {
92
+ super.onCreate()
93
+ // ${NOTIFICATION_PROCESS_GUARD}
94
+ if (com.mentra.crust.services.NotificationProcess.isCurrent(this)) {
95
+ return
96
+ }`;
97
+ if (!pattern.test(source)) {
98
+ throw new Error("@mentra/crust could not add the notification-process guard to MainApplication");
99
+ }
100
+ source = source.replace(pattern, replacement);
101
+ }
102
+ if (!source.includes(NOTIFICATION_CONFIG_GUARD)) {
103
+ const pattern = isJava
104
+ ? /public void onConfigurationChanged\(Configuration newConfig\)\s*\{\s*super\.onConfigurationChanged\(newConfig\);/
105
+ : /override fun onConfigurationChanged\(newConfig: Configuration\)\s*\{\s*super\.onConfigurationChanged\(newConfig\)/;
106
+ const replacement = isJava
107
+ ? `public void onConfigurationChanged(Configuration newConfig) {
108
+ super.onConfigurationChanged(newConfig);
109
+ // ${NOTIFICATION_CONFIG_GUARD}
110
+ if (com.mentra.crust.services.NotificationProcess.isCurrent(this)) {
111
+ return;
112
+ }`
113
+ : `override fun onConfigurationChanged(newConfig: Configuration) {
114
+ super.onConfigurationChanged(newConfig)
115
+ // ${NOTIFICATION_CONFIG_GUARD}
116
+ if (com.mentra.crust.services.NotificationProcess.isCurrent(this)) {
117
+ return
118
+ }`;
119
+ // Some custom hosts do not override onConfigurationChanged. In that case
120
+ // there is no Expo lifecycle callback to guard.
121
+ if (pattern.test(source))
122
+ source = source.replace(pattern, replacement);
123
+ }
124
+ cfg.modResults.contents = source;
125
+ return cfg;
126
+ });
127
+ }
74
128
  const withCrustAndroidBuildContract = (config) => {
75
129
  config = withCrustProjectGradle(config);
76
- return withCrustAppGradle(config);
130
+ config = withCrustAppGradle(config);
131
+ return withNotificationProcessGuard(config);
77
132
  };
78
133
  exports.withCrustAndroidBuildContract = withCrustAndroidBuildContract;
@@ -128,7 +128,12 @@ export type PhoneNotificationEvent = {
128
128
  app: string
129
129
  title: string
130
130
  content: string
131
- priority: string
131
+ /**
132
+ * Android notification priority: PRIORITY_MIN (-2) through PRIORITY_MAX (2).
133
+ * Derived from the channel importance when the ranking is available, since
134
+ * Notification.priority reads 0 for channel-based notifications.
135
+ */
136
+ priority: number
132
137
  timestamp: number
133
138
  packageName: string
134
139
  }
@@ -6,6 +6,12 @@ declare class CrustModule extends NativeModule<CrustModuleEvents> {
6
6
  PI: number
7
7
  hello(): string
8
8
  setValueAsync(value: string): Promise<void>
9
+ nativeHttpRequest(
10
+ method: string,
11
+ url: string,
12
+ headers: Record<string, string>,
13
+ body?: string | null,
14
+ ): Promise<{status: number; statusText: string; headers: Record<string, string>; body: string}>
9
15
  showAVRoutePicker(tintColor?: string | null): void
10
16
 
11
17
  /**
@@ -17,15 +23,14 @@ declare class CrustModule extends NativeModule<CrustModuleEvents> {
17
23
  * Pass `[]` to restore default behavior. Android: no-op (Android has no
18
24
  * per-app equivalent; system gestures are configured at the OS level).
19
25
  */
20
- setDeferredSystemGestures(
21
- edges: Array<"top" | "bottom" | "left" | "right" | "all">,
22
- ): Promise<void>
26
+ setDeferredSystemGestures(edges: Array<"top" | "bottom" | "left" | "right" | "all">): Promise<void>
23
27
 
24
28
  // MentraOS Notification Commands
25
- setNotificationConfig(enabled: boolean, blocklist: string[]): Promise<void>
29
+ setNotificationConfig(listenerEnabled: boolean, blocklist: string[]): Promise<void>
26
30
  getInstalledApps(): Promise<InstalledApp[]>
27
31
  getInstalledAppsForNotifications(): Promise<InstalledApp[]>
28
32
  hasNotificationListenerPermission(): Promise<boolean>
33
+ refreshNotificationListener(): Promise<boolean>
29
34
  openNotificationListenerSettings(): Promise<boolean>
30
35
  isBetaBuild(): Promise<boolean>
31
36
  // location services commands
@@ -82,6 +87,7 @@ declare class CrustModule extends NativeModule<CrustModuleEvents> {
82
87
  success: boolean
83
88
  uri?: string
84
89
  identifier?: string
90
+ existing?: boolean
85
91
  error?: string
86
92
  }>
87
93
 
@@ -7,12 +7,21 @@ class CrustModule extends NativeModule<CrustModuleEvents> {
7
7
  async setValueAsync(value: string): Promise<void> {
8
8
  this.emit("onChange", {value})
9
9
  }
10
+ async nativeHttpRequest(method: string, url: string, headers: Record<string, string>, body?: string | null) {
11
+ const response = await fetch(url, {method, headers, body})
12
+ return {
13
+ status: response.status,
14
+ statusText: response.statusText,
15
+ headers: Object.fromEntries(response.headers.entries()),
16
+ body: await response.text(),
17
+ }
18
+ }
10
19
  hello() {
11
20
  return "Hello world! 👋"
12
21
  }
13
22
  showAVRoutePicker(_tintColor?: string | null) {}
14
23
  async setDeferredSystemGestures(_edges: string[]): Promise<void> {}
15
- async setNotificationConfig(_enabled: boolean, _blocklist: string[]): Promise<void> {}
24
+ async setNotificationConfig(_listenerEnabled: boolean, _blocklist: string[]): Promise<void> {}
16
25
  async getInstalledApps() {
17
26
  return []
18
27
  }
@@ -22,6 +31,9 @@ class CrustModule extends NativeModule<CrustModuleEvents> {
22
31
  async hasNotificationListenerPermission() {
23
32
  return false
24
33
  }
34
+ async refreshNotificationListener() {
35
+ return false
36
+ }
25
37
  async openNotificationListenerSettings() {
26
38
  return false
27
39
  }