Merge "Asynchronous the resetUsbPort" into tm-dev
This commit is contained in:
commit
c7daca4990
@ -5365,7 +5365,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 @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbPort(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
|
||||
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
|
||||
@ -5383,6 +5383,11 @@ package android.hardware.usb {
|
||||
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5; // 0x5
|
||||
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH = 3; // 0x3
|
||||
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS = 0; // 0x0
|
||||
field public static final int RESET_USB_PORT_ERROR_INTERNAL = 1; // 0x1
|
||||
field public static final int RESET_USB_PORT_ERROR_NOT_SUPPORTED = 2; // 0x2
|
||||
field public static final int RESET_USB_PORT_ERROR_OTHER = 4; // 0x4
|
||||
field public static final int RESET_USB_PORT_ERROR_PORT_MISMATCH = 3; // 0x3
|
||||
field public static final int RESET_USB_PORT_SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
public final class UsbPortStatus implements android.os.Parcelable {
|
||||
|
@ -137,7 +137,7 @@ interface IUsbManager
|
||||
void resetUsbGadget();
|
||||
|
||||
/* Resets the USB port. */
|
||||
boolean resetUsbPort(in String portId, int operationId, in IUsbOperationInternal callback);
|
||||
void 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);
|
||||
|
@ -1360,11 +1360,11 @@ public class UsbManager {
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.MANAGE_USB)
|
||||
boolean resetUsbPort(@NonNull UsbPort port, int operationId,
|
||||
void 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);
|
||||
mService.resetUsbPort(port.getId(), operationId, callback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "resetUsbPort: failed. ", e);
|
||||
try {
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package android.hardware.usb;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
import android.hardware.usb.IUsbOperationInternal;
|
||||
import android.hardware.usb.UsbPort;
|
||||
@ -24,7 +25,9 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
/**
|
||||
* UsbOperationInternal allows UsbPort to support both synchronous and
|
||||
* asynchronous function irrespective of whether the underlying hal
|
||||
@ -39,6 +42,10 @@ public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
|
||||
private final String mId;
|
||||
// True implies operation did not timeout.
|
||||
private boolean mOperationComplete;
|
||||
private boolean mAsynchronous = false;
|
||||
private Executor mExecutor;
|
||||
private Consumer<Integer> mConsumer;
|
||||
private int mResult = 0;
|
||||
private @UsbOperationStatus int mStatus;
|
||||
final ReentrantLock mLock = new ReentrantLock();
|
||||
final Condition mOperationWait = mLock.newCondition();
|
||||
@ -78,6 +85,15 @@ public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface UsbOperationStatus{}
|
||||
|
||||
UsbOperationInternal(int operationID, String id,
|
||||
Executor executor, Consumer<Integer> consumer) {
|
||||
this.mOperationID = operationID;
|
||||
this.mId = id;
|
||||
this.mExecutor = executor;
|
||||
this.mConsumer = consumer;
|
||||
this.mAsynchronous = true;
|
||||
}
|
||||
|
||||
UsbOperationInternal(int operationID, String id) {
|
||||
this.mOperationID = operationID;
|
||||
this.mId = id;
|
||||
@ -94,7 +110,27 @@ public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
|
||||
mOperationComplete = true;
|
||||
mStatus = status;
|
||||
Log.i(TAG, "Port:" + mId + " opID:" + mOperationID + " status:" + mStatus);
|
||||
mOperationWait.signal();
|
||||
if (mAsynchronous) {
|
||||
switch (mStatus) {
|
||||
case USB_OPERATION_SUCCESS:
|
||||
mResult = UsbPort.RESET_USB_PORT_SUCCESS;
|
||||
break;
|
||||
case USB_OPERATION_ERROR_INTERNAL:
|
||||
mResult = UsbPort.RESET_USB_PORT_ERROR_INTERNAL;
|
||||
break;
|
||||
case USB_OPERATION_ERROR_NOT_SUPPORTED:
|
||||
mResult = UsbPort.RESET_USB_PORT_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
case USB_OPERATION_ERROR_PORT_MISMATCH:
|
||||
mResult = UsbPort.RESET_USB_PORT_ERROR_PORT_MISMATCH;
|
||||
break;
|
||||
default:
|
||||
mResult = UsbPort.RESET_USB_PORT_ERROR_OTHER;
|
||||
}
|
||||
mExecutor.execute(() -> mConsumer.accept(mResult));
|
||||
} else {
|
||||
mOperationWait.signal();
|
||||
}
|
||||
} finally {
|
||||
mLock.unlock();
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE;
|
||||
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_DEBUG;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.CheckResult;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
@ -65,6 +66,8 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represents a physical USB port and describes its characteristics.
|
||||
@ -128,9 +131,6 @@ public final class UsbPort {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface EnableUsbDataStatus{}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface ResetUsbPortStatus{}
|
||||
|
||||
/**
|
||||
* The {@link #enableLimitPowerTransfer} request was successfully completed.
|
||||
*/
|
||||
@ -197,6 +197,42 @@ public final class UsbPort {
|
||||
*/
|
||||
public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5;
|
||||
|
||||
/**
|
||||
* The {@link #resetUsbPort} request was successfully completed.
|
||||
*/
|
||||
public static final int RESET_USB_PORT_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* The {@link #resetUsbPort} request failed due to internal error.
|
||||
*/
|
||||
public static final int RESET_USB_PORT_ERROR_INTERNAL = 1;
|
||||
|
||||
/**
|
||||
* The {@link #resetUsbPort} request failed as it's not supported.
|
||||
*/
|
||||
public static final int RESET_USB_PORT_ERROR_NOT_SUPPORTED = 2;
|
||||
|
||||
/**
|
||||
* The {@link #resetUsbPort} request failed as port id mismatched.
|
||||
*/
|
||||
public static final int RESET_USB_PORT_ERROR_PORT_MISMATCH = 3;
|
||||
|
||||
/**
|
||||
* The {@link #resetUsbPort} request failed due to other reasons.
|
||||
*/
|
||||
public static final int RESET_USB_PORT_ERROR_OTHER = 4;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "RESET_USB_PORT_" }, value = {
|
||||
RESET_USB_PORT_SUCCESS,
|
||||
RESET_USB_PORT_ERROR_INTERNAL,
|
||||
RESET_USB_PORT_ERROR_NOT_SUPPORTED,
|
||||
RESET_USB_PORT_ERROR_PORT_MISMATCH,
|
||||
RESET_USB_PORT_ERROR_OTHER
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface ResetUsbPortStatus{}
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "ENABLE_USB_DATA_WHILE_DOCKED_" }, value = {
|
||||
ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS,
|
||||
@ -324,38 +360,29 @@ public final class UsbPort {
|
||||
/**
|
||||
* 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.
|
||||
* @param executor Executor for the callback.
|
||||
* @param consumer A consumer that consumes the reset result.
|
||||
* {@link #RESET_USB_PORT_SUCCESS} when request completes
|
||||
* successfully or
|
||||
* {@link #RESET_USB_PORT_ERROR_INTERNAL} when request
|
||||
* fails due to internal error or
|
||||
* {@link RESET_USB_PORT_ERROR_NOT_SUPPORTED} when not
|
||||
* supported or
|
||||
* {@link RESET_USB_PORT_ERROR_PORT_MISMATCH} when request
|
||||
* fails due to port id mismatch or
|
||||
* {@link RESET_USB_PORT_ERROR_OTHER} when fails due to
|
||||
* other reasons.
|
||||
*/
|
||||
@CheckResult
|
||||
@RequiresPermission(Manifest.permission.MANAGE_USB)
|
||||
public @ResetUsbPortStatus int resetUsbPort() {
|
||||
public void resetUsbPort(@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull @ResetUsbPortStatus Consumer<Integer> consumer) {
|
||||
// UID is added To minimize operationID overlap between two different packages.
|
||||
int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
|
||||
Log.i(TAG, "resetUsbData opId:" + operationId);
|
||||
Log.i(TAG, "resetUsbPort 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;
|
||||
}
|
||||
new UsbOperationInternal(operationId, mId, executor, consumer);
|
||||
mUsbManager.resetUsbPort(this, operationId, opCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -508,7 +508,7 @@ public class UsbPortManager {
|
||||
*
|
||||
* @param portId port identifier.
|
||||
*/
|
||||
public boolean resetUsbPort(@NonNull String portId, int transactionId,
|
||||
public void resetUsbPort(@NonNull String portId, int transactionId,
|
||||
@NonNull IUsbOperationInternal callback, IndentingPrintWriter pw) {
|
||||
synchronized (mLock) {
|
||||
Objects.requireNonNull(callback);
|
||||
@ -525,12 +525,11 @@ public class UsbPortManager {
|
||||
"resetUsbPort: Failed to call OperationComplete. opId:"
|
||||
+ transactionId, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
return mUsbPortHal.resetUsbPort(portId, transactionId, callback);
|
||||
mUsbPortHal.resetUsbPort(portId, transactionId, callback);
|
||||
} catch (Exception e) {
|
||||
logAndPrintException(pw,
|
||||
"reseetUsbPort: Failed to resetUsbPort. opId:"
|
||||
@ -542,7 +541,6 @@ public class UsbPortManager {
|
||||
"resetUsbPort: Failed to call onOperationComplete. opId:"
|
||||
+ transactionId, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,7 +685,7 @@ public class UsbService extends IUsbManager.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetUsbPort(String portId, int operationId,
|
||||
public void resetUsbPort(String portId, int operationId,
|
||||
IUsbOperationInternal callback) {
|
||||
Objects.requireNonNull(portId, "resetUsbPort: portId must not be null. opId:"
|
||||
+ operationId);
|
||||
@ -694,13 +694,11 @@ public class UsbService extends IUsbManager.Stub {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
boolean wait;
|
||||
|
||||
try {
|
||||
if (mPortManager != null) {
|
||||
wait = mPortManager.resetUsbPort(portId, operationId, callback, null);
|
||||
mPortManager.resetUsbPort(portId, operationId, callback, null);
|
||||
} else {
|
||||
wait = false;
|
||||
try {
|
||||
callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
|
||||
} catch (RemoteException e) {
|
||||
@ -710,7 +708,6 @@ public class UsbService extends IUsbManager.Stub {
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
return wait;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -274,7 +274,7 @@ public final class UsbPortAidl implements UsbPortHal {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetUsbPort(String portName, long operationID,
|
||||
public void resetUsbPort(String portName, long operationID,
|
||||
IUsbOperationInternal callback) {
|
||||
Objects.requireNonNull(portName);
|
||||
Objects.requireNonNull(callback);
|
||||
@ -286,7 +286,6 @@ public final class UsbPortAidl implements UsbPortHal {
|
||||
"resetUsbPort: Proxy is null. Retry !opID:"
|
||||
+ operationID);
|
||||
callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
|
||||
return false;
|
||||
}
|
||||
while (sCallbacks.get(key) != null) {
|
||||
key = ThreadLocalRandom.current().nextInt();
|
||||
@ -304,16 +303,13 @@ public final class UsbPortAidl implements UsbPortHal {
|
||||
+ portName + "opId:" + operationID, e);
|
||||
callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
|
||||
sCallbacks.remove(key);
|
||||
return false;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
logAndPrintException(mPw,
|
||||
"resetUsbPort: Failed to call onOperationComplete portID="
|
||||
+ portName + "opID:" + operationID, e);
|
||||
sCallbacks.remove(key);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,9 +202,7 @@ public interface UsbPortHal {
|
||||
* implementation as needed.
|
||||
* @param callback callback object to be invoked to invoke the status of the operation upon
|
||||
* completion.
|
||||
* @param callback callback object to be invoked to invoke the status of the operation upon
|
||||
* completion.
|
||||
*/
|
||||
public boolean resetUsbPort(String portName, long transactionId,
|
||||
public void resetUsbPort(String portName, long transactionId,
|
||||
IUsbOperationInternal callback);
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ public final class UsbPortHidl implements UsbPortHal {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetUsbPort(String portName, long transactionId,
|
||||
public void resetUsbPort(String portName, long transactionId,
|
||||
IUsbOperationInternal callback) {
|
||||
try {
|
||||
callback.onOperationComplete(USB_OPERATION_ERROR_NOT_SUPPORTED);
|
||||
@ -327,7 +327,6 @@ public final class UsbPortHidl implements UsbPortHal {
|
||||
+ transactionId
|
||||
+ " portId:" + portName, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user