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

Commit 5d4ad0c2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support USB Port Reset"

parents 6ec5f7fd 476cd2e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4791,6 +4791,7 @@ package android.hardware.usb {
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbData(boolean);
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbDataWhileDocked();
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int resetUsbPort();
    method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
    field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_INTERNAL = 1; // 0x1
    field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_NOT_SUPPORTED = 2; // 0x2
+3 −0
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ interface IUsbManager
    /* Resets the USB gadget. */
    void resetUsbGadget();

    /* Resets the USB port. */
    boolean resetUsbPort(in String portId, int operationId, in IUsbOperationInternal callback);

    /* Set USB data on or off */
    boolean enableUsbData(in String portId, boolean enable, int operationId, in IUsbOperationInternal callback);

+37 −0
Original line number Diff line number Diff line
@@ -1323,6 +1323,43 @@ public class UsbManager {
        }
    }

    /**
     * Should only be called by {@link UsbPort#resetUsbPort}.
     * <p>
     * Disable and then re-enable USB data signaling.
     *
     * Reset USB first port..
     * It will force to stop and restart USB data signaling.
     * Call UsbPort API if the device has more than one UsbPort.
     * </p>
     *
     * @param port reset the USB Port
     * @return true enable or disable USB data successfully
     *         false if something wrong
     *
     * Should only be called by {@link UsbPort#resetUsbPort}.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.MANAGE_USB)
    boolean resetUsbPort(@NonNull UsbPort port, int operationId,
            IUsbOperationInternal callback) {
        Objects.requireNonNull(port, "resetUsbPort: port must not be null. opId:" + operationId);
        try {
            return mService.resetUsbPort(port.getId(), operationId, callback);
        } catch (RemoteException e) {
            Log.e(TAG, "resetUsbPort: failed. ", e);
            try {
                callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
            } catch (RemoteException r) {
                Log.e(TAG, "resetUsbPort: failed to call onOperationComplete. opId:"
                        + operationId, r);
            }
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Should only be called by {@link UsbPort#enableUsbData}.
     * <p>
+40 −0
Original line number Diff line number Diff line
@@ -128,6 +128,9 @@ public final class UsbPort {
    @Retention(RetentionPolicy.SOURCE)
    @interface EnableUsbDataStatus{}

    @Retention(RetentionPolicy.SOURCE)
    @interface ResetUsbPortStatus{}

    /**
     * The {@link #enableLimitPowerTransfer} request was successfully completed.
     */
@@ -318,6 +321,43 @@ public final class UsbPort {
        mUsbManager.setPortRoles(this, powerRole, dataRole);
    }

    /**
     * Reset Usb data on the port.
     *
     * @return       {@link #ENABLE_USB_DATA_SUCCESS} when request completes successfully or
     *               {@link #ENABLE_USB_DATA_ERROR_INTERNAL} when request fails due to internal
     *               error or
     *               {@link ENABLE_USB_DATA_ERROR_NOT_SUPPORTED} when not supported or
     *               {@link ENABLE_USB_DATA_ERROR_PORT_MISMATCH} when request fails due to port id
     *               mismatch or
     *               {@link ENABLE_USB_DATA_ERROR_OTHER} when fails due to other reasons.
     */
    @CheckResult
    @RequiresPermission(Manifest.permission.MANAGE_USB)
    public @ResetUsbPortStatus int resetUsbPort() {
        // UID is added To minimize operationID overlap between two different packages.
        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
        Log.i(TAG, "resetUsbData opId:" + operationId);
        UsbOperationInternal opCallback =
                new UsbOperationInternal(operationId, mId);
        if (mUsbManager.resetUsbPort(this, operationId, opCallback) == true) {
            opCallback.waitForOperationComplete();
        }
        int result = opCallback.getStatus();
        switch (result) {
            case USB_OPERATION_SUCCESS:
                return ENABLE_USB_DATA_SUCCESS;
            case USB_OPERATION_ERROR_INTERNAL:
                return ENABLE_USB_DATA_ERROR_INTERNAL;
            case USB_OPERATION_ERROR_NOT_SUPPORTED:
                return ENABLE_USB_DATA_ERROR_NOT_SUPPORTED;
            case USB_OPERATION_ERROR_PORT_MISMATCH:
                return ENABLE_USB_DATA_ERROR_PORT_MISMATCH;
            default:
                return ENABLE_USB_DATA_ERROR_OTHER;
        }
    }

    /**
     * Enables/Disables Usb data on the port.
     *
+43 −0
Original line number Diff line number Diff line
@@ -503,6 +503,49 @@ public class UsbPortManager {
            return HAL_MODE_DFP;
    }

    /**
     * Reset USB port.
     *
     * @param portId port identifier.
     */
    public boolean resetUsbPort(@NonNull String portId, int transactionId,
            @NonNull IUsbOperationInternal callback, IndentingPrintWriter pw) {
        synchronized (mLock) {
            Objects.requireNonNull(callback);
            Objects.requireNonNull(portId);
            final PortInfo portInfo = mPorts.get(portId);
            if (portInfo == null) {
                logAndPrint(Log.ERROR, pw, "resetUsbPort: No such port: " + portId
                    + " opId:" + transactionId);
                try {
                    callback.onOperationComplete(
                            USB_OPERATION_ERROR_PORT_MISMATCH);
                } catch (RemoteException e) {
                    logAndPrintException(pw,
                            "resetUsbPort: Failed to call OperationComplete. opId:"
                            + transactionId, e);
                }
                return false;
            }

            try {
                try {
                    return mUsbPortHal.resetUsbPort(portId, transactionId, callback);
                } catch (Exception e) {
                    logAndPrintException(pw,
                        "reseetUsbPort: Failed to resetUsbPort. opId:"
                        + transactionId , e);
                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
                }
            } catch (RemoteException e) {
                logAndPrintException(pw,
                        "resetUsbPort: Failed to call onOperationComplete. opId:"
                        + transactionId, e);
            }
            return false;
        }
    }

    public void setPortRoles(String portId, int newPowerRole, int newDataRole,
            IndentingPrintWriter pw) {
        synchronized (mLock) {
Loading