@glassly/engine 0.3.0-beta.489 → 0.3.0-dev.460

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 (90) hide show
  1. package/build/engine.d.ts +0 -3
  2. package/build/engine.d.ts.map +1 -1
  3. package/build/facades/miniapps.d.ts +0 -6
  4. package/build/facades/miniapps.d.ts.map +1 -1
  5. package/build/facades/miniapps.js +0 -7
  6. package/build/facades/miniapps.js.map +1 -1
  7. package/build/generated/releaseMetadata.js +3 -3
  8. package/build/generated/releaseMetadata.js.map +1 -1
  9. package/build/index.d.ts +2 -2
  10. package/build/index.d.ts.map +1 -1
  11. package/build/index.js +2 -2
  12. package/build/index.js.map +1 -1
  13. package/build/services/AppRegistry.js +1 -1
  14. package/build/services/AppRegistry.js.map +1 -1
  15. package/build/services/BlobStore.js +2 -2
  16. package/build/services/BlobStore.js.map +1 -1
  17. package/build/services/LocalDisplayManager.d.ts +2 -1
  18. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  19. package/build/services/LocalDisplayManager.js +2 -1
  20. package/build/services/LocalDisplayManager.js.map +1 -1
  21. package/build/services/LocalMiniappRuntime.d.ts +9 -22
  22. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  23. package/build/services/LocalMiniappRuntime.js +52 -117
  24. package/build/services/LocalMiniappRuntime.js.map +1 -1
  25. package/build/services/MiniappLauncher.d.ts +0 -2
  26. package/build/services/MiniappLauncher.d.ts.map +1 -1
  27. package/build/services/MiniappLauncher.js +1 -6
  28. package/build/services/MiniappLauncher.js.map +1 -1
  29. package/build/services/pages/OverlayPages.d.ts +2 -13
  30. package/build/services/pages/OverlayPages.d.ts.map +1 -1
  31. package/build/services/pages/OverlayPages.js +10 -11
  32. package/build/services/pages/OverlayPages.js.map +1 -1
  33. package/build/services/pages/PageHost.d.ts +1 -1
  34. package/build/services/pages/PageHost.d.ts.map +1 -1
  35. package/build/services/pages/PageHost.js +2 -2
  36. package/build/services/pages/PageHost.js.map +1 -1
  37. package/build/services/pages/overlayApps.d.ts +13 -20
  38. package/build/services/pages/overlayApps.d.ts.map +1 -1
  39. package/build/services/pages/overlayApps.js +31 -50
  40. package/build/services/pages/overlayApps.js.map +1 -1
  41. package/build/services/settingsBridge.d.ts +14 -15
  42. package/build/services/settingsBridge.d.ts.map +1 -1
  43. package/build/services/settingsBridge.js +20 -20
  44. package/build/services/settingsBridge.js.map +1 -1
  45. package/build/stores/appVisibility.d.ts +0 -5
  46. package/build/stores/appVisibility.d.ts.map +1 -1
  47. package/build/stores/appVisibility.js +0 -2
  48. package/build/stores/appVisibility.js.map +1 -1
  49. package/build/stores/apps.d.ts +0 -5
  50. package/build/stores/apps.d.ts.map +1 -1
  51. package/build/stores/apps.js +10 -40
  52. package/build/stores/apps.js.map +1 -1
  53. package/build/stores/settings.d.ts.map +1 -1
  54. package/build/stores/settings.js +45 -19
  55. package/build/stores/settings.js.map +1 -1
  56. package/build/types/applet.d.ts +2 -2
  57. package/build/types/applet.d.ts.map +1 -1
  58. package/build/types/applet.js.map +1 -1
  59. package/build/utils/display/scene/anchor.d.ts +2 -1
  60. package/build/utils/display/scene/anchor.d.ts.map +1 -1
  61. package/build/utils/display/scene/anchor.js +2 -1
  62. package/build/utils/display/scene/anchor.js.map +1 -1
  63. package/package.json +7 -7
  64. package/src/facades/miniapps.ts +0 -9
  65. package/src/generated/releaseMetadata.ts +3 -3
  66. package/src/index.ts +1 -3
  67. package/src/services/AppRegistry.ts +1 -1
  68. package/src/services/BlobStore.ts +2 -2
  69. package/src/services/LocalDisplayManager.ts +2 -1
  70. package/src/services/LocalMiniappRuntime.ts +52 -136
  71. package/src/services/MiniappLauncher.ts +1 -6
  72. package/src/services/pages/OverlayPages.ts +10 -11
  73. package/src/services/pages/PageHost.ts +2 -2
  74. package/src/services/pages/overlayApps.ts +30 -51
  75. package/src/services/settingsBridge.ts +20 -20
  76. package/src/stores/appVisibility.ts +0 -4
  77. package/src/stores/apps.ts +12 -44
  78. package/src/stores/settings.ts +45 -19
  79. package/src/types/applet.ts +1 -3
  80. package/src/utils/display/scene/anchor.ts +2 -1
  81. package/build/services/miniappPermissions.d.ts +0 -16
  82. package/build/services/miniappPermissions.d.ts.map +0 -1
  83. package/build/services/miniappPermissions.js +0 -7
  84. package/build/services/miniappPermissions.js.map +0 -1
  85. package/build/services/pages/activeDashboard.d.ts +0 -7
  86. package/build/services/pages/activeDashboard.d.ts.map +0 -1
  87. package/build/services/pages/activeDashboard.js +0 -21
  88. package/build/services/pages/activeDashboard.js.map +0 -1
  89. package/src/services/miniappPermissions.ts +0 -19
  90. package/src/services/pages/activeDashboard.ts +0 -24
