Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if selected USB device has ADB interface, if no, redirect to ro… #191

Merged
merged 1 commit into from
Oct 9, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 52 additions & 8 deletions src/AdbRouter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, {
import {
Routes,
Route,
useNavigate,
} from "react-router-dom";
import {
useDispatch,
Expand Down Expand Up @@ -48,6 +49,7 @@ import { reset as resetHealthchecks } from "./features/healthcheck/healthcheckSl

export default function AdbRouter() {
const dispatch = useDispatch();
const navigate = useNavigate();

const isChecked = useSelector(selectChecked);

Expand Down Expand Up @@ -123,6 +125,20 @@ export default function AdbRouter() {
}
}, [adb, dispatch]);

/**
* If an ADB interface could be found, attempt to connect, otherwise
* redirect to rooting page.
*/
const connectOrRedirect = useCallback(async (device) => {
if (hasAdb(device)) {
const backendDevice = new AdbWebUsbBackend(device);
await connectToDevice(backendDevice);
devicePromiseRef.current = null;
} else {
navigate("/root");
}
}, [connectToDevice, navigate]);

/**
* Auto connect to ADB device if all criteria are matched.
*
Expand All @@ -132,26 +148,54 @@ export default function AdbRouter() {
const autoConnect = useCallback(async() => {
const canAutoConnect = (!devicePromiseRef.current && checkedMasterState && isMaster);
if(canAutoConnect) {
const devices = await AdbWebUsbBackend.getDevices();
const devices = await navigator.usb.getDevices();
if(devices.length > 0) {
await connectToDevice(devices[0]);
connectOrRedirect(devices[0]);
}
}
}, [connectOrRedirect, checkedMasterState, devicePromiseRef, isMaster]);

/**
* Check if USB device has ADB interface.
*/
const hasAdb = (device) => {
for(let i = 0; i < device.configurations.length; i += 1) {
const configuration = device.configurations[i];
const interfaces = configuration.interfaces;

for(let j = 0; j < interfaces.length; j += 1) {
const currentInterface = interfaces[j].alternate;
if (currentInterface.interfaceClass === 0xFF) {
return true;
}
}
}
}, [connectToDevice, checkedMasterState, devicePromiseRef, isMaster]);

// Handle button press for device connection
return false;
};

/**
* A general usb device is invoked and the selected device is then used
* to creat an ADB Backend, if this does not work, then we know that the
* device is not rooted yet and we can redirect the user accordingly.
*
* This has the benefit that the user paired the device once and we will
* be able to automatically connect after successful root without any
* more user interaction.
*/
const handleDeviceConnect = useCallback(async() => {
dispatch(connecting());

try {
devicePromiseRef.current = AdbWebUsbBackend.requestDevice();
const filters = [{ vendorId: 0x2ca3 }];
devicePromiseRef.current = navigator.usb.requestDevice({ filters });
const device = await devicePromiseRef.current;
await connectToDevice(device);
devicePromiseRef.current = null;

connectOrRedirect(device);
} catch(e) {
dispatch(connectionFailed());
}
}, [connectToDevice, devicePromiseRef, dispatch]);
}, [connectOrRedirect, devicePromiseRef, dispatch]);

// Set watcher to monitor WebUSB devices popping up or going away
useEffect(() => {
Expand Down