Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf4cf575 authored by Jackeagle's avatar Jackeagle
Browse files

Fix ADB on Pixel 7: select alternate interface and route stale packets



Select the USB alternate setting that has bulk endpoints when it is not
alternate 0 (Pixel 7 exposes ADB endpoints on alternate 1).

Add packet routing by checking arg1 (target localId) in stream open
and shell read loops so stale CLSE acknowledgments from previously
closed streams are skipped instead of breaking the next stream.

Signed-off-by: default avatarJackeagle <jackeagle102@gmail.com>
parent bcaa6e3b
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -156,6 +156,15 @@ export class AdbDevice {
      while (true) {
        const packet = await this.receivePacket();

        // Skip packets for other streams (stale CLSE acks, etc.)
        if (packet.arg1 !== 0 && packet.arg1 !== stream.localId) {
          log(
            `Shell: skipping stale packet cmd=0x${packet.command.toString(16)} ` +
              `for localId=${packet.arg1} (ours=${stream.localId})`,
          );
          continue;
        }

        if (packet.command === AdbCommand.Write) {
          output += decodeUtf8(packet.payload);
          // Send OKAY to acknowledge
+30 −16
Original line number Diff line number Diff line
@@ -59,9 +59,22 @@ export class AdbStream {

    log(`Stream OPEN: localId=${localId}, service="${service}"`);

    // Read response — expect OKAY
    // Read response — expect OKAY.
    // Skip stale packets from previously closed streams (e.g., a CLSE
    // acknowledgment for a stream we already closed).
    // eslint-disable-next-line no-constant-condition
    while (true) {
      const response = await receivePacket();

      // Packets for other streams have arg1 != our localId — skip them
      if (response.arg1 !== 0 && response.arg1 !== localId) {
        log(
          `Stream OPEN: skipping stale packet cmd=0x${response.command.toString(16)} ` +
            `for localId=${response.arg1} (ours=${localId})`,
        );
        continue;
      }

      if (response.command === AdbCommand.Okay) {
        const stream = new AdbStream(transport, localId, response.arg0);
        log(
@@ -80,6 +93,7 @@ export class AdbStream {
        `Unexpected response to OPEN: command=0x${response.command.toString(16)}`,
      );
    }
  }

  /**
   * Write data to the remote end.
+1 −0
Original line number Diff line number Diff line
@@ -26,4 +26,5 @@ export interface EndpointInfo {
  inEndpoint: number;
  outEndpoint: number;
  interfaceNumber: number;
  alternateSetting: number;
}
+11 −0
Original line number Diff line number Diff line
@@ -105,6 +105,16 @@ export class WebUsbTransport {
      // Claim the interface
      await this._device.claimInterface(this._interfaceNumber);

      // Select the alternate setting that has the bulk endpoints.
      // Some devices (e.g. Pixel 7) have alternate 0 with no endpoints
      // and alternate 1 with the actual bulk IN/OUT endpoints.
      if (endpoints.alternateSetting !== 0) {
        await this._device.selectAlternateInterface(
          this._interfaceNumber,
          endpoints.alternateSetting,
        );
      }

      // Clear any stale halt condition on both endpoints.
      // Previous sessions that were interrupted (tab closed, USB unplugged)
      // can leave endpoints in a HALTED state, causing every subsequent
@@ -415,6 +425,7 @@ export class WebUsbTransport {
              inEndpoint,
              outEndpoint,
              interfaceNumber: iface.interfaceNumber,
              alternateSetting: alt.alternateSetting,
            };
          }
        }