@@ -42,9 +42,7 @@ import dashboardOpenTrace from "./debug/DashboardOpenTrace";
42
42
  import { isAppForegrounded, isPhoneActive, onAppForegroundChange, onPhoneActivityChange } from "./PhoneActivity";
43
43
  import { installedNotificationApps } from "./PhoneNotificationsSync";
44
44
  import { DERIVED_SETTINGS_KEYS, SETTINGS_BRIDGE_KEYS, isDerivedSettingsKey, ringBatteryFrom, selectSettingsBridgeKeys, validateSettingsSet, } from "./settingsBridge";
45
- import { mayUsePermission } from "./miniappPermissions";
46
- import { activeDashboardAmong } from "./pages/activeDashboard";
47
- import { activeDashboard, addDashboardApp, displayViewsFor, isDashboardApp, isOverlayApp, onOverlayAppsChange, removeDashboardApp, setActiveDashboard, setOverlayViewer, } from "./pages/overlayApps";
45
+ import { addOverlayApp, displayViewsFor, isOverlayApp, removeOverlayApp, setOverlayViewer } from "./pages/overlayApps";
48
46
  import { pagesEligible } from "./pages/pageEligibility";
49
47
  import nativeNavigationService from "./NativeNavigationService";
50
48
  import headingService from "./HeadingService";
@@ -75,7 +73,6 @@ import { buildMiniappManifestSnapshot } from "../utils/miniappDiagnostics";
75
73
  import ttsModelManager from "./TTSModelManager";
76
74
  import { NavigationHandlers } from "./NavigationHandlers";
77
75
  import { useAppStatusStore } from "../stores/apps";
78
- import { isSystemMiniapp } from "../stores/appVisibility";
79
76
  import { getDevAppAttestation, getDevAppSourcePackage } from "./AppRegistry";
80
77
  import { resolveForegroundLocationPermission } from "./ForegroundLocationPermission";
81
78
  import { advanceMiniappPingLiveness } from "./MiniappLiveness";
@@ -133,6 +130,9 @@ const SYSTEM_MINIAPP_PACKAGES = new Set([
133
130
  "com.glassly.ai",
134
131
  "com.glassly.feedback",
135
132
  "com.glassly.miniappdev",
133
+ // The dashboard: the settings bridge and the miniapp list/start/stop are its side menu and settings
134
+ // page, and the notification app list is its notification settings' per-app filter.
135
+ "com.glassly.dashboard",
136
136
  ]);
