react-native-web-serial-api 0.0.2 → 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.
Files changed (120) hide show
  1. package/README.md +23 -0
  2. package/TESTING.md +301 -0
  3. package/android/build.gradle +2 -2
  4. package/android/src/main/java/dev/webserialapi/NativeUsbSerialModule.java +7 -1
  5. package/lib/commonjs/UsbSerial.js +58 -26
  6. package/lib/commonjs/UsbSerial.js.map +1 -1
  7. package/lib/commonjs/WebSerial.js +169 -57
  8. package/lib/commonjs/WebSerial.js.map +1 -1
  9. package/lib/commonjs/index.js +13 -1
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/lib/dom-exception.js +176 -0
  12. package/lib/commonjs/lib/dom-exception.js.map +1 -0
  13. package/lib/commonjs/lib/event-target.js +138 -0
  14. package/lib/commonjs/lib/event-target.js.map +1 -0
  15. package/lib/commonjs/lib/promise.js +23 -0
  16. package/lib/commonjs/lib/promise.js.map +1 -0
  17. package/lib/commonjs/testing/index.js +70 -0
  18. package/lib/commonjs/testing/index.js.map +1 -0
  19. package/lib/commonjs/testing/install.js +54 -0
  20. package/lib/commonjs/testing/install.js.map +1 -0
  21. package/lib/commonjs/testing/serial-device.js +164 -0
  22. package/lib/commonjs/testing/serial-device.js.map +1 -0
  23. package/lib/commonjs/testing/virtual-serial.js +615 -0
  24. package/lib/commonjs/testing/virtual-serial.js.map +1 -0
  25. package/lib/commonjs/transport.js +61 -0
  26. package/lib/commonjs/transport.js.map +1 -0
  27. package/lib/typescript/src/UsbSerial.d.ts +24 -67
  28. package/lib/typescript/src/UsbSerial.d.ts.map +1 -1
  29. package/lib/typescript/src/WebSerial.d.ts +11 -2
  30. package/lib/typescript/src/WebSerial.d.ts.map +1 -1
  31. package/lib/typescript/src/index.d.ts +2 -0
  32. package/lib/typescript/src/index.d.ts.map +1 -1
  33. package/lib/typescript/src/lib/dom-exception.d.ts +100 -0
  34. package/lib/typescript/src/lib/dom-exception.d.ts.map +1 -0
  35. package/lib/typescript/src/lib/event-target.d.ts +53 -0
  36. package/lib/typescript/src/lib/event-target.d.ts.map +1 -0
  37. package/lib/typescript/src/lib/promise.d.ts +11 -0
  38. package/lib/typescript/src/lib/promise.d.ts.map +1 -0
  39. package/lib/typescript/src/testing/index.d.ts +23 -0
  40. package/lib/typescript/src/testing/index.d.ts.map +1 -0
  41. package/lib/typescript/src/testing/install.d.ts +25 -0
  42. package/lib/typescript/src/testing/install.d.ts.map +1 -0
  43. package/lib/typescript/src/testing/serial-device.d.ts +127 -0
  44. package/lib/typescript/src/testing/serial-device.d.ts.map +1 -0
  45. package/lib/typescript/src/testing/virtual-serial.d.ts +205 -0
  46. package/lib/typescript/src/testing/virtual-serial.d.ts.map +1 -0
  47. package/lib/typescript/src/transport.d.ts +131 -0
  48. package/lib/typescript/src/transport.d.ts.map +1 -0
  49. package/package.json +38 -2
  50. package/src/UsbSerial.ts +65 -90
  51. package/src/WebSerial.ts +227 -88
  52. package/src/index.ts +2 -7
  53. package/src/lib/dom-exception.ts +129 -60
  54. package/src/lib/event-target.ts +46 -21
  55. package/src/lib/promise.ts +7 -7
  56. package/src/testing/index.ts +42 -0
  57. package/src/testing/install.ts +65 -0
  58. package/src/testing/serial-device.ts +193 -0
  59. package/src/testing/virtual-serial.ts +801 -0
  60. package/src/transport.ts +200 -0
  61. package/babel.config.js +0 -3
  62. package/biome.json +0 -35
  63. package/example/.watchmanconfig +0 -1
  64. package/example/App.tsx +0 -71
  65. package/example/__tests__/App.test.tsx +0 -16
  66. package/example/__tests__/connectEvents.test.tsx +0 -81
  67. package/example/__tests__/getPorts.test.tsx +0 -140
  68. package/example/android/app/build.gradle +0 -120
  69. package/example/android/app/debug.keystore +0 -0
  70. package/example/android/app/proguard-rules.pro +0 -10
  71. package/example/android/app/src/debug/AndroidManifest.xml +0 -9
  72. package/example/android/app/src/main/AndroidManifest.xml +0 -38
  73. package/example/android/app/src/main/java/dev/uzlopak/MainActivity.kt +0 -22
  74. package/example/android/app/src/main/java/dev/uzlopak/MainApplication.kt +0 -41
  75. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -37
  76. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  77. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  78. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  79. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  80. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  81. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  82. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  83. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  84. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  85. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  86. package/example/android/app/src/main/res/values/strings.xml +0 -3
  87. package/example/android/app/src/main/res/values/styles.xml +0 -9
  88. package/example/android/build.gradle +0 -22
  89. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  90. package/example/android/gradle/wrapper/gradle-wrapper.properties +0 -7
  91. package/example/android/gradle.properties +0 -47
  92. package/example/android/gradlew +0 -252
  93. package/example/android/gradlew.bat +0 -94
  94. package/example/android/settings.gradle +0 -6
  95. package/example/app.json +0 -4
  96. package/example/babel.config.js +0 -21
  97. package/example/biome.json +0 -47
  98. package/example/deploy.sh +0 -11
  99. package/example/index.html +0 -26
  100. package/example/index.js +0 -9
  101. package/example/index.web.js +0 -8
  102. package/example/jest.config.js +0 -12
  103. package/example/metro.config.js +0 -58
  104. package/example/package-lock.json +0 -14510
  105. package/example/package.json +0 -48
  106. package/example/react-native.config.js +0 -17
  107. package/example/src/components/AppBar.tsx +0 -73
  108. package/example/src/components/Menu.tsx +0 -90
  109. package/example/src/components/SingleChoiceDialog.tsx +0 -120
  110. package/example/src/screens/ConnectScreen.tsx +0 -195
  111. package/example/src/screens/DevicesScreen.tsx +0 -248
  112. package/example/src/screens/TerminalScreen.tsx +0 -564
  113. package/example/src/settings.ts +0 -43
  114. package/example/src/theme.ts +0 -19
  115. package/example/src/util/TextUtil.ts +0 -129
  116. package/example/tsconfig.json +0 -10
  117. package/example/vite.config.mjs +0 -55
  118. package/scripts/deploy-release.sh +0 -127
  119. package/tsconfig.build.json +0 -7
  120. package/tsconfig.json +0 -20
