Skip to content

Commit

Permalink
Handle Chrome OS 105 WebUSB error (#1000)
Browse files Browse the repository at this point in the history
Temporary workaround for ChromeOS 105 bug.
See https://bugs.chromium.org/p/chromium/issues/detail?id=1363712&q=usb&can=2

Co-authored-by: Matt Hillsdon <[email protected]>
Co-authored-by: Matt Hillsdon <[email protected]>
  • Loading branch information
3 people authored Sep 27, 2022
1 parent a4d25d6 commit d9d970e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 18 deletions.
14 changes: 11 additions & 3 deletions src/device/webusb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,24 @@ import {
WebUSBError,
} from "./device";

// Temporary workaround for ChromeOS 105 bug.
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1363712&q=usb&can=2
export const isChromeOS105 = (): boolean => {
const userAgent = navigator.userAgent;
return /CrOS/.test(userAgent) && /Chrome\/105\b/.test(userAgent);
};

/**
* A WebUSB connection to a micro:bit device.
*/
export class MicrobitWebUSBConnection
extends EventEmitter
implements DeviceConnection
{
status: ConnectionStatus = navigator.usb
? ConnectionStatus.NO_AUTHORIZED_DEVICE
: ConnectionStatus.NOT_SUPPORTED;
status: ConnectionStatus =
navigator.usb && !isChromeOS105()
? ConnectionStatus.NO_AUTHORIZED_DEVICE
: ConnectionStatus.NOT_SUPPORTED;

/**
* The USB device we last connected to.
Expand Down
76 changes: 61 additions & 15 deletions src/workbench/connect-dialogs/WebUSBDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
* SPDX-License-Identifier: MIT
*/
import { Button } from "@chakra-ui/button";
import { HStack, Text, VStack } from "@chakra-ui/react";
import { useCallback } from "react";
import { Flex, HStack, Image, Stack, Text, VStack } from "@chakra-ui/react";
import { ReactNode, useCallback } from "react";
import { FormattedMessage } from "react-intl";
import { GenericDialog } from "../../common/GenericDialog";
import { isChromeOS105 } from "../../device/webusb";
import chromeOSErrorImage from "./chrome-os-105-error.png";

interface WebUSBDialogProps {
callback: () => void;
Expand All @@ -25,24 +27,32 @@ export const WebUSBDialog = ({
<GenericDialog
finalFocusRef={finalFocusRef}
onClose={handleClose}
body={<WebUSBDialogBody />}
body={
isChromeOS105() ? <Chrome105ErrorBody /> : <NotSupportedErrorBody />
}
footer={<WebUSBDialogFooter onCancel={handleClose} />}
size="3xl"
/>
);
};

const WebUSBDialogBody = () => {
const DialogBodyWrapper = ({ children }: { children: ReactNode }) => (
<VStack
width="auto"
ml="auto"
mr="auto"
p={8}
pb={0}
spacing={5}
alignItems="flex-start"
>
{children}
</VStack>
);

const NotSupportedErrorBody = () => {
return (
<VStack
width="auto"
ml="auto"
mr="auto"
p={8}
pb={0}
spacing={5}
alignItems="flex-start"
>
<DialogBodyWrapper>
<Text as="h2" fontSize="xl" fontWeight="semibold">
<FormattedMessage id="webusb-not-supported-title" />
</Text>
Expand All @@ -52,7 +62,43 @@ const WebUSBDialogBody = () => {
<Text>
<FormattedMessage id="webusb-why-use" />
</Text>
</VStack>
</DialogBodyWrapper>
);
};

const Chrome105ErrorBody = () => {
return (
<DialogBodyWrapper>
<Text as="h2" fontSize="xl" fontWeight="semibold">
There is an issue with Chrome OS version 105 and WebUSB*
</Text>
<HStack spacing={5}>
<Stack>
<Text>
Unfortunately “Send to micro:bit” does not work in this particular
Chrome OS version due to a bug in the operating system. The next
version of Chrome OS, version 106, expected October 2022, should
contain a fix for this.
</Text>
<Text fontSize="md">
Your program will be saved to your computer instead. Follow the
steps on the next screen to transfer it to your micro:bit.
</Text>
<Text fontSize="sm">
*<FormattedMessage id="webusb-why-use" />
</Text>
</Stack>
<Flex justifyContent="center" width="100%">
<Image
width="100%"
height="100%"
src={chromeOSErrorImage}
alt=""
pb={3}
/>
</Flex>
</HStack>
</DialogBodyWrapper>
);
};

Expand All @@ -63,7 +109,7 @@ interface WebUSBDialogFooterProps {
const WebUSBDialogFooter = ({ onCancel }: WebUSBDialogFooterProps) => {
return (
<HStack spacing={2.5}>
<Button onClick={onCancel} size="lg">
<Button onClick={onCancel} size="lg" variant="solid">
<FormattedMessage id="close-action" />
</Button>
</HStack>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d9d970e

Please sign in to comment.