137
137
  const PING_INTERVAL_MS = 5_000;
138
138
  // Min gap between "transcription limit reached" notices on the glasses. A
@@ -214,8 +214,6 @@ const PERMISSION_TYPE_TO_CANONICAL = {
214
214
  MEMORY: "memory",
215
215
  AI: "ai",
216
216
  SPEAKERS: "speakers",
217
- MANAGE_MINIAPPS: "manageMiniapps",
218
- PLATFORM_SETTINGS: "platformSettings",
219
217
  };
220
218
  /**
221
219
  * User API keys (Settings > API Keys) a miniapp may read via
@@ -315,8 +313,6 @@ const ALL_CANONICAL_PERMISSIONS = [
315
313
  "ai",
316
314
  "speakers",
317
315
  "displayMirror",
318
- "manageMiniapps",
319
- "platformSettings",
320
316
  ];
321
317
  /**
322
318
  * Build the {location, microphone, camera, notifications, calendar, apiKeys}
@@ -965,11 +961,11 @@ class LocalMiniappRuntime {
965
961
  // Drop this app's transcription hints; the cloud subscription rebuild
966
962
  // below (via replaceStreamSubscribers) re-derives the hint union without it.
967
963
  this.transcriptionHintsByApp.delete(packageName);
968
- // A dashboard is going: release the slot if it holds it, and drop the
964
+ // An overlay app is going: release the slot if it holds it, and drop the
969
965
  // dashboard view from its capabilities record.
970
- if (isDashboardApp(packageName)) {
966
+ if (isOverlayApp(packageName)) {
971
967
  overlayPages.remove(packageName);
972
- removeDashboardApp(packageName);
968
+ removeOverlayApp(packageName);
973
969
  }
974
970
  // Its gesture claims go back to whoever claimed them before.
975
971
  this.applyGestureClaimChanges(dropGestureClaims(this.gestureClaims, packageName));
@@ -1328,10 +1324,7 @@ class LocalMiniappRuntime {
1328
1324
  this.handleOpenUrl(packageName, payload);
1329
1325
  break;
1330
1326
  case MiniappRequestType.DISPLAY_DIAGNOSTICS: {
1331
- // The records are parsed out of the G2PERF lines, which the SDK only logs while g2_perf_logs is on.
1332
- const settings = useSettingsStore.getState();
1333
- const enabled = settings.getSetting(SETTINGS.debug_console.key) === true &&
1334
- settings.getSetting(SETTINGS.g2_perf_logs.key) === true;
1327
+ const enabled = useSettingsStore.getState().getSetting(SETTINGS.debug_console.key) === true;
1335
1328
  this.sendResult(packageName, requestId, true, {
1336
1329
  enabled,
1337
1330
  generatedAt: Date.now(),
@@ -1485,12 +1478,10 @@ class LocalMiniappRuntime {
1485
1478
  // Update lastPongAt so it doesn't time out right away
1486
1479
  existing.lastPongAt = Date.now();
1487
1480
  existing.unansweredPingRounds = 0;
1488
- // The dashboard that holds the role may take the overlay slot: its
1489
- // capabilities carry the dashboard view from the start.
1490
- if (existing.installedManifest?.type === "dashboard") {
1491
- addDashboardApp(packageName);
1492
- this.syncActiveDashboard();
1493
- }
1481
+ // A system_dashboard app may take the overlay slot: its capabilities
1482
+ // carry the dashboard view from the start.
1483
+ if (existing.installedManifest?.type === "system_dashboard")
1484
+ addOverlayApp(packageName);
1494
1485
  const capabilities = this.capabilitiesFor(packageName);
1495
1486
  // Build the declared-permission record for the SDK's session.permissions
1496
1487
  // module. Lower-cased to match v3's PermissionType union (microphone,
@@ -1834,25 +1825,23 @@ class LocalMiniappRuntime {
1834
1825
  const required = permissionForStream(stream);
1835
1826
  if (required && !declaredTypes.has(required)) {
1836
1827
  logPermissionNotDeclared(packageName, required, `to subscribe to "${stream}"`, `{"type": "${required}"}`);
1837
- const error = {
1828
+ this.sendResult(packageName, requestId, false, undefined, {
1838
1829
  code: MiniappErrorCode.PERMISSION_NOT_DECLARED,
1839
1830
  message: `${required} permission not declared in miniapp.json (required for "${stream}"). Add {"type": "${required}"} to the "permissions" array.`,
1840
1831
  // Extra context fields read by the SDK so authors that subscribe
1841
1832
  // to session.on("error") can format their own messages.
1842
1833
  permission: required,
1843
1834
  subscription: stream,
1844
- };
1845
- // The SDK sends SUBSCRIBE without a requestId, so push the rejection.
1846
- if (requestId)
1847
- this.sendResult(packageName, requestId, false, undefined, error);
1848
- else
1849
- this.sendToMiniapp(packageName, { type: MiniappResponseType.ERROR, ...error });
1835
+ });
1850
1836
  return;
1851
1837
  }
1852
1838
  }
1853
- // The settings stream carries the wearer's settings.
1854
- if (streams.includes(MiniappStreamType.SETTINGS_CHANGED) &&
1855
- !this.requirePermission(packageName, requestId, "PLATFORM_SETTINGS", "to subscribe to the settings stream")) {
1839
+ // The settings stream carries the wearer's settings: system apps only.
1840
+ if (streams.includes(MiniappStreamType.SETTINGS_CHANGED) && !this.isSystemPackage(packageName)) {
1841
+ this.sendResult(packageName, requestId, false, undefined, {
1842
+ code: MiniappErrorCode.NOT_PERMITTED,
1843
+ message: "The settings stream is restricted to system apps",
1844
+ });
1856
1845
  return;
1857
1846
  }
1858
1847
  // Add new subscriptions
@@ -1861,9 +1850,8 @@ class LocalMiniappRuntime {
1861
1850
  app.forceLocalTranscriptionStreams = new Set([...forceLocalTranscriptionStreams].filter((stream) => app.subscriptions.has(stream)));
1862
1851
  app.cloudTranscriptionStreams = new Set([...cloudTranscriptionStreams].filter((stream) => app.subscriptions.has(stream)));
1863
1852
  this.replaceStreamSubscribers(packageName, previousSubscriptions, app.subscriptions);
1864
- // The overlay app presents phone notifications on the glasses while it
1865
- // listens to them; recorded for every dashboard so the role can move.
1866
- if (isDashboardApp(packageName)) {
1853
+ // An overlay app that listens to phone notifications presents them on the glasses.
1854
+ if (isOverlayApp(packageName)) {
1867
1855
  setOverlayViewer(packageName, app.subscriptions.has(MiniappStreamType.PHONE_NOTIFICATION));
1868
1856
  }
1869
1857
  this.recomputeMicRequirements();
@@ -2085,13 +2073,13 @@ class LocalMiniappRuntime {
2085
2073
  });
2086
2074
  return;
2087
2075
  }
2088
- // The dashboard view is the overlay app's alone; anyone else's frame
2076
+ // The dashboard view is the overlay apps' alone; anyone else's frame
2089
2077
  // is dropped, reported rather than silently lost.
2090
2078
  if (payload.view === "dashboard" && !isOverlayApp(packageName)) {
2091
2079
  this.sendResult(packageName, requestId, true, {
2092
2080
  status: "displayed",
2093
2081
  presented: false,
2094
- reason: "not the active dashboard",
2082
+ reason: "not the dashboard app",
2095
2083
  });
2096
2084
  return;
2097
2085
  }
@@ -2110,11 +2098,10 @@ class LocalMiniappRuntime {
2110
2098
  }
2111
2099
  }
2112
2100
  /**
2113
- * display.showView: the active dashboard takes or releases the overlay
2114
- * slot. Refused (NOT_PERMITTED) for an app that is not a dashboard;
2115
- * "unsupported" for a dashboard without the role and while the glasses
2116
- * cannot show the dashboard view. Idempotent either way; the slot's state
2117
- * comes back to the app as a display_view change.
2101
+ * display.showView: the designated dashboard app takes or releases the
2102
+ * overlay slot. Refused (NOT_PERMITTED) for any other app; "unsupported"
2103
+ * while the glasses cannot show the dashboard view. Idempotent either way;
2104
+ * the slot's state comes back to the app as a display_view change.
2118
2105
  */