package/README.md CHANGED
@@ -70,6 +70,9 @@ async function run() {
70
70
  }
71
71
  ```
72
72
 
73
+ In Android USB mode, `allowedBluetoothServiceClassIds` is not supported by
74
+ `requestPort()` and will throw a `TypeError` if provided.
75
+
73
76
  ### Control & status signals
74
77
 
75
78
  ```ts
@@ -192,6 +195,26 @@ npm run web # dev server at http://localhost:5173
192
195
 
193
196
  The JavaScript layer (`src/`) implements the Web Serial API on top of a thin TurboModule (`NativeUsbSerial`) whose native Android implementation (`android/src/main/java/dev/webserialapi/`) wraps `usb-serial-for-android`. Reads/writes are bridged to `ReadableStream`/`WritableStream` via [`web-streams-polyfill`](https://github.com/MattiasBuelens/web-streams-polyfill).
194
197
 
198
+ ## Testing
199
+
200
+ The hardware layer sits behind a single injectable `SerialTransport` interface, so you can test against a pure-JS **virtual serial device** instead of real USB hardware — in Jest *and* live on a device/emulator/browser. The same conformance suite runs in both places, and the example app has a **Self Test** screen plus a **Virtual device (demo)** mode.
201
+
202
+ ```ts
203
+ import {Serial} from 'react-native-web-serial-api';
204
+ import {VirtualSerialTransport, EchoDevice} from 'react-native-web-serial-api/testing';
205
+
206
+ const transport = new VirtualSerialTransport();
207
+ transport.addDevice(new EchoDevice(), {hasPermission: true});
208
+ const serial = new Serial(transport); // no native module, no hardware
209
+ ```
210
+
211
+ ```sh
212
+ npm test # unit + WPT conformance suites
213
+ npm run test:coverage # coverage report (HTML in coverage/lcov-report)
214
+ ```
215
+
216
+ See **[TESTING.md](TESTING.md)** for the full guide (authoring a `SerialDevice`, the conformance/WPT suites, on-device E2E, and coverage).
217
+
195
218
  ## License
196
219
 
197
220
  MIT © Aras Abbasi
package/TESTING.md ADDED
@@ -0,0 +1,301 @@
1
+ # Testing
2
+
3
+ This library is designed to be testable **without USB hardware** — both in a
4
+ test runner (Jest, Vitest, …) and live on a device, an emulator, or in the
5
+ browser. One idea makes that possible: every path to the hardware goes through a
6
+ single interface, [`SerialTransport`](src/transport.ts), and you can swap in a
7
+ pure-JavaScript implementation.
8
+
9
+ ```
10
+ Serial / SerialPort ──depends on──► SerialTransport
11
+ ▲ ▲
12
+ UsbSerialModule │ │ VirtualSerialTransport
13
+ (real, native) (in-memory, no native deps)
14
+ ```
15
+
16
+ Because `VirtualSerialTransport` has **no `react-native` dependency**, the same
17
+ code runs under Node/Jest, on a real Android device, and on the web.
18
+
19
+ ---
20
+
21
+ ## The transport seam
22
+
23
+ `Serial` resolves its transport in three ways, in order of precedence:
24
+
25
+ 1. **Constructor injection** — `new Serial(transport)` (best for isolated tests).
26
+ 2. **Global override** — `setUsbSerial(transport)` affects the singleton `serial`
27
+ and any `new Serial()` created without an explicit transport.
28
+ 3. **Default** — the real `UsbSerialModule` backed by the native TurboModule.
29
+
30
+ ```ts
31
+ import {Serial, setUsbSerial, resetUsbSerial} from 'react-native-web-serial-api';
32
+ import {VirtualSerialTransport} from 'react-native-web-serial-api/testing';
33
+
34
+ // (1) explicit — recommended in unit tests
35
+ const transport = new VirtualSerialTransport();
36
+ const serial = new Serial(transport);
37
+
38
+ // (2) global — redirects the singleton `serial` too. Call it before the first
39
+ // getPorts()/requestPort()/addEventListener(). resetUsbSerial() restores default.
40
+ setUsbSerial(transport);
41
+ ```
42
+
43
+ The testing utilities live in the **`react-native-web-serial-api/testing`**
44
+ subpath, so they stay out of your production bundle.
45
+
46
+ ---
47
+
48
+ ## VirtualSerialTransport
49
+
50
+ An in-memory transport backing one or more simulated devices. You register a
51
+ [`SerialDevice`](#simulating-a-whole-device-serialdevice) and the transport
52
+ reads its USB identity; `options` carries the transport-side knobs.
53
+
54
+ ```ts
55
+ import {VirtualSerialTransport, EchoDevice} from 'react-native-web-serial-api/testing';
56
+
57
+ const transport = new VirtualSerialTransport({
58
+ latencyMs: 0, // 0 = resolve on a microtask (deterministic for Jest)
59
+ autoGrantPermission: true,
60
+ });
61
+
62
+ const device = transport.addDevice(
63
+ new EchoDevice({usbVendorId: 0x0403, usbProductId: 0x6001, serialNumber: 'DEMO-1'}),
64
+ {
65
+ hasPermission: true, // false → hidden from getPorts() until requestPort()
66
+ loopbackSignals: true, // DTR→DSR+DCD, RTS→CTS, so getSignals reflects setSignals
67
+ },
68
+ );
69
+ ```
70
+
71
+ `EchoDevice` (loopback) and `SilentDevice` (accepts writes, sends nothing) are
72
+ built in; for anything richer, write a `SerialDevice` (next section).
73
+
74
+ ### Driving a device from a test/UI
75
+
76
+ ```ts
77
+ device.push([0x01, 0x02]); // inbound bytes as if the device sent them
78
+ device.emitError('cable fault'); // raise a read error on the readable stream
79
+ device.attach(); // (re)attach → fires "connect" (new deviceId)
80
+ device.detach(); // detach → fires "disconnect"
81
+ device.loseDevice(); // unplug while open: errors the stream, disconnects
82
+ device.failNext('open'); // make the next open()/write()/… reject once
83
+ device.written; // number[][] — everything the host wrote
84
+ ```
85
+
86
+ `transport.selectNextPort(device)` / `transport.rejectNextPortPicker()` script
87
+ what the next `requestPort()` returns.
88
+
89
+ ---
90
+
91
+ ## Simulating a whole device (`SerialDevice`)
92
+
93
+ To model a *whole* peripheral — a stateful protocol that greets on open, streams
94
+ over time, reacts to control signals, and raises typed errors — extend
95
+ **`SerialDevice`** and override the lifecycle hooks:
96
+
97
+ ```ts
98
+ import {SerialDevice, VirtualSerialTransport} from 'react-native-web-serial-api/testing';
99
+ import {Serial} from 'react-native-web-serial-api';
100
+
101
+ class Thermometer extends SerialDevice {
102
+ usbVendorId = 0x0403;
103
+ usbProductId = 0x6001;
104
+ #timer?: ReturnType<typeof setInterval>;
105
+
106
+ onOpen() { // host opened the port
107
+ this.send('READY\r\n');
108
+ this.#timer = setInterval(() => this.send(`temp=${20 + Math.random()}C\r\n`), 1000);
109
+ }
110
+ onData(bytes: Uint8Array) { // host wrote to the device
111
+ if (String.fromCharCode(...bytes).trim() === 'ID?') this.send('ACME-TEMP\r\n');
112
+ }
113
+ onHostSignals(s) { /* DTR/RTS/break changed */ }
114
+ onClose() { clearInterval(this.#timer); }
115
+ }
116
+
117
+ const transport = new VirtualSerialTransport();
118
+ transport.addDevice(new Thermometer(), {hasPermission: true});
119
+ const serial = new Serial(transport);
120
+ ```
121
+
122
+ Hooks: `onOpen(options)`, `onData(data)`, `onHostSignals(signals)`, `onClose()`
123
+ (all optional, may be async). Helpers: `this.send(bytes|string)`,
124
+ `this.raiseError(message, name?)` (e.g. `'BreakError'`),
125
+ `this.setSignals({dataCarrierDetect, clearToSend, ringIndicator, dataSetReady})`,
126
+ `this.openOptions`. **`EchoDevice`** (loopback), **`SilentDevice`**, and
127
+ **`LineDevice`** (buffers to `\n`, calls `onLine(line)`) are built in.
128
+ `addDevice(device, options?)` reads the device's
129
+ `usbVendorId`/`usbProductId`/`serialNumber`; `options` carries the transport
130
+ knobs (`hasPermission`, `portNumber`, …).
131
+
132
+ ---
133
+
134
+ ## Writing unit tests (Jest)
135
+
136
+ No native mocks required — inject the transport and exercise the real
137
+ `Serial`/`SerialPort` logic and streams:
138
+
139
+ ```ts
140
+ import {Serial} from 'react-native-web-serial-api';
141
+ import {VirtualSerialTransport} from 'react-native-web-serial-api/testing';
142
+
143
+ it('echoes bytes through the streams', async () => {
144
+ const transport = new VirtualSerialTransport();
145
+ transport.addDevice({usbVendorId: 0x0403, usbProductId: 0x6001, hasPermission: true});
146
+ const serial = new Serial(transport);
147
+
148
+ const [port] = await serial.getPorts();
149
+ await port.open({baudRate: 115200});
150
+
151
+ const reader = port.readable!.getReader();
152
+ const writer = port.writable!.getWriter();
153
+ await writer.write(Uint8Array.from([1, 2, 3]));
154
+ expect(Array.from((await reader.read()).value!)).toEqual([1, 2, 3]);
155
+ });
156
+ ```
157
+
158
+ See [`src/__tests__/`](src/__tests__) for the library's own suites. Note: the
159
+ seam imports `react-native`, so a Jest setup needs the RN preset — see this
160
+ repo's [`jest.config.js`](jest.config.js).
161
+
162
+ ---
163
+
164
+ ## The conformance suite (one suite, two runtimes)
165
+
166
+ [`src/__tests__/conformance-suite.ts`](src/__tests__/conformance-suite.ts) exports
167
+ `serialConformanceTests` — self-contained cases (each builds its own
168
+ `Serial` + `VirtualSerialTransport`) with built-in assertions and **no
169
+ test-runner dependency**. It is **test-only code**: it is excluded from the
170
+ build and from the published npm package (it imports the shipped testing
171
+ utilities, not the other way round), so it adds nothing to consumers' bundles.
172
+ The very same array runs:
173
+
174
+ - **under Jest** — [`src/__tests__/conformance.test.ts`](src/__tests__/conformance.test.ts):
175
+ ```ts
176
+ import {serialConformanceTests} from './conformance-suite';
177
+ for (const t of serialConformanceTests) it(t.name, () => t.run());
178
+ ```
179
+ - **on a device** — via `runSerialConformance()`, which returns a structured
180
+ pass/fail result per test (it never throws). The example app's Self-Test
181
+ screen imports it directly from the test folder (a dev-only import — see
182
+ [`example/src/screens/SelfTestScreen.tsx`](example/src/screens/SelfTestScreen.tsx)).
183
+
184
+ ```ts
185
+ import {runSerialConformance, runRealDeviceSmokeTest} from './conformance-suite';
186
+
187
+ const results = await runSerialConformance(); // virtual, full suite
188
+ const smoke = await runRealDeviceSmokeTest(serial); // small, safe, real device
189
+ ```
190
+
191
+ ---
192
+
193
+ ## WPT spec compliance
194
+
195
+ The `WPT …` cases **at the end of the conformance suite**
196
+ ([`src/__tests__/conformance-suite.ts`](src/__tests__/conformance-suite.ts)) are ports of the
197
+ **official Web Platform Tests** for the Web Serial API (vendored in
198
+ `tmp/serial/`), so the spec's own test logic runs against our polyfill via the
199
+ virtual loopback device — proof of W3C compliance, not just our own assertions.
200
+ They live in the conformance suite rather than a separate Jest-only file, so the
201
+ same spec tests run **under Jest *and* on-device** (Self Test screen), not just
202
+ in a browser. They cover loopback read/write (small + large, repeated),
203
+ `readable.cancel()` discarding buffered data, hardware flow-control
204
+ back-pressure, typed `BreakError`/`BufferOverrunError`, large PRNG-stream
205
+ integrity, disconnect during a pending read/write, and the interface (IDL) shape.
206
+
207
+ Porting the spec faithfully originally surfaced five real gaps in the polyfill
208
+ (typed `BreakError`/`BufferOverrunError` on the readable; disconnect rejecting
209
+ the pending read/write with `NetworkError`; the `disconnect` event `target`; and
210
+ a leaked subscription on `readable.cancel()`). All are now **fixed** in
211
+ `WebSerial.ts`, and these cases pass as regression guards. The browser-security
212
+ WPT files (permission prompts, secure-context, `requestPort()` user-gesture
213
+ gating) don't apply to a React Native polyfill and are intentionally not ported;
214
+ the PRNG-stream length is scaled down from the upstream 10 MB so the on-device
215
+ Self Test stays fast.
216
+
217
+ ---
218
+
219
+ ## On-device testing (example app)
220
+
221
+ The [example app](example) ships two ways to test on real hardware (or none):
222
+
223
+ - **Self Test screen** (overflow menu → *Self test…*) runs the conformance suite
224
+ in-app and shows pass/fail, plus a *Run on connected device* smoke test. This
225
+ works on Android, web, and in an emulator with **no device attached**.
226
+ - **Virtual device (demo)** toggle (overflow menu) injects a
227
+ `VirtualSerialTransport` (an FTDI `EchoDevice` + a CP210x `SensorDevice`, both
228
+ authored as `SerialDevice`s — see [example/src/devices/](example/src/devices))
229
+ so the whole Devices → Connect → Terminal flow runs hardware-free.
230
+
231
+ > **Platform note:** demo mode redirects the app's live serial, which only works
232
+ > on Android (where `serial` is this library's polyfill). On web `serial` is the
233
+ > browser's native `navigator.serial`, which the library cannot inject into — but
234
+ > the Self-Test screen still works everywhere because it builds its own
235
+ > `new Serial(virtualTransport)`.
236
+
237
+ ---
238
+
239
+ ## E2E in the emulator
240
+
241
+ The same `SerialDevice` mocks let you run **UI E2E tests** against an app with no
242
+ USB hardware. Install the mock once at startup behind your own flag:
243
+
244
+ ```ts
245
+ // index.js — debug/E2E build only
246
+ import {installSerialMock, EchoDevice} from 'react-native-web-serial-api/testing';
247
+ import {MyThermometer} from './devices/MyThermometer';
248
+
249
+ installSerialMock({
250
+ enabled: process.env.RNWS_SERIAL_MOCK === '1', // your own gate
251
+ devices: [new EchoDevice(), new MyThermometer()],
252
+ });
253
+ ```
254
+
255
+ `installSerialMock` builds a `VirtualSerialTransport` and calls `setUsbSerial`, so
256
+ `navigator.serial` now talks to your simulated devices.
257
+
258
+ The example app ships a **Maestro** suite ([example/.maestro/](example/.maestro))
259
+ that drives the real UI against the in-app mock (via the demo toggle):
260
+
261
+ ```sh
262
+ # start an Android emulator, then:
263
+ npm --prefix example run android # build + install the debug app (Metro)
264
+ npm --prefix example run e2e # maestro test .maestro
265
+
266
+ # from the repo root: run host Jest first, then emulator E2E
267
+ npm run test:host+emulator
268
+ ```
269
+
270
+ - `demo-echo.yaml` — enable demo mode → connect to the FTDI echo device → send a
271
+ line in the Terminal → assert it round-trips.
272
+ - `self-test.yaml` — open *Self test* → run the conformance suite → assert green.
273
+
274
+ This isn't wired into GitHub CI (it needs an emulator); run it locally or in an
275
+ emulator-equipped job. [Detox](https://wix.github.io/Detox/) works the same way —
276
+ the mock is what makes either runner hardware-free.
277
+
278
+ ---
279
+
280
+ ## Running the tests
281
+
282
+ ```sh
283
+ npm test # library unit + conformance suite
284
+ npm run test:watch # watch mode
285
+ npm run typecheck
286
+ npm run lint
287
+
288
+ npm test --prefix example # example app tests
289
+ ```
290
+
291
+ CI runs all of the above plus a build check on every push/PR — see
292
+ [`.github/workflows/ci.yml`](.github/workflows/ci.yml).
293
+
294
+ ## Coverage
295
+
296
+ ```sh
297
+ npm run test:coverage
298
+ ```
299
+
300
+ Prints a per-file table + summary and writes a browsable HTML report to
301
+ `coverage/lcov-report/index.html` (config in [`jest.config.js`](jest.config.js)).
@@ -31,7 +31,7 @@ def getExtOrIntegerDefault(name) {
31
31
  }
32
32
 
33
33
  android {
34
- namespace "dev.webserialapi"
34
+ namespace = "dev.webserialapi"
35
35
 
36
36
  compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
37
37
 
@@ -50,7 +50,7 @@ repositories {
50
50
  mavenCentral()
51
51
  google()
52
52
  // usb-serial-for-android is published on JitPack
53
- maven { url "https://jitpack.io" }
53
+ maven { url = "https://jitpack.io" }
54
54
  }
55
55
 
56
56
  dependencies {
@@ -657,11 +657,17 @@ public class NativeUsbSerialModule extends NativeUsbSerialSpec {
657
657
  Intent intent = new Intent(ACTION_USB_PERMISSION);
658
658
  intent.putExtra(EXTRA_REQUEST_CODE, requestCode);
659
659
 
660
+ intent.setPackage(getReactApplicationContext().getPackageName());
661
+
662
+ int flags = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S
663
+ ? PendingIntent.FLAG_MUTABLE
664
+ : 0;
665
+
660
666
  PendingIntent permissionIntent = PendingIntent.getBroadcast(
661
667
  getReactApplicationContext(),
662
668
  requestCode,
663
669
  intent,
664
- PendingIntent.FLAG_IMMUTABLE
670
+ flags
665
671
  );
666
672
  usbManager.requestPermission(driver.getDevice(), permissionIntent);
667
673
  } catch (Exception e) {
@@ -3,34 +3,37 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.UsbSerialModule = exports.StopBits = exports.Parity = exports.DataBits = void 0;
6
+ Object.defineProperty(exports, "DataBits", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _transport.DataBits;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "Parity", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _transport.Parity;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "StopBits", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _transport.StopBits;
22
+ }
23
+ });
24
+ exports.UsbSerialModule = void 0;
7
25
  exports.getUsbSerial = getUsbSerial;
26
+ exports.resetUsbSerial = resetUsbSerial;
27
+ exports.setUsbSerial = setUsbSerial;
8
28
  var _reactNative = require("react-native");
9
29
  var _NativeUsbSerial = _interopRequireDefault(require("./NativeUsbSerial"));
30
+ var _transport = require("./transport");
10
31
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
- const Parity = exports.Parity = {
12
- NONE: 0,
13
- ODD: 1,
14
- EVEN: 2,
15
- MARK: 3,
16
- SPACE: 4
17
- };
18
- const DataBits = exports.DataBits = {
19
- FIVE: 5,
20
- SIX: 6,
21
- SEVEN: 7,
22
- EIGHT: 8
23
- };
24
- const StopBits = exports.StopBits = {
25
- ONE: 1,
26
- ONE_FIVE: 3,
27
- TWO: 2
28
- };
29
- const DEFAULT_OPEN_OPTIONS = {
30
- dataBits: DataBits.EIGHT,
31
- stopBits: StopBits.ONE,
32
- parity: Parity.NONE
33
- };
32
+ // These types and enums were originally declared in this module and form part
33
+ // of the public `UsbSerial` namespace. They now live in ./transport (a
34
+ // react-native-free module the virtual transport also builds on) and are
35
+ // re-exported here unchanged for backwards compatibility.
36
+
34
37
  class UsbSerialModule {
35
38
  constructor() {
36
39
  if (!_NativeUsbSerial.default) {
@@ -50,7 +53,7 @@ class UsbSerialModule {
50
53
  }
51
54
  open(deviceId, portNumber, options) {
52
55
  const opts = {
53
- ...DEFAULT_OPEN_OPTIONS,
56
+ ..._transport.DEFAULT_OPEN_OPTIONS,
54
57
  ...options
55
58
  };
56
59
  return this.native.open(deviceId, portNumber, opts.baudRate, opts.dataBits, opts.stopBits, opts.parity);
@@ -72,7 +75,7 @@ class UsbSerialModule {
72
75
  }
73
76
  setParameters(deviceId, portNumber, options) {
74
77
  const opts = {
75
- ...DEFAULT_OPEN_OPTIONS,
78
+ ..._transport.DEFAULT_OPEN_OPTIONS,
76
79
  ...options
77
80
  };
78
81
  return this.native.setParameters(deviceId, portNumber, opts.baudRate, opts.dataBits, opts.stopBits, opts.parity);
@@ -140,10 +143,39 @@ class UsbSerialModule {
140
143
  }
141
144
  exports.UsbSerialModule = UsbSerialModule;
142
145
  let instance = null;
146
+ let override = null;
147
+
148
+ /**
149
+ * Resolve the active serial transport. Returns the override set via
150
+ * {@link setUsbSerial} if present (used by tests and by the example's on-device
151
+ * "virtual device" mode); otherwise lazily constructs the real native-backed
152
+ * {@link UsbSerialModule}.
153
+ */
143
154
  function getUsbSerial() {
155
+ if (override) return override;
144
156
  if (!instance) {
145
157
  instance = new UsbSerialModule();
146
158
  }
147
159
  return instance;
148
160
  }
161
+
162
+ /**
163
+ * Override the transport returned by {@link getUsbSerial}. Pass a
164
+ * {@link SerialTransport} (e.g. a `VirtualSerialTransport`) to make the
165
+ * singleton `serial` instance — and any `new Serial()` created without an
166
+ * explicit transport — talk to it instead of real hardware. Pass `null` to
167
+ * clear the override.
168
+ *
169
+ * Inject before the first `getPorts()` / `requestPort()` / `addEventListener()`
170
+ * call so the lazy initialisation in `Serial` picks it up.
171
+ */
172
+ function setUsbSerial(transport) {
173
+ override = transport;
174
+ }
175
+
176
+ /** Clear any override and drop the cached native instance (test teardown). */
177
+ function resetUsbSerial() {
178
+ override = null;
179
+ instance = null;
180
+ }
149
181
  //# sourceMappingURL=UsbSerial.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_NativeUsbSerial","_interopRequireDefault","e","__esModule","default","Parity","exports","NONE","ODD","EVEN","MARK","SPACE","DataBits","FIVE","SIX","SEVEN","EIGHT","StopBits","ONE","ONE_FIVE","TWO","DEFAULT_OPEN_OPTIONS","dataBits","stopBits","parity","UsbSerialModule","constructor","NativeUsbSerial","Error","native","emitter","NativeEventEmitter","NativeModules","findAllDrivers","showPortPicker","filter","labels","requestPermission","deviceId","open","portNumber","options","opts","baudRate","close","isOpen","write","data","timeout","startReading","stopReading","setParameters","setDTR","value","setRTS","getDTR","getRTS","getCD","getCTS","getDSR","getRI","getControlLines","getSupportedControlLines","setFlowControl","flowControl","getFlowControl","getSupportedFlowControl","setBreak","purgeHwBuffers","purgeWriteBuffers","purgeReadBuffers","getSerial","onData","listener","addListener","onError","onConnect","onDisconnect","instance","getUsbSerial"],"sourceRoot":"../../src","sources":["UsbSerial.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_NativeUsbSerial","_interopRequireDefault","_transport","e","__esModule","default","UsbSerialModule","constructor","NativeUsbSerial","Error","native","emitter","NativeEventEmitter","NativeModules","findAllDrivers","showPortPicker","filter","labels","requestPermission","deviceId","open","portNumber","options","opts","DEFAULT_OPEN_OPTIONS","baudRate","dataBits","stopBits","parity","close","isOpen","write","data","timeout","startReading","stopReading","setParameters","setDTR","value","setRTS","getDTR","getRTS","getCD","getCTS","getDSR","getRI","getControlLines","getSupportedControlLines","setFlowControl","flowControl","getFlowControl","getSupportedFlowControl","setBreak","purgeHwBuffers","purgeWriteBuffers","purgeReadBuffers","getSerial","onData","listener","addListener","onError","onConnect","onDisconnect","exports","instance","override","getUsbSerial","setUsbSerial","transport","resetUsbSerial"],"sourceRoot":"../../src","sources":["UsbSerial.ts"],"mappings":"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","ignoreList":[]}