@voltkit-rtc/react-native 0.0.0-stage → 0.1.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/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +1606 -2
- package/android/build.gradle +70 -0
- package/android/consumer-rules.pro +21 -0
- package/android/src/main/AndroidManifest.xml +25 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/AppVisibility.kt +67 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/AudioDevices.kt +67 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/AudioRouter.kt +487 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/CallServiceTypes.kt +120 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/NativeTimers.kt +106 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/NetworkWatch.kt +120 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/OutputChoice.kt +65 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/RtcConfig.kt +83 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/ScoLink.kt +61 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitCallService.kt +287 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcInitProvider.kt +215 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcModule.kt +313 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcPackage.kt +30 -0
- package/android/src/main/res/drawable/voltkit_rtc_default_call_icon.xml +15 -0
- package/android/src/main/res/raw/voltkit_rtc_keep.xml +7 -0
- package/app.plugin.js +17 -0
- package/lib/commonjs/audio.js +215 -0
- package/lib/commonjs/audio.js.map +1 -0
- package/lib/commonjs/components.js +207 -0
- package/lib/commonjs/components.js.map +1 -0
- package/lib/commonjs/create-client.js +47 -0
- package/lib/commonjs/create-client.js.map +1 -0
- package/lib/commonjs/errors.js +99 -0
- package/lib/commonjs/errors.js.map +1 -0
- package/lib/commonjs/globals.js +61 -0
- package/lib/commonjs/globals.js.map +1 -0
- package/lib/commonjs/index.js +234 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/local-media.js +392 -0
- package/lib/commonjs/local-media.js.map +1 -0
- package/lib/commonjs/native-session.js +314 -0
- package/lib/commonjs/native-session.js.map +1 -0
- package/lib/commonjs/native.js +99 -0
- package/lib/commonjs/native.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/permissions.js +166 -0
- package/lib/commonjs/permissions.js.map +1 -0
- package/lib/commonjs/platform/android.js +126 -0
- package/lib/commonjs/platform/android.js.map +1 -0
- package/lib/commonjs/platform/common.js +138 -0
- package/lib/commonjs/platform/common.js.map +1 -0
- package/lib/commonjs/platform/devices.js +151 -0
- package/lib/commonjs/platform/devices.js.map +1 -0
- package/lib/commonjs/platform/index.js +35 -0
- package/lib/commonjs/platform/index.js.map +1 -0
- package/lib/commonjs/platform/ios.js +54 -0
- package/lib/commonjs/platform/ios.js.map +1 -0
- package/lib/commonjs/platform/streams.js +273 -0
- package/lib/commonjs/platform/streams.js.map +1 -0
- package/lib/commonjs/platform/timers.js +71 -0
- package/lib/commonjs/platform/timers.js.map +1 -0
- package/lib/commonjs/platform/visibility.js +60 -0
- package/lib/commonjs/platform/visibility.js.map +1 -0
- package/lib/commonjs/preflight.js +77 -0
- package/lib/commonjs/preflight.js.map +1 -0
- package/lib/commonjs/provider.js +73 -0
- package/lib/commonjs/provider.js.map +1 -0
- package/lib/commonjs/specs/NativeVoltkitRtc.js +29 -0
- package/lib/commonjs/specs/NativeVoltkitRtc.js.map +1 -0
- package/lib/module/audio.js +207 -0
- package/lib/module/audio.js.map +1 -0
- package/lib/module/components.js +200 -0
- package/lib/module/components.js.map +1 -0
- package/lib/module/create-client.js +42 -0
- package/lib/module/create-client.js.map +1 -0
- package/lib/module/errors.js +87 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/globals.js +53 -0
- package/lib/module/globals.js.map +1 -0
- package/lib/module/index.js +33 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/local-media.js +387 -0
- package/lib/module/local-media.js.map +1 -0
- package/lib/module/native-session.js +309 -0
- package/lib/module/native-session.js.map +1 -0
- package/lib/module/native.js +87 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/permissions.js +160 -0
- package/lib/module/permissions.js.map +1 -0
- package/lib/module/platform/android.js +122 -0
- package/lib/module/platform/android.js.map +1 -0
- package/lib/module/platform/common.js +128 -0
- package/lib/module/platform/common.js.map +1 -0
- package/lib/module/platform/devices.js +142 -0
- package/lib/module/platform/devices.js.map +1 -0
- package/lib/module/platform/index.js +24 -0
- package/lib/module/platform/index.js.map +1 -0
- package/lib/module/platform/ios.js +49 -0
- package/lib/module/platform/ios.js.map +1 -0
- package/lib/module/platform/streams.js +268 -0
- package/lib/module/platform/streams.js.map +1 -0
- package/lib/module/platform/timers.js +67 -0
- package/lib/module/platform/timers.js.map +1 -0
- package/lib/module/platform/visibility.js +54 -0
- package/lib/module/platform/visibility.js.map +1 -0
- package/lib/module/preflight.js +72 -0
- package/lib/module/preflight.js.map +1 -0
- package/lib/module/provider.js +68 -0
- package/lib/module/provider.js.map +1 -0
- package/lib/module/specs/NativeVoltkitRtc.js +37 -0
- package/lib/module/specs/NativeVoltkitRtc.js.map +1 -0
- package/lib/typescript/commonjs/audio.d.ts +58 -0
- package/lib/typescript/commonjs/audio.d.ts.map +1 -0
- package/lib/typescript/commonjs/components.d.ts +58 -0
- package/lib/typescript/commonjs/components.d.ts.map +1 -0
- package/lib/typescript/commonjs/create-client.d.ts +35 -0
- package/lib/typescript/commonjs/create-client.d.ts.map +1 -0
- package/lib/typescript/commonjs/errors.d.ts +34 -0
- package/lib/typescript/commonjs/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/globals.d.ts +16 -0
- package/lib/typescript/commonjs/globals.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +24 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/local-media.d.ts +86 -0
- package/lib/typescript/commonjs/local-media.d.ts.map +1 -0
- package/lib/typescript/commonjs/native-session.d.ts +38 -0
- package/lib/typescript/commonjs/native-session.d.ts.map +1 -0
- package/lib/typescript/commonjs/native.d.ts +18 -0
- package/lib/typescript/commonjs/native.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/permissions.d.ts +30 -0
- package/lib/typescript/commonjs/permissions.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/android.d.ts +4 -0
- package/lib/typescript/commonjs/platform/android.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/common.d.ts +101 -0
- package/lib/typescript/commonjs/platform/common.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/devices.d.ts +42 -0
- package/lib/typescript/commonjs/platform/devices.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/index.d.ts +6 -0
- package/lib/typescript/commonjs/platform/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/ios.d.ts +4 -0
- package/lib/typescript/commonjs/platform/ios.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/streams.d.ts +82 -0
- package/lib/typescript/commonjs/platform/streams.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/timers.d.ts +19 -0
- package/lib/typescript/commonjs/platform/timers.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/visibility.d.ts +11 -0
- package/lib/typescript/commonjs/platform/visibility.d.ts.map +1 -0
- package/lib/typescript/commonjs/preflight.d.ts +19 -0
- package/lib/typescript/commonjs/preflight.d.ts.map +1 -0
- package/lib/typescript/commonjs/provider.d.ts +35 -0
- package/lib/typescript/commonjs/provider.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/NativeVoltkitRtc.d.ts +157 -0
- package/lib/typescript/commonjs/specs/NativeVoltkitRtc.d.ts.map +1 -0
- package/lib/typescript/module/audio.d.ts +58 -0
- package/lib/typescript/module/audio.d.ts.map +1 -0
- package/lib/typescript/module/components.d.ts +58 -0
- package/lib/typescript/module/components.d.ts.map +1 -0
- package/lib/typescript/module/create-client.d.ts +35 -0
- package/lib/typescript/module/create-client.d.ts.map +1 -0
- package/lib/typescript/module/errors.d.ts +34 -0
- package/lib/typescript/module/errors.d.ts.map +1 -0
- package/lib/typescript/module/globals.d.ts +16 -0
- package/lib/typescript/module/globals.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +24 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/local-media.d.ts +86 -0
- package/lib/typescript/module/local-media.d.ts.map +1 -0
- package/lib/typescript/module/native-session.d.ts +38 -0
- package/lib/typescript/module/native-session.d.ts.map +1 -0
- package/lib/typescript/module/native.d.ts +18 -0
- package/lib/typescript/module/native.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/permissions.d.ts +30 -0
- package/lib/typescript/module/permissions.d.ts.map +1 -0
- package/lib/typescript/module/platform/android.d.ts +4 -0
- package/lib/typescript/module/platform/android.d.ts.map +1 -0
- package/lib/typescript/module/platform/common.d.ts +101 -0
- package/lib/typescript/module/platform/common.d.ts.map +1 -0
- package/lib/typescript/module/platform/devices.d.ts +42 -0
- package/lib/typescript/module/platform/devices.d.ts.map +1 -0
- package/lib/typescript/module/platform/index.d.ts +6 -0
- package/lib/typescript/module/platform/index.d.ts.map +1 -0
- package/lib/typescript/module/platform/ios.d.ts +4 -0
- package/lib/typescript/module/platform/ios.d.ts.map +1 -0
- package/lib/typescript/module/platform/streams.d.ts +82 -0
- package/lib/typescript/module/platform/streams.d.ts.map +1 -0
- package/lib/typescript/module/platform/timers.d.ts +19 -0
- package/lib/typescript/module/platform/timers.d.ts.map +1 -0
- package/lib/typescript/module/platform/visibility.d.ts +11 -0
- package/lib/typescript/module/platform/visibility.d.ts.map +1 -0
- package/lib/typescript/module/preflight.d.ts +19 -0
- package/lib/typescript/module/preflight.d.ts.map +1 -0
- package/lib/typescript/module/provider.d.ts +35 -0
- package/lib/typescript/module/provider.d.ts.map +1 -0
- package/lib/typescript/module/specs/NativeVoltkitRtc.d.ts +157 -0
- package/lib/typescript/module/specs/NativeVoltkitRtc.d.ts.map +1 -0
- package/package.json +140 -4
- package/plugin/build/android.d.ts +36 -0
- package/plugin/build/android.js +265 -0
- package/plugin/build/index.d.ts +9 -0
- package/plugin/build/index.js +54 -0
- package/plugin/build/ios.d.ts +4 -0
- package/plugin/build/ios.js +43 -0
- package/plugin/build/options.d.ts +93 -0
- package/plugin/build/options.js +140 -0
- package/react-native.config.js +11 -0
- package/src/audio.ts +221 -0
- package/src/components.tsx +233 -0
- package/src/create-client.ts +53 -0
- package/src/errors.ts +81 -0
- package/src/globals.ts +54 -0
- package/src/index.ts +95 -0
- package/src/local-media.ts +420 -0
- package/src/native-session.tsx +338 -0
- package/src/native.ts +84 -0
- package/src/permissions.ts +173 -0
- package/src/platform/android.ts +128 -0
- package/src/platform/common.ts +157 -0
- package/src/platform/devices.ts +148 -0
- package/src/platform/index.ts +22 -0
- package/src/platform/ios.ts +48 -0
- package/src/platform/streams.ts +285 -0
- package/src/platform/timers.ts +72 -0
- package/src/platform/visibility.ts +59 -0
- package/src/preflight.ts +60 -0
- package/src/provider.tsx +86 -0
- package/src/specs/NativeVoltkitRtc.ts +180 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What a connected call needs from the device on Android, kept by the provider for its client:
|
|
5
|
+
*
|
|
6
|
+
* - The call audio (audio.ts): held from the join to the close, so the audio mode, focus and routing are a call's; two
|
|
7
|
+
* clients (a PK battle) hold it together and the last out restores the device.
|
|
8
|
+
* - The call service: a foreground service that keeps the call's network, microphone and timers alive while the app is
|
|
9
|
+
* in the background or the screen is off. Without it Android cuts the app's sockets about 6 s after it leaves the
|
|
10
|
+
* foreground or the screen goes off (Phase 0 finding 3). It runs while any call is live, for every client together
|
|
11
|
+
* (one notification), when the app's manifest declares it (the Expo plugin's callService, default on). Android lets
|
|
12
|
+
* it start, and take new foreground service types (the camera, a screen share), only while the app is visible: it
|
|
13
|
+
* starts on the join and is brought up to date whenever the app comes back to the front. Its notification's Leave
|
|
14
|
+
* action, and the app being swiped away from Recents, close every client it runs for (close code 1000, `left`).
|
|
15
|
+
* Failures reach the provider's onError as `media-unavailable` with `{ feature: 'callService' }`.
|
|
16
|
+
*/
|
|
17
|
+
import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';
|
|
18
|
+
import { useVoltkitClient } from '@voltkit-rtc/react';
|
|
19
|
+
import { listen, nativeConstants, nativeModule } from "./native.js";
|
|
20
|
+
import { callServiceFailed, describeError, logError } from "./errors.js";
|
|
21
|
+
import { audioHoldOf, speakerPreference } from "./audio.js";
|
|
22
|
+
import { localSessionOf } from "./local-media.js";
|
|
23
|
+
import { nativeVisibility } from "./platform/visibility.js";
|
|
24
|
+
import { localStream } from "./platform/common.js";
|
|
25
|
+
|
|
26
|
+
/** The call service's notification. */
|
|
27
|
+
|
|
28
|
+
/** How the provider manages the call audio. */
|
|
29
|
+
|
|
30
|
+
// ----------------------------------------------------------------------------------------- the call service, shared
|
|
31
|
+
|
|
32
|
+
const NOT_DECLARED = Object.freeze({
|
|
33
|
+
declared: false,
|
|
34
|
+
running: false,
|
|
35
|
+
types: Object.freeze([])
|
|
36
|
+
});
|
|
37
|
+
class CallServices {
|
|
38
|
+
/** What each call wants, read afresh at every decision: a call's state is its client's, which emits no event for some changes. */
|
|
39
|
+
wants = new Map();
|
|
40
|
+
running = false;
|
|
41
|
+
busy = false;
|
|
42
|
+
again = false;
|
|
43
|
+
/** The options the service runs with, as sent. */
|
|
44
|
+
applied = null;
|
|
45
|
+
/** Options a start failed for: not tried again until they change or the app comes back to the front. */
|
|
46
|
+
failed = null;
|
|
47
|
+
watching = null;
|
|
48
|
+
state = null;
|
|
49
|
+
listeners = new Set();
|
|
50
|
+
set(key, want) {
|
|
51
|
+
if (want) this.wants.set(key, want);else this.wants.delete(key);
|
|
52
|
+
this.reconcile();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Something a call publishes may have changed: decide again. */
|
|
56
|
+
changed() {
|
|
57
|
+
this.reconcile();
|
|
58
|
+
}
|
|
59
|
+
subscribe = listener => {
|
|
60
|
+
this.listeners.add(listener);
|
|
61
|
+
return () => {
|
|
62
|
+
this.listeners.delete(listener);
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
snapshot = () => {
|
|
66
|
+
if (this.state) return this.state;
|
|
67
|
+
const module = nativeModule();
|
|
68
|
+
if (!module || !nativeConstants()?.callServiceDeclared) return NOT_DECLARED;
|
|
69
|
+
let status = {
|
|
70
|
+
declared: true,
|
|
71
|
+
running: false,
|
|
72
|
+
types: []
|
|
73
|
+
};
|
|
74
|
+
try {
|
|
75
|
+
status = module.getCallServiceStatus();
|
|
76
|
+
} catch (err) {
|
|
77
|
+
logError('could not read the call service\'s status', err);
|
|
78
|
+
}
|
|
79
|
+
this.state = {
|
|
80
|
+
declared: status.declared,
|
|
81
|
+
running: status.running,
|
|
82
|
+
types: [...status.types]
|
|
83
|
+
};
|
|
84
|
+
return this.state;
|
|
85
|
+
};
|
|
86
|
+
publish(status) {
|
|
87
|
+
const now = this.snapshot();
|
|
88
|
+
const next = {
|
|
89
|
+
...now,
|
|
90
|
+
...status
|
|
91
|
+
};
|
|
92
|
+
if (next.running === now.running && next.declared === now.declared && next.types.join() === now.types.join()) return;
|
|
93
|
+
this.state = next;
|
|
94
|
+
for (const listener of [...this.listeners]) listener();
|
|
95
|
+
}
|
|
96
|
+
live() {
|
|
97
|
+
return [...this.wants.values()].map(want => want()).filter(w => w.live);
|
|
98
|
+
}
|
|
99
|
+
reconcile() {
|
|
100
|
+
const module = nativeModule();
|
|
101
|
+
if (!module || !nativeConstants()?.callServiceDeclared) return;
|
|
102
|
+
const live = this.live();
|
|
103
|
+
this.watch(module, live.length > 0 || this.running);
|
|
104
|
+
if (this.busy) {
|
|
105
|
+
this.again = true;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (live.length === 0) {
|
|
109
|
+
this.failed = null;
|
|
110
|
+
if (this.running || this.applied !== null) this.run(module, 'stop', null);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const options = merged(live);
|
|
114
|
+
const key = JSON.stringify(options);
|
|
115
|
+
if (this.running && key === this.applied || key === this.failed) return;
|
|
116
|
+
// Android lets a foreground service start, or widen its types, only while the app is visible.
|
|
117
|
+
if (!safeVisible(module)) return;
|
|
118
|
+
this.run(module, this.running ? 'update' : 'start', options);
|
|
119
|
+
}
|
|
120
|
+
run(module, what, options) {
|
|
121
|
+
this.busy = true;
|
|
122
|
+
const key = options ? JSON.stringify(options) : null;
|
|
123
|
+
const call = what === 'stop' ? module.stopCallService() : what === 'start' ? module.startCallService(options) : module.updateCallService(options);
|
|
124
|
+
call.then(status => {
|
|
125
|
+
this.running = status.running;
|
|
126
|
+
this.applied = status.running ? key : null;
|
|
127
|
+
if (status.running) this.failed = null;
|
|
128
|
+
this.publish({
|
|
129
|
+
declared: status.declared,
|
|
130
|
+
running: status.running,
|
|
131
|
+
types: [...status.types]
|
|
132
|
+
});
|
|
133
|
+
}, err => {
|
|
134
|
+
if (what === 'stop') {
|
|
135
|
+
logError('could not stop the call service', err);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.failed = key;
|
|
139
|
+
const error = callServiceFailed(describeError(err));
|
|
140
|
+
for (const want of this.live()) want.report(error);
|
|
141
|
+
}).finally(() => {
|
|
142
|
+
this.busy = false;
|
|
143
|
+
if (this.again) {
|
|
144
|
+
this.again = false;
|
|
145
|
+
this.reconcile();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// Nothing left to keep running: stop listening until the next call.
|
|
149
|
+
if (!this.running && this.live().length === 0) this.watch(module, false);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Visibility and the service's own events, while a call is live or the service runs. */
|
|
154
|
+
watch(module, on) {
|
|
155
|
+
if (on === (this.watching !== null)) return;
|
|
156
|
+
if (!on) {
|
|
157
|
+
this.watching?.();
|
|
158
|
+
this.watching = null;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const visibility = nativeVisibility(module);
|
|
162
|
+
const stops = [visibility.subscribe(visible => {
|
|
163
|
+
if (!visible) return;
|
|
164
|
+
// Back in front: try again what failed, and bring the service up to date.
|
|
165
|
+
this.failed = null;
|
|
166
|
+
this.reconcile();
|
|
167
|
+
}), listen(module.onCallServiceEvent, 'onCallServiceEvent', event => this.onEvent(event.type, event.types, event.message))];
|
|
168
|
+
this.watching = () => {
|
|
169
|
+
for (const stop of stops) stop();
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
onEvent(type, types, message) {
|
|
173
|
+
switch (type) {
|
|
174
|
+
case 'started':
|
|
175
|
+
case 'updated':
|
|
176
|
+
this.running = true;
|
|
177
|
+
this.publish({
|
|
178
|
+
running: true,
|
|
179
|
+
types: [...types]
|
|
180
|
+
});
|
|
181
|
+
return;
|
|
182
|
+
case 'stopped':
|
|
183
|
+
this.running = false;
|
|
184
|
+
this.applied = null;
|
|
185
|
+
// Stopped from outside while a call is live: started again when the app next comes to the front, not now.
|
|
186
|
+
if (this.live().length > 0) this.failed = JSON.stringify(merged(this.live()));
|
|
187
|
+
this.publish({
|
|
188
|
+
running: false,
|
|
189
|
+
types: []
|
|
190
|
+
});
|
|
191
|
+
this.reconcile();
|
|
192
|
+
return;
|
|
193
|
+
case 'leave':
|
|
194
|
+
case 'taskRemoved':
|
|
195
|
+
for (const want of this.live()) want.leave();
|
|
196
|
+
return;
|
|
197
|
+
case 'failed':
|
|
198
|
+
{
|
|
199
|
+
const error = callServiceFailed(message || 'Android refused it');
|
|
200
|
+
for (const want of this.live()) want.report(error);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
default:
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function safeVisible(module) {
|
|
208
|
+
try {
|
|
209
|
+
return module.isAppVisible();
|
|
210
|
+
} catch {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** What the service runs with for these calls together. */
|
|
216
|
+
function merged(live) {
|
|
217
|
+
const text = [...live].reverse();
|
|
218
|
+
const pick = field => text.find(w => w.text[field])?.text[field] ?? '';
|
|
219
|
+
return {
|
|
220
|
+
title: pick('title'),
|
|
221
|
+
text: pick('text'),
|
|
222
|
+
leaveLabel: pick('leaveLabel'),
|
|
223
|
+
// The camera type only for a call that keeps its camera on in the background.
|
|
224
|
+
pauseCamera: !live.some(w => w.cameraPublished && !w.pauseCamera),
|
|
225
|
+
micPublished: live.some(w => w.micPublished),
|
|
226
|
+
cameraPublished: live.some(w => w.cameraPublished),
|
|
227
|
+
sharing: live.some(w => w.sharing)
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
const callServices = new CallServices();
|
|
231
|
+
|
|
232
|
+
/** The call service: whether the app declares it, whether it runs and with which types. */
|
|
233
|
+
export function useCallService() {
|
|
234
|
+
return useSyncExternalStore(callServices.subscribe, callServices.snapshot, callServices.snapshot);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ---------------------------------------------------------------------------------------------- the provider's part
|
|
238
|
+
|
|
239
|
+
/** Rendered by the provider inside @voltkit-rtc/react's provider: keeps the call audio and the call service for its client. */
|
|
240
|
+
export function NativeSession({
|
|
241
|
+
audio,
|
|
242
|
+
callService,
|
|
243
|
+
pauseCamera,
|
|
244
|
+
onError
|
|
245
|
+
}) {
|
|
246
|
+
const client = useVoltkitClient();
|
|
247
|
+
const manage = audio !== false && audio?.manage !== false;
|
|
248
|
+
const speakerphone = audio === false ? undefined : audio?.speakerphone;
|
|
249
|
+
const wantsService = callService !== false;
|
|
250
|
+
const text = useMemo(() => typeof callService === 'object' && callService !== null ? callService : {}, [callService]);
|
|
251
|
+
const latest = useRef({
|
|
252
|
+
speakerphone,
|
|
253
|
+
text,
|
|
254
|
+
pauseCamera
|
|
255
|
+
});
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
latest.current = {
|
|
258
|
+
speakerphone,
|
|
259
|
+
text,
|
|
260
|
+
pauseCamera
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// What useLocalMedia shows (the screen being shared) is recorded for as long as the provider has the client.
|
|
265
|
+
useEffect(() => client ? localSessionOf(client).hold() : undefined, [client]);
|
|
266
|
+
useEffect(() => {
|
|
267
|
+
if (!client || !manage || !nativeModule()) return;
|
|
268
|
+
const hold = audioHoldOf(client, error => onError.current?.(error));
|
|
269
|
+
hold.retain();
|
|
270
|
+
const sync = () => {
|
|
271
|
+
const state = client.connectionState;
|
|
272
|
+
if (state === 'connected' || state === 'reconnecting') hold.acquire(speakerPreference(latest.current.speakerphone));else if (state === 'closed') hold.release();
|
|
273
|
+
};
|
|
274
|
+
sync();
|
|
275
|
+
const off = client.on('connectionStateChanged', sync);
|
|
276
|
+
return () => {
|
|
277
|
+
off();
|
|
278
|
+
hold.unretain();
|
|
279
|
+
};
|
|
280
|
+
}, [client, manage, onError]);
|
|
281
|
+
useEffect(() => {
|
|
282
|
+
if (!client || !wantsService || !nativeModule()) return;
|
|
283
|
+
const key = {};
|
|
284
|
+
callServices.set(key, () => wantOf(client, latest.current, error => onError.current?.(error)));
|
|
285
|
+
const update = () => callServices.changed();
|
|
286
|
+
// publish() and a camera switch emit no event of their own: useLocalMedia's calls say so through the local session.
|
|
287
|
+
const offs = [...['connectionStateChanged', 'localMediaChanged', 'localStreamChanged', 'screenShareStarted', 'screenShareEnded'].map(event => client.on(event, update)), localSessionOf(client).subscribe(update)];
|
|
288
|
+
return () => {
|
|
289
|
+
for (const off of offs) off();
|
|
290
|
+
callServices.set(key, null);
|
|
291
|
+
};
|
|
292
|
+
}, [client, wantsService, onError]);
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
function wantOf(client, latest, report) {
|
|
296
|
+
const state = client.connectionState;
|
|
297
|
+
const local = localStream(client);
|
|
298
|
+
return {
|
|
299
|
+
live: state === 'connected' || state === 'reconnecting',
|
|
300
|
+
micPublished: (local?.getAudioTracks().length ?? 0) > 0,
|
|
301
|
+
cameraPublished: (local?.getVideoTracks().length ?? 0) > 0,
|
|
302
|
+
sharing: localSessionOf(client).screen !== null,
|
|
303
|
+
pauseCamera: latest.pauseCamera,
|
|
304
|
+
text: latest.text,
|
|
305
|
+
leave: () => client.close(),
|
|
306
|
+
report
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=native-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","useMemo","useRef","useSyncExternalStore","useVoltkitClient","listen","nativeConstants","nativeModule","callServiceFailed","describeError","logError","audioHoldOf","speakerPreference","localSessionOf","nativeVisibility","localStream","NOT_DECLARED","Object","freeze","declared","running","types","CallServices","wants","Map","busy","again","applied","failed","watching","state","listeners","Set","set","key","want","delete","reconcile","changed","subscribe","listener","add","snapshot","module","callServiceDeclared","status","getCallServiceStatus","err","publish","now","next","join","live","values","map","filter","w","watch","length","run","options","merged","JSON","stringify","safeVisible","what","call","stopCallService","startCallService","updateCallService","then","error","report","finally","on","visibility","stops","visible","onCallServiceEvent","event","onEvent","type","message","stop","leave","isAppVisible","text","reverse","pick","field","find","title","leaveLabel","pauseCamera","some","cameraPublished","micPublished","sharing","callServices","useCallService","NativeSession","audio","callService","onError","client","manage","speakerphone","undefined","wantsService","latest","current","hold","retain","sync","connectionState","acquire","release","off","unretain","wantOf","update","offs","local","getAudioTracks","getVideoTracks","screen","close"],"sourceRoot":"../../src","sources":["native-session.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This package's native module (src/specs/NativeVoltkitRtc.ts), read only through here: it is null on iOS (JavaScript
|
|
5
|
+
* only in 0.1.0), in Expo Go and wherever the app was not rebuilt after installing the package. Everything that can do
|
|
6
|
+
* without it does (JavaScript timers, AppState); what cannot raises `media-unavailable` (errors.ts).
|
|
7
|
+
*/
|
|
8
|
+
import { Platform } from 'react-native';
|
|
9
|
+
import NativeVoltkitRtc from "./specs/NativeVoltkitRtc.js";
|
|
10
|
+
import { iosUnsupported, logError, nativeMissing } from "./errors.js";
|
|
11
|
+
/** The version of this package: what getDiagnostics() reports, and what the native side was built from. */
|
|
12
|
+
export const SDK_VERSION = '0.1.0';
|
|
13
|
+
|
|
14
|
+
/** The native module, or null where there is none (iOS, Expo Go, an app not rebuilt). */
|
|
15
|
+
export function nativeModule() {
|
|
16
|
+
if (Platform.OS !== 'android') return null;
|
|
17
|
+
return NativeVoltkitRtc ?? null;
|
|
18
|
+
}
|
|
19
|
+
let constants = null;
|
|
20
|
+
let staleWarned = false;
|
|
21
|
+
|
|
22
|
+
/** The module's constants, read once: the audio mode, screen sharing, the call service as the manifest declares them. */
|
|
23
|
+
export function nativeConstants() {
|
|
24
|
+
const module = nativeModule();
|
|
25
|
+
if (!module) return null;
|
|
26
|
+
if (constants?.module === module) return constants.value;
|
|
27
|
+
let value;
|
|
28
|
+
try {
|
|
29
|
+
value = module.getConstants();
|
|
30
|
+
} catch (err) {
|
|
31
|
+
logError('could not read the native module\'s constants', err);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
constants = {
|
|
35
|
+
module,
|
|
36
|
+
value
|
|
37
|
+
};
|
|
38
|
+
if (!staleWarned && value.nativeVersion && value.nativeVersion !== SDK_VERSION) {
|
|
39
|
+
staleWarned = true;
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.warn(`[voltkit-rtc] the app's native code is @voltkit-rtc/react-native ${value.nativeVersion} but its JavaScript is ${SDK_VERSION}: rebuild the app`);
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The native module for `feature`, or the error that says why there is none. */
|
|
47
|
+
export function requireNative(feature) {
|
|
48
|
+
if (Platform.OS === 'ios') throw iosUnsupported(feature);
|
|
49
|
+
const module = nativeModule();
|
|
50
|
+
if (!module) throw nativeMissing(feature);
|
|
51
|
+
return module;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Subscribe to one of the module's events; a listener that throws is logged and the others still run. */
|
|
55
|
+
export function listen(emitter, name, listener) {
|
|
56
|
+
if (typeof emitter !== 'function') return () => undefined;
|
|
57
|
+
const subscription = emitter(value => {
|
|
58
|
+
try {
|
|
59
|
+
listener(value);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
logError(`listener for ${name} threw`, err);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return () => subscription.remove();
|
|
65
|
+
}
|
|
66
|
+
const AUDIO_TYPES = ['speaker', 'earpiece', 'wiredHeadset', 'bluetooth', 'usb', 'builtinMic', 'other'];
|
|
67
|
+
const KINDS = ['audioinput', 'audiooutput', 'videoinput'];
|
|
68
|
+
|
|
69
|
+
/** A native audio device as the client's MediaDevice. */
|
|
70
|
+
export function toMediaDevice(device) {
|
|
71
|
+
const type = AUDIO_TYPES.includes(device.type) ? device.type : 'other';
|
|
72
|
+
const kind = KINDS.includes(device.kind) ? device.kind : 'audiooutput';
|
|
73
|
+
return {
|
|
74
|
+
deviceId: device.deviceId,
|
|
75
|
+
groupId: device.groupId ?? '',
|
|
76
|
+
kind,
|
|
77
|
+
label: device.label,
|
|
78
|
+
type
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** For tests: forget the cached constants. */
|
|
83
|
+
export function resetNativeForTests() {
|
|
84
|
+
constants = null;
|
|
85
|
+
staleWarned = false;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Platform","NativeVoltkitRtc","iosUnsupported","logError","nativeMissing","SDK_VERSION","nativeModule","OS","constants","staleWarned","nativeConstants","module","value","getConstants","err","nativeVersion","console","warn","requireNative","feature","listen","emitter","name","listener","undefined","subscription","remove","AUDIO_TYPES","KINDS","toMediaDevice","device","type","includes","kind","deviceId","groupId","label","resetNativeForTests"],"sourceRoot":"../../src","sources":["native.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Camera, microphone and notification permissions.
|
|
5
|
+
*
|
|
6
|
+
* Android: PermissionsAndroid. `blocked` is Android's "never ask again" (the user refused twice, or chose "Don't ask
|
|
7
|
+
* again"): only the app's settings can grant it now. The notification permission (Android 13+, POST_NOTIFICATIONS,
|
|
8
|
+
* for the call service's notification) is asked only when asked for; below Android 13 there is none to ask.
|
|
9
|
+
*
|
|
10
|
+
* iOS (preview): react-native-webrtc's permissions module. iOS asks once: a refusal is `blocked` from then on.
|
|
11
|
+
*
|
|
12
|
+
* useLocalMedia().publish() asks for what it needs before any device opens, so a refusal is a `media-unavailable`
|
|
13
|
+
* error with `{ permission, status }` and the camera light never comes on. The SDK's own captures afterwards (a
|
|
14
|
+
* reconnect, a switch) only check, never ask: a dialog must not open in the background.
|
|
15
|
+
*/
|
|
16
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
17
|
+
import { AppState, PermissionsAndroid, Platform } from 'react-native';
|
|
18
|
+
import { loadWebRTC } from "./globals.js";
|
|
19
|
+
import { logError } from "./errors.js";
|
|
20
|
+
|
|
21
|
+
/** What can be asked for. */
|
|
22
|
+
|
|
23
|
+
/** `granted`; `denied` (not granted yet: asking may still show the dialog); `blocked` (only the settings can grant it). */
|
|
24
|
+
|
|
25
|
+
const ANDROID = {
|
|
26
|
+
camera: 'android.permission.CAMERA',
|
|
27
|
+
microphone: 'android.permission.RECORD_AUDIO',
|
|
28
|
+
notifications: 'android.permission.POST_NOTIFICATIONS'
|
|
29
|
+
};
|
|
30
|
+
const unique = kinds => [...new Set(kinds)];
|
|
31
|
+
|
|
32
|
+
/** Android 13 and later have a notification permission; below, notifications need none. */
|
|
33
|
+
const notificationsNeedAsking = () => Platform.OS === 'android' && Number(Platform.Version) >= 33;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Ask for these permissions, showing the system's dialogs for those not granted yet. Resolves with each one's status;
|
|
37
|
+
* never rejects.
|
|
38
|
+
*/
|
|
39
|
+
export async function requestMediaPermissions(kinds) {
|
|
40
|
+
const wanted = unique(kinds);
|
|
41
|
+
const out = {};
|
|
42
|
+
if (wanted.length === 0) return out;
|
|
43
|
+
if (Platform.OS === 'android') {
|
|
44
|
+
const ask = wanted.filter(k => k !== 'notifications' || notificationsNeedAsking());
|
|
45
|
+
for (const kind of wanted) if (!ask.includes(kind)) out[kind] = 'granted';
|
|
46
|
+
if (ask.length === 0) return out;
|
|
47
|
+
let results = {};
|
|
48
|
+
try {
|
|
49
|
+
results = await PermissionsAndroid.requestMultiple(ask.map(k => ANDROID[k]));
|
|
50
|
+
} catch (err) {
|
|
51
|
+
logError('could not ask for permissions', err);
|
|
52
|
+
}
|
|
53
|
+
for (const kind of ask) out[kind] = androidStatus(results[ANDROID[kind]]);
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
for (const kind of wanted) out[kind] = await requestIos(kind);
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Each permission's status now, without asking. Never rejects. */
|
|
61
|
+
export async function checkMediaPermissions(kinds) {
|
|
62
|
+
const wanted = unique(kinds);
|
|
63
|
+
const out = {};
|
|
64
|
+
for (const kind of wanted) {
|
|
65
|
+
if (Platform.OS === 'android') {
|
|
66
|
+
if (kind === 'notifications' && !notificationsNeedAsking()) {
|
|
67
|
+
out[kind] = 'granted';
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
out[kind] = (await PermissionsAndroid.check(ANDROID[kind])) ? 'granted' : 'denied';
|
|
72
|
+
} catch (err) {
|
|
73
|
+
logError('could not check a permission', err);
|
|
74
|
+
out[kind] = 'denied';
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
out[kind] = await queryIos(kind);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
function androidStatus(result) {
|
|
83
|
+
if (result === 'granted') return 'granted';
|
|
84
|
+
if (result === 'never_ask_again') return 'blocked';
|
|
85
|
+
return 'denied';
|
|
86
|
+
}
|
|
87
|
+
async function queryIos(kind) {
|
|
88
|
+
// The SDK shows no notification of its own on iOS: nothing to ask.
|
|
89
|
+
if (kind === 'notifications') return 'granted';
|
|
90
|
+
const webrtc = loadWebRTC();
|
|
91
|
+
if (!webrtc) return 'denied';
|
|
92
|
+
try {
|
|
93
|
+
const result = await webrtc.permissions.query({
|
|
94
|
+
name: kind
|
|
95
|
+
});
|
|
96
|
+
if (result === 'granted') return 'granted';
|
|
97
|
+
return result === 'denied' ? 'blocked' : 'denied';
|
|
98
|
+
} catch (err) {
|
|
99
|
+
logError('could not check a permission', err);
|
|
100
|
+
return 'denied';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function requestIos(kind) {
|
|
104
|
+
const now = await queryIos(kind);
|
|
105
|
+
if (now !== 'denied') return now;
|
|
106
|
+
const webrtc = loadWebRTC();
|
|
107
|
+
if (!webrtc) return 'denied';
|
|
108
|
+
try {
|
|
109
|
+
return (await webrtc.permissions.request({
|
|
110
|
+
name: kind
|
|
111
|
+
})) ? 'granted' : 'blocked';
|
|
112
|
+
} catch (err) {
|
|
113
|
+
logError('could not ask for a permission', err);
|
|
114
|
+
return 'denied';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The status of these permissions, checked on mount and whenever the app returns to the front (the user may have
|
|
119
|
+
* changed them in the settings), with `request()` to ask for them.
|
|
120
|
+
*/
|
|
121
|
+
export function usePermissions(kinds) {
|
|
122
|
+
const key = unique(kinds).sort().join(',');
|
|
123
|
+
const wanted = useMemo(() => key ? key.split(',') : [], [key]);
|
|
124
|
+
const [statuses, setStatuses] = useState(null);
|
|
125
|
+
const live = useRef(true);
|
|
126
|
+
const refresh = useCallback(async () => {
|
|
127
|
+
const next = await checkMediaPermissions(wanted);
|
|
128
|
+
if (live.current) setStatuses(previous => same(previous, next) ? previous : next);
|
|
129
|
+
return next;
|
|
130
|
+
}, [wanted]);
|
|
131
|
+
const request = useCallback(async () => {
|
|
132
|
+
const next = await requestMediaPermissions(wanted);
|
|
133
|
+
if (live.current) setStatuses(previous => same(previous, next) ? previous : next);
|
|
134
|
+
return next;
|
|
135
|
+
}, [wanted]);
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
live.current = true;
|
|
138
|
+
void refresh();
|
|
139
|
+
const subscription = AppState.addEventListener('change', state => {
|
|
140
|
+
if (state === 'active') void refresh();
|
|
141
|
+
});
|
|
142
|
+
return () => {
|
|
143
|
+
live.current = false;
|
|
144
|
+
subscription?.remove();
|
|
145
|
+
};
|
|
146
|
+
}, [refresh]);
|
|
147
|
+
const granted = statuses !== null && wanted.every(k => statuses[k] === 'granted');
|
|
148
|
+
return useMemo(() => ({
|
|
149
|
+
statuses,
|
|
150
|
+
granted,
|
|
151
|
+
request,
|
|
152
|
+
refresh
|
|
153
|
+
}), [statuses, granted, request, refresh]);
|
|
154
|
+
}
|
|
155
|
+
function same(a, b) {
|
|
156
|
+
if (!a) return false;
|
|
157
|
+
const keys = Object.keys(b);
|
|
158
|
+
return keys.length === Object.keys(a).length && keys.every(k => a[k] === b[k]);
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","AppState","PermissionsAndroid","Platform","loadWebRTC","logError","ANDROID","camera","microphone","notifications","unique","kinds","Set","notificationsNeedAsking","OS","Number","Version","requestMediaPermissions","wanted","out","length","ask","filter","k","kind","includes","results","requestMultiple","map","err","androidStatus","requestIos","checkMediaPermissions","check","queryIos","result","webrtc","permissions","query","name","now","request","usePermissions","key","sort","join","split","statuses","setStatuses","live","refresh","next","current","previous","same","subscription","addEventListener","state","remove","granted","every","a","b","keys","Object"],"sourceRoot":"../../src","sources":["permissions.ts"],"mappings":"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","ignoreList":[]}
|