Skip to content

Commit 987bbb0

Browse files
committedNov 23, 2022
Disable native BarcodeDetector on M1/M2 Macs with Ventura
On Macs with an M1/M2 processor and macOS Ventura (macOS version 13), the BarcodeDetector is broken in Chromium based browsers, regardless of the version. For that constellation, the BarcodeDetector does not error but does not detect QR codes. Macs without an M1/M2 or before Ventura are fine. See https://bugs.chromium.org/p/chromium/issues/detail?id=1382442. Fixes nimiq#209
1 parent 34bccc6 commit 987bbb0

8 files changed

+145
-90
lines changed
 

‎qr-scanner.legacy.min.js

+53-52
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎qr-scanner.legacy.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎qr-scanner.min.js

+13-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎qr-scanner.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎qr-scanner.umd.min.js

+13-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎qr-scanner.umd.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/qr-scanner.ts

+48-9
Original file line numberDiff line numberDiff line change
@@ -623,15 +623,37 @@ class QrScanner {
623623
if (workerPath) {
624624
console.warn('Specifying a worker path is not required and not supported anymore.');
625625
}
626-
const useNativeBarcodeDetector = !QrScanner._disableBarcodeDetector
627-
&& ('BarcodeDetector' in window && BarcodeDetector.getSupportedFormats
628-
? (await BarcodeDetector.getSupportedFormats()).includes('qr_code')
629-
: false);
630-
return useNativeBarcodeDetector
631-
? new BarcodeDetector({ formats: ['qr_code'] })
632-
// @ts-ignore no types defined
633-
: (import('./qr-scanner-worker.min.js') as Promise<{ createWorker: () => Worker }>)
634-
.then((module) => module.createWorker());
626+
627+
// @ts-ignore no types defined for import
628+
const createWorker = () => (import('./qr-scanner-worker.min.js') as Promise<{ createWorker: () => Worker }>)
629+
.then((module) => module.createWorker());
630+
631+
const useBarcodeDetector = !QrScanner._disableBarcodeDetector
632+
&& 'BarcodeDetector' in window
633+
&& BarcodeDetector.getSupportedFormats
634+
&& (await BarcodeDetector.getSupportedFormats()).includes('qr_code');
635+
636+
if (!useBarcodeDetector) return createWorker();
637+
638+
// On Macs with an M1/M2 processor and macOS Ventura (macOS version 13), the BarcodeDetector is broken in
639+
// Chromium based browsers, regardless of the version. For that constellation, the BarcodeDetector does not
640+
// error but does not detect QR codes. Macs without an M1/M2 or before Ventura are fine.
641+
// See issue #209 and https://bugs.chromium.org/p/chromium/issues/detail?id=1382442
642+
// TODO update this once the issue in macOS is fixed
643+
const userAgentData = navigator.userAgentData;
644+
const isChromiumOnMacWithArmVentura = userAgentData // all Chromium browsers support userAgentData
645+
&& userAgentData.brands.some(({ brand }) => /Chromium/i.test(brand))
646+
&& /mac ?OS/i.test(userAgentData.platform)
647+
// Does it have an ARM chip (e.g. M1/M2) and Ventura? Check this last as getHighEntropyValues can
648+
// theoretically trigger a browser prompt, although no browser currently does seem to show one.
649+
// If browser or user refused to return the requested values, assume broken ARM Ventura, to be safe.
650+
&& await userAgentData.getHighEntropyValues(['architecture', 'platformVersion'])
651+
.then(({ architecture, platformVersion }) =>
652+
/arm/i.test(architecture || 'arm') && parseInt(platformVersion || '13') >= /* Ventura */ 13)
653+
.catch(() => true);
654+
if (isChromiumOnMacWithArmVentura) return createWorker();
655+
656+
return new BarcodeDetector({ formats: ['qr_code'] });
635657
}
636658

637659
private _onPlay(): void {
@@ -1083,4 +1105,21 @@ declare class BarcodeDetector {
10831105
detect(image: ImageBitmapSource): Promise<Array<{ rawValue: string, cornerPoints: QrScanner.Point[] }>>;
10841106
}
10851107

1108+
// simplified from https://github.com/lukewarlow/user-agent-data-types/blob/master/index.d.ts
1109+
declare global {
1110+
interface Navigator {
1111+
readonly userAgentData?: {
1112+
readonly platform: string;
1113+
readonly brands: Array<{
1114+
readonly brand: string;
1115+
readonly version: string;
1116+
}>;
1117+
getHighEntropyValues(hints: string[]): Promise<{
1118+
readonly architecture?: string;
1119+
readonly platformVersion?: string;
1120+
}>;
1121+
};
1122+
}
1123+
}
1124+
10861125
export default QrScanner;

‎types/qr-scanner.d.ts

+15
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,19 @@ declare class BarcodeDetector {
122122
cornerPoints: QrScanner.Point[];
123123
}>>;
124124
}
125+
declare global {
126+
interface Navigator {
127+
readonly userAgentData?: {
128+
readonly platform: string;
129+
readonly brands: Array<{
130+
readonly brand: string;
131+
readonly version: string;
132+
}>;
133+
getHighEntropyValues(hints: string[]): Promise<{
134+
readonly architecture?: string;
135+
readonly platformVersion?: string;
136+
}>;
137+
};
138+
}
139+
}
125140
export default QrScanner;

0 commit comments

Comments
 (0)
Please sign in to comment.