2119
2106
  handleShowView(packageName, payload, requestId) {
2120
2107
  if (!this.connectedApps.has(packageName)) {
@@ -2129,17 +2116,13 @@ class LocalMiniappRuntime {
2129
2116
  });
2130
2117
  return;
2131
2118
  }
2132
- if (!isDashboardApp(packageName)) {
2119
+ if (!isOverlayApp(packageName)) {
2133
2120
  this.sendResult(packageName, requestId, false, undefined, {
2134
2121
  code: MiniappErrorCode.NOT_PERMITTED,
2135
- message: 'The dashboard view belongs to miniapps of type "dashboard"',
2122
+ message: "The dashboard view belongs to system_dashboard apps",
2136
2123
  });
2137
2124
  return;
2138
2125
  }
2139
- if (!isOverlayApp(packageName)) {
2140
- this.sendResult(packageName, requestId, true, { status: "unsupported", reason: "not the active dashboard" });
2141
- return;
2142
- }
2143
2126
  if (view === "main") {
2144
2127
  overlayPages.hide(packageName);
2145
2128
  this.sendResult(packageName, requestId, true, { status: "shown" });
@@ -2158,31 +2141,18 @@ class LocalMiniappRuntime {
2158
2141
  dashboardOpenTrace.slotGranted();
2159
2142
  this.sendResult(packageName, requestId, true, shown ? { status: "shown" } : { status: "unsupported", reason: "the overlay slot was refused" });
2160
2143
  }
2161
- /**
2162
- * Reject the request with PERMISSION_NOT_DECLARED unless the caller's
2163
- * manifest declares `permission`. System apps pass without declaring it.
2164
- */
2165
- requirePermission(packageName, requestId, permission, context) {
2166
- const caller = {
2167
- system: this.isSystemPackage(packageName),
2168
- permissions: this.connectedApps.get(packageName)?.installedManifest?.permissions,
2169
- };
2170
- if (mayUsePermission(caller, permission))
2144
+ // ---------------------------------------------------------------------------
2145
+ // Settings bridge (session.settings) — system apps only
2146
+ // ---------------------------------------------------------------------------
2147
+ requireSystemForSettings(packageName, requestId) {
2148
+ if (this.isSystemPackage(packageName))
2171
2149
  return true;
2172
- logPermissionNotDeclared(packageName, permission, context, `{"type": "${permission}"}`);
2173
2150
  this.sendResult(packageName, requestId, false, undefined, {
2174
- code: MiniappErrorCode.PERMISSION_NOT_DECLARED,
2175
- message: `${permission} permission not declared in miniapp.json. Add {"type": "${permission}"} to the "permissions" array.`,
2176
- permission,
2151
+ code: MiniappErrorCode.NOT_PERMITTED,
2152
+ message: "The settings bridge is restricted to system apps",
2177
2153
  });
2178
2154
  return false;
2179
2155
  }
2180
- // ---------------------------------------------------------------------------
2181
- // Settings bridge (session.settings) — PLATFORM_SETTINGS permission
2182
- // ---------------------------------------------------------------------------
2183
- requireSettingsPermission(packageName, requestId) {
2184
- return this.requirePermission(packageName, requestId, "PLATFORM_SETTINGS", "to use the settings bridge");
2185
- }
2186
2156
  /** A bridged key's current value: the store's, or the engine's for a derived key. */
2187
2157
  settingsBridgeValue(key) {
2188
2158
  if (isDerivedSettingsKey(key))
@@ -2197,12 +2167,10 @@ class LocalMiniappRuntime {
2197
2167
  return localDisplayManager.foregroundAppOnScreen();
2198
2168
  case "ring_battery":
2199
2169
  return ringBatteryFrom(useGlassesStore.getState());
2200
- case "active_dashboard":
2201
- return activeDashboard();
2202
2170
  }
2203
2171
  }
2204
2172
  handleSettingsGet(packageName, payload, requestId) {
2205
- if (!this.requireSettingsPermission(packageName, requestId))
2173
+ if (!this.requireSystemForSettings(packageName, requestId))
2206
2174
  return;
2207
2175
  const values = {};
2208
2176
  for (const key of selectSettingsBridgeKeys(payload.keys))
@@ -2210,7 +2178,7 @@ class LocalMiniappRuntime {
2210
2178
  this.sendResult(packageName, requestId, true, { values });
2211
2179
  }
2212
2180
  async handleSettingsSet(packageName, payload, requestId) {
2213
- if (!this.requireSettingsPermission(packageName, requestId))
2181
+ if (!this.requireSystemForSettings(packageName, requestId))
2214
2182
  return;
2215
2183
  const validated = validateSettingsSet(payload);
2216
2184
  if (!validated.ok) {
@@ -2230,9 +2198,8 @@ class LocalMiniappRuntime {
2230
2198
  this.sendResult(packageName, requestId, true);
2231
2199
  }
2232
2200
  async handleNotificationAppsList(packageName, requestId) {
2233
- if (!this.requirePermission(packageName, requestId, "READ_NOTIFICATIONS", "to list the apps that post notifications")) {
2201
+ if (!this.requireSystemForSettings(packageName, requestId))
2234
2202
  return;
2235
- }
2236
2203
  try {
2237
2204
  this.sendResult(packageName, requestId, true, await installedNotificationApps());
2238
2205
  }
@@ -2246,9 +2213,8 @@ class LocalMiniappRuntime {
2246
2213
  /**
2247
2214
  * Push bridged settings as they change: stored keys from the store, the
2248
2215
  * derived keys whenever their inputs move (phone activity, the display,
2249
- * the apps store, the ring, the dashboard role). Subscribers declared
2250
- * PLATFORM_SETTINGS (gated at SUBSCRIBE), so this is a no-op fan-out for
2251
- * everyone else.
2216
+ * the apps store, the ring). Subscribers are system apps only (gated at
2217
+ * SUBSCRIBE), so this is a no-op fan-out for everyone else.
2252
2218
  */
2253
2219
  ensureSettingsBridgeWired() {
2254
2220
  if (this.settingsBridgeWired)
@@ -2283,7 +2249,6 @@ class LocalMiniappRuntime {
2283
2249
  onAppForegroundChange((foregrounded) => this.broadcastVisibility(foregrounded));
2284
2250
  localDisplayManager.onActiveDisplayChange(pushDerived);
2285
2251
  useAppStatusStore.subscribe(pushDerived);
2286
- onOverlayAppsChange(pushDerived);
2287
2252
  useGlassesStore.subscribe((s) => `${s.ringConnected}:${s.ringBatteryLevel}:${s.controllerConnected}:${s.controllerBatteryLevel}`, pushDerived);
2288
2253
  }
2289
2254
  /**
@@ -4597,33 +4562,6 @@ class LocalMiniappRuntime {
4597
4562
  useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.cfw_native_navigation.key), broadcast);
4598
4563
  // The dashboard master switch flips the dashboard view.
4599
4564
  useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.custom_dashboard_enabled.key), broadcast);
4600
- // The wearer's choice and the installed dashboards decide who holds the role.
4601
- const syncRole = () => this.syncActiveDashboard();
4602
- useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.active_dashboard.key), syncRole);
4603
- useAppStatusStore.subscribe(syncRole);
4604
- syncRole();
4605
- }
4606
- /**
4607
- * Recompute who holds the dashboard role (ADR-0009). The previous holder
4608
- * gives up the slot first, so it hears the view change while it is still
4609
- * the overlay app; then every app sees its views again.
4610
- */
4611
- syncActiveDashboard() {
4612
- const candidates = [...useAppStatusStore.getState().apps];
4613
- // A dashboard can connect at launch before the apps store has listed it.
4614
- for (const [packageName, app] of this.connectedApps) {
4615
- if (candidates.some((candidate) => candidate.packageName === packageName))
4616
- continue;
4617
- candidates.push({ packageName, type: app.installedManifest?.type });
4618
- }
4619
- const next = activeDashboardAmong(candidates);
4620
- const previous = activeDashboard();
4621
- if (next === previous)
4622
- return;
4623
- if (previous !== null)
4624
- overlayPages.hide(previous, "replaced");
4625
- setActiveDashboard(next);
4626
- this.broadcastCapabilities();
4627
4565
  }
4628
4566
  /** Capabilities as `packageName` sees them: the model profile plus the views this app may draw. */
4629
4567
  capabilitiesFor(packageName) {
@@ -5050,16 +4988,14 @@ class LocalMiniappRuntime {
5050
4988
  /* telemetry must never break an interop call */
5051
4989
  }
5052
4990
  }
5053
- /** Reject the request unless the caller may list, start and stop other miniapps (MANAGE_MINIAPPS). */
5054
- requireMiniappsPermission(packageName, requestId, op, target) {
5055
- if (this.requirePermission(packageName, requestId, "MANAGE_MINIAPPS", `to ${op} miniapps`))
4991
+ /** Reject the request with NOT_PERMITTED unless the caller is a system app. */
4992
+ requireSystemCaller(packageName, requestId, op, target) {
4993
+ if (this.isSystemPackage(packageName))
5056
4994
  return true;
5057
- this.auditInterop({
5058
- caller: packageName,
5059
- op,
5060
- target,
5061
- ok: false,
5062
- errorCode: MiniappErrorCode.PERMISSION_NOT_DECLARED,
4995
+ this.auditInterop({ caller: packageName, op, target, ok: false, errorCode: MiniappErrorCode.NOT_PERMITTED });
4996
+ this.sendResult(packageName, requestId, false, undefined, {
4997
+ code: MiniappErrorCode.NOT_PERMITTED,
4998
+ message: "Inter-miniapp APIs are restricted to system apps",
5063
4999
  });
5064
5000
  return false;
5065
5001
  }
@@ -5077,13 +5013,12 @@ class LocalMiniappRuntime {
5077
5013
  version: app.version ?? "",
5078
5014
  running: app.running,
5079
5015
  hidden: app.hidden === true,
5080
- system: isSystemMiniapp(app),
5081
5016
  compatibility,
5082
5017
  actions: app.actions ?? [],
5083
5018
  };
5084
5019
  }
5085
5020
  handleMiniappsList(packageName, payload, requestId) {
5086
- if (!this.requireMiniappsPermission(packageName, requestId, "list"))
5021
+ if (!this.requireSystemCaller(packageName, requestId, "list"))
5087
5022
  return;
5088
5023
  const includeIncompatible = payload.includeIncompatible === true;
5089
5024
  const infos = this.interopApps()
@@ -5097,7 +5032,7 @@ class LocalMiniappRuntime {
5097
5032
  }
5098
5033
  async handleMiniappsStart(packageName, payload, requestId) {
5099
5034
  const target = payload.packageName;
5100
- if (!this.requireMiniappsPermission(packageName, requestId, "start", target))
5035
+ if (!this.requireSystemCaller(packageName, requestId, "start", target))
5101
5036
  return;
5102
5037
  const app = target ? this.interopApps().find((a) => a.packageName === target) : undefined;
5103
5038
  if (!target || !app) {
@@ -5186,7 +5121,7 @@ class LocalMiniappRuntime {
5186
5121
  }
5187
5122
  async handleMiniappsStop(packageName, payload, requestId) {
5188
5123
  const target = payload.packageName;
5189
- if (!this.requireMiniappsPermission(packageName, requestId, "stop", target))
5124
+ if (!this.requireSystemCaller(packageName, requestId, "stop", target))
5190
5125
  return;
5191
5126
  if (!target) {
5192
5127
  this.sendResult(packageName, requestId, false, undefined, {