@expo/serve-sim 0.1.35-canary.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/LICENSE +202 -0
- package/README.md +279 -0
- package/Sources/SimAXSettings/build.sh +21 -0
- package/Sources/SimAXSettings/sim-ax-settings.m +273 -0
- package/Sources/SimCameraHelper/build.sh +33 -0
- package/Sources/SimCameraHelper/main.m +955 -0
- package/Sources/SimCameraInjector/SimCamFakes.h +88 -0
- package/Sources/SimCameraInjector/SimCamFakes.m +704 -0
- package/Sources/SimCameraInjector/SimCamFrameSource.h +26 -0
- package/Sources/SimCameraInjector/SimCamFrameSource.m +577 -0
- package/Sources/SimCameraInjector/SimCamLog.h +5 -0
- package/Sources/SimCameraInjector/SimCamLog.m +9 -0
- package/Sources/SimCameraInjector/SimCamSwizzles.h +3 -0
- package/Sources/SimCameraInjector/SimCamSwizzles.m +1338 -0
- package/Sources/SimCameraInjector/SimCameraInjector.m +19 -0
- package/Sources/SimCameraInjector/build.sh +39 -0
- package/Sources/SimCameraInjector/include/SimCamShared.h +79 -0
- package/dist/bin/LiveKitWebRTC.framework/LiveKitWebRTC +0 -0
- package/dist/bin/LiveKitWebRTC.framework/Resources/Info.plist +36 -0
- package/dist/bin/LiveKitWebRTC.framework/Resources/LICENSE.webrtc +29 -0
- package/dist/bin/LiveKitWebRTC.framework/Resources/PrivacyInfo.xcprivacy +32 -0
- package/dist/bin/LiveKitWebRTC.framework/_CodeSignature/CodeResources +150 -0
- package/dist/middleware.cjs +2 -0
- package/dist/middleware.js +123 -0
- package/dist/native/serve-sim-native.node +0 -0
- package/dist/serve-sim.js +218 -0
- package/dist/simax/serve-sim-ax-settings +0 -0
- package/dist/simcam/libSimCameraInjector.dylib +0 -0
- package/dist/simcam/serve-sim-camera-helper +0 -0
- package/dist/state.js +1 -0
- package/package.json +99 -0
- package/src/ax-shared.ts +25 -0
- package/src/ax.ts +258 -0
- package/src/camera-helper.ts +150 -0
- package/src/connect-to-fetch.ts +239 -0
- package/src/middleware.ts +2208 -0
- package/src/native.ts +294 -0
- package/src/state.ts +86 -0
- package/src/stream-settings.ts +202 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// sim-ax-settings — tiny CLI that runs *inside* the iOS Simulator (via
|
|
2
|
+
// `simctl spawn`) to read and write the simulator-wide settings that
|
|
3
|
+
// `simctl ui` does not cover. It drives the same private libAccessibility
|
|
4
|
+
// and MediaAccessibility setters the Xcode Devices app uses, which write the
|
|
5
|
+
// backing preference *and* post the darwin notification that makes running
|
|
6
|
+
// apps pick the change up live.
|
|
7
|
+
//
|
|
8
|
+
// Usage:
|
|
9
|
+
// sim-ax-settings get <key>
|
|
10
|
+
// sim-ax-settings set <key> <value>
|
|
11
|
+
// sim-ax-settings status # JSON object of every key
|
|
12
|
+
//
|
|
13
|
+
// Keys / values:
|
|
14
|
+
// reduce-motion on|off -> _AXSSetReduceMotionEnabled
|
|
15
|
+
// show-borders on|off -> _AXSSetButtonShapesEnabled
|
|
16
|
+
// reduce-transparency on|off -> _AXSSetEnhanceBackgroundContrastEnabled
|
|
17
|
+
// voiceover on|off -> _AXSVoiceOverTouchSetEnabled
|
|
18
|
+
// color-filter none|grayscale|red-green|green-red|blue-yellow
|
|
19
|
+
// -> MADisplayFilterPrefSetType/CategoryEnabled
|
|
20
|
+
// liquid-glass clear|tinted
|
|
21
|
+
// -> com.apple.UIKit UIViewGlassLegibilitySetting
|
|
22
|
+
|
|
23
|
+
#include <CoreFoundation/CoreFoundation.h>
|
|
24
|
+
#include <dlfcn.h>
|
|
25
|
+
#include <notify.h>
|
|
26
|
+
#include <stdio.h>
|
|
27
|
+
#include <stdlib.h>
|
|
28
|
+
#include <string.h>
|
|
29
|
+
|
|
30
|
+
typedef int (*GetBoolFn)(void);
|
|
31
|
+
typedef void (*SetBoolFn)(int);
|
|
32
|
+
typedef long (*MAGetTypeFn)(long);
|
|
33
|
+
typedef void (*MASetTypeFn)(long, long);
|
|
34
|
+
typedef int (*MAGetEnabledFn)(long);
|
|
35
|
+
typedef void (*MASetEnabledFn)(long, int);
|
|
36
|
+
|
|
37
|
+
// MADisplayFilterPref* "category" argument: 1 maps to the "__Color__." key
|
|
38
|
+
// prefix in com.apple.mediaaccessibility (the Settings > Color Filters pane).
|
|
39
|
+
static const long kMAColorCategory = 1;
|
|
40
|
+
|
|
41
|
+
// MADisplayFilterType values, confirmed against libAccessibility's
|
|
42
|
+
// _AXS{GreenRed,BlueYellow}FilterSetEnabled disassembly on iOS 26.5.
|
|
43
|
+
enum {
|
|
44
|
+
kFilterNone = 0,
|
|
45
|
+
kFilterGrayscale = 1,
|
|
46
|
+
kFilterRedGreen = 2, // protanopia
|
|
47
|
+
kFilterGreenRed = 4, // deuteranopia
|
|
48
|
+
kFilterBlueYellow = 8, // tritanopia
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
static void *axHandle(void) {
|
|
52
|
+
static void *handle;
|
|
53
|
+
if (!handle) handle = dlopen("/usr/lib/libAccessibility.dylib", RTLD_NOW);
|
|
54
|
+
return handle;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static void *maHandle(void) {
|
|
58
|
+
static void *handle;
|
|
59
|
+
if (!handle) {
|
|
60
|
+
handle = dlopen(
|
|
61
|
+
"/System/Library/Frameworks/MediaAccessibility.framework/MediaAccessibility",
|
|
62
|
+
RTLD_NOW);
|
|
63
|
+
}
|
|
64
|
+
return handle;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static void *requireSym(void *handle, const char *name) {
|
|
68
|
+
void *sym = handle ? dlsym(handle, name) : NULL;
|
|
69
|
+
if (!sym) {
|
|
70
|
+
fprintf(stderr, "sim-ax-settings: missing symbol %s\n", name);
|
|
71
|
+
exit(2);
|
|
72
|
+
}
|
|
73
|
+
return sym;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ─── Boolean AXS settings ───
|
|
77
|
+
|
|
78
|
+
typedef struct {
|
|
79
|
+
const char *key;
|
|
80
|
+
const char *getter;
|
|
81
|
+
const char *setter;
|
|
82
|
+
} BoolSetting;
|
|
83
|
+
|
|
84
|
+
static const BoolSetting kBoolSettings[] = {
|
|
85
|
+
{"reduce-motion", "_AXSReduceMotionEnabled", "_AXSSetReduceMotionEnabled"},
|
|
86
|
+
{"show-borders", "_AXSButtonShapesEnabled", "_AXSSetButtonShapesEnabled"},
|
|
87
|
+
{"reduce-transparency", "_AXSEnhanceBackgroundContrastEnabled",
|
|
88
|
+
"_AXSSetEnhanceBackgroundContrastEnabled"},
|
|
89
|
+
{"voiceover", "_AXSVoiceOverTouchEnabled", "_AXSVoiceOverTouchSetEnabled"},
|
|
90
|
+
};
|
|
91
|
+
static const size_t kBoolSettingCount =
|
|
92
|
+
sizeof(kBoolSettings) / sizeof(kBoolSettings[0]);
|
|
93
|
+
|
|
94
|
+
static const BoolSetting *findBoolSetting(const char *key) {
|
|
95
|
+
for (size_t i = 0; i < kBoolSettingCount; i++) {
|
|
96
|
+
if (strcmp(kBoolSettings[i].key, key) == 0) return &kBoolSettings[i];
|
|
97
|
+
}
|
|
98
|
+
return NULL;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static int getBoolSetting(const BoolSetting *s) {
|
|
102
|
+
GetBoolFn fn = (GetBoolFn)requireSym(axHandle(), s->getter);
|
|
103
|
+
return fn() ? 1 : 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static void setBoolSetting(const BoolSetting *s, int enabled) {
|
|
107
|
+
SetBoolFn fn = (SetBoolFn)requireSym(axHandle(), s->setter);
|
|
108
|
+
fn(enabled);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ─── Color filter ───
|
|
112
|
+
|
|
113
|
+
static const char *filterName(long type, int enabled) {
|
|
114
|
+
if (!enabled) return "none";
|
|
115
|
+
switch (type) {
|
|
116
|
+
case kFilterGrayscale: return "grayscale";
|
|
117
|
+
case kFilterRedGreen: return "red-green";
|
|
118
|
+
case kFilterGreenRed: return "green-red";
|
|
119
|
+
case kFilterBlueYellow: return "blue-yellow";
|
|
120
|
+
default: return "none";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
static long filterTypeForName(const char *name) {
|
|
125
|
+
if (strcmp(name, "grayscale") == 0) return kFilterGrayscale;
|
|
126
|
+
if (strcmp(name, "red-green") == 0) return kFilterRedGreen;
|
|
127
|
+
if (strcmp(name, "green-red") == 0) return kFilterGreenRed;
|
|
128
|
+
if (strcmp(name, "blue-yellow") == 0) return kFilterBlueYellow;
|
|
129
|
+
return kFilterNone;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static const char *getColorFilter(void) {
|
|
133
|
+
MAGetTypeFn getType =
|
|
134
|
+
(MAGetTypeFn)requireSym(maHandle(), "MADisplayFilterPrefGetType");
|
|
135
|
+
MAGetEnabledFn getEnabled = (MAGetEnabledFn)requireSym(
|
|
136
|
+
maHandle(), "MADisplayFilterPrefGetCategoryEnabled");
|
|
137
|
+
return filterName(getType(kMAColorCategory), getEnabled(kMAColorCategory));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static void setColorFilter(const char *name) {
|
|
141
|
+
MASetTypeFn setType =
|
|
142
|
+
(MASetTypeFn)requireSym(maHandle(), "MADisplayFilterPrefSetType");
|
|
143
|
+
MASetEnabledFn setEnabled = (MASetEnabledFn)requireSym(
|
|
144
|
+
maHandle(), "MADisplayFilterPrefSetCategoryEnabled");
|
|
145
|
+
long type = filterTypeForName(name);
|
|
146
|
+
if (type == kFilterNone) {
|
|
147
|
+
setEnabled(kMAColorCategory, 0);
|
|
148
|
+
} else {
|
|
149
|
+
setType(kMAColorCategory, type);
|
|
150
|
+
setEnabled(kMAColorCategory, 1);
|
|
151
|
+
}
|
|
152
|
+
// Keep the com.apple.Accessibility grayscale flag in sync, matching what
|
|
153
|
+
// the Xcode Devices app writes for the Grayscale filter.
|
|
154
|
+
SetBoolFn setGrayscale =
|
|
155
|
+
(SetBoolFn)requireSym(axHandle(), "_AXSGrayscaleSetEnabled");
|
|
156
|
+
setGrayscale(type == kFilterGrayscale);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ─── Liquid Glass (iOS 26+) ───
|
|
160
|
+
|
|
161
|
+
static CFStringRef kGlassDomain = CFSTR("com.apple.UIKit");
|
|
162
|
+
static CFStringRef kGlassKey = CFSTR("UIViewGlassLegibilitySetting");
|
|
163
|
+
|
|
164
|
+
static const char *getLiquidGlass(void) {
|
|
165
|
+
CFPropertyListRef value = CFPreferencesCopyValue(
|
|
166
|
+
kGlassKey, kGlassDomain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
|
|
167
|
+
int tinted = 0;
|
|
168
|
+
if (value) {
|
|
169
|
+
if (CFGetTypeID(value) == CFNumberGetTypeID()) {
|
|
170
|
+
int n = 0;
|
|
171
|
+
CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &n);
|
|
172
|
+
tinted = n == 1;
|
|
173
|
+
}
|
|
174
|
+
CFRelease(value);
|
|
175
|
+
}
|
|
176
|
+
return tinted ? "tinted" : "clear";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static void setLiquidGlass(const char *name) {
|
|
180
|
+
int tinted = strcmp(name, "tinted") == 0;
|
|
181
|
+
CFNumberRef value = CFNumberCreate(NULL, kCFNumberIntType, &tinted);
|
|
182
|
+
CFPreferencesSetValue(kGlassKey, value, kGlassDomain,
|
|
183
|
+
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
|
|
184
|
+
CFRelease(value);
|
|
185
|
+
CFPreferencesSynchronize(kGlassDomain, kCFPreferencesCurrentUser,
|
|
186
|
+
kCFPreferencesAnyHost);
|
|
187
|
+
notify_post("UIViewGlassLegibilityUpdateNotification");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ─── Entry point ───
|
|
191
|
+
|
|
192
|
+
static void printStatus(void) {
|
|
193
|
+
printf("{");
|
|
194
|
+
for (size_t i = 0; i < kBoolSettingCount; i++) {
|
|
195
|
+
printf("\"%s\":\"%s\",", kBoolSettings[i].key,
|
|
196
|
+
getBoolSetting(&kBoolSettings[i]) ? "on" : "off");
|
|
197
|
+
}
|
|
198
|
+
printf("\"color-filter\":\"%s\",", getColorFilter());
|
|
199
|
+
printf("\"liquid-glass\":\"%s\"}\n", getLiquidGlass());
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static int parseOnOff(const char *value) {
|
|
203
|
+
if (strcmp(value, "on") == 0 || strcmp(value, "1") == 0 ||
|
|
204
|
+
strcmp(value, "true") == 0 || strcmp(value, "enabled") == 0)
|
|
205
|
+
return 1;
|
|
206
|
+
if (strcmp(value, "off") == 0 || strcmp(value, "0") == 0 ||
|
|
207
|
+
strcmp(value, "false") == 0 || strcmp(value, "disabled") == 0)
|
|
208
|
+
return 0;
|
|
209
|
+
return -1;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
int main(int argc, char **argv) {
|
|
213
|
+
if (argc >= 2 && strcmp(argv[1], "status") == 0) {
|
|
214
|
+
printStatus();
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (argc == 3 && strcmp(argv[1], "get") == 0) {
|
|
219
|
+
const char *key = argv[2];
|
|
220
|
+
const BoolSetting *bs = findBoolSetting(key);
|
|
221
|
+
if (bs) {
|
|
222
|
+
printf("%s\n", getBoolSetting(bs) ? "on" : "off");
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
if (strcmp(key, "color-filter") == 0) {
|
|
226
|
+
printf("%s\n", getColorFilter());
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
if (strcmp(key, "liquid-glass") == 0) {
|
|
230
|
+
printf("%s\n", getLiquidGlass());
|
|
231
|
+
return 0;
|
|
232
|
+
}
|
|
233
|
+
fprintf(stderr, "sim-ax-settings: unknown key %s\n", key);
|
|
234
|
+
return 1;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (argc == 4 && strcmp(argv[1], "set") == 0) {
|
|
238
|
+
const char *key = argv[2];
|
|
239
|
+
const char *value = argv[3];
|
|
240
|
+
const BoolSetting *bs = findBoolSetting(key);
|
|
241
|
+
if (bs) {
|
|
242
|
+
int enabled = parseOnOff(value);
|
|
243
|
+
if (enabled < 0) {
|
|
244
|
+
fprintf(stderr, "sim-ax-settings: %s wants on|off, got %s\n", key, value);
|
|
245
|
+
return 1;
|
|
246
|
+
}
|
|
247
|
+
setBoolSetting(bs, enabled);
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
if (strcmp(key, "color-filter") == 0) {
|
|
251
|
+
if (strcmp(value, "none") != 0 && filterTypeForName(value) == kFilterNone) {
|
|
252
|
+
fprintf(stderr, "sim-ax-settings: unknown color filter %s\n", value);
|
|
253
|
+
return 1;
|
|
254
|
+
}
|
|
255
|
+
setColorFilter(value);
|
|
256
|
+
return 0;
|
|
257
|
+
}
|
|
258
|
+
if (strcmp(key, "liquid-glass") == 0) {
|
|
259
|
+
if (strcmp(value, "clear") != 0 && strcmp(value, "tinted") != 0) {
|
|
260
|
+
fprintf(stderr, "sim-ax-settings: liquid-glass wants clear|tinted\n");
|
|
261
|
+
return 1;
|
|
262
|
+
}
|
|
263
|
+
setLiquidGlass(value);
|
|
264
|
+
return 0;
|
|
265
|
+
}
|
|
266
|
+
fprintf(stderr, "sim-ax-settings: unknown key %s\n", key);
|
|
267
|
+
return 1;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
fprintf(stderr,
|
|
271
|
+
"Usage: sim-ax-settings status | get <key> | set <key> <value>\n");
|
|
272
|
+
return 64;
|
|
273
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
4
|
+
OUT_DIR="${1:-$HERE/../../dist/simcam}"
|
|
5
|
+
mkdir -p "$OUT_DIR"
|
|
6
|
+
|
|
7
|
+
SDK="$(xcrun --sdk macosx --show-sdk-path)"
|
|
8
|
+
BIN="$OUT_DIR/serve-sim-camera-helper"
|
|
9
|
+
|
|
10
|
+
xcrun --sdk macosx clang \
|
|
11
|
+
-arch arm64 \
|
|
12
|
+
-mmacosx-version-min=14.0 \
|
|
13
|
+
-isysroot "$SDK" \
|
|
14
|
+
-fobjc-arc -fmodules \
|
|
15
|
+
-framework Foundation \
|
|
16
|
+
-framework AVFoundation \
|
|
17
|
+
-framework CoreMedia \
|
|
18
|
+
-framework CoreVideo \
|
|
19
|
+
-framework CoreGraphics \
|
|
20
|
+
-framework CoreImage \
|
|
21
|
+
-framework CoreText \
|
|
22
|
+
-framework ImageIO \
|
|
23
|
+
-framework IOSurface \
|
|
24
|
+
-framework Accelerate \
|
|
25
|
+
-O2 \
|
|
26
|
+
-o "$BIN" \
|
|
27
|
+
"$HERE/main.m"
|
|
28
|
+
|
|
29
|
+
# Re-sign so the camera privacy prompt persists per-build instead of restarting.
|
|
30
|
+
codesign -s - -f "$BIN" 2>/dev/null || true
|
|
31
|
+
|
|
32
|
+
echo "Built: $BIN"
|
|
33
|
+
file "$BIN"
|