Merge "Add control functions to RangingSession" am: 022ba65d34
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1532667 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Ib0277c191acd5ed2b27f850b57e1d4cb4b6966c4
This commit is contained in:
@@ -119,41 +119,95 @@ interface IUwbAdapter {
|
||||
PersistableBundle getSpecificationInfo();
|
||||
|
||||
/**
|
||||
* Request to start a new ranging session
|
||||
* Request to open a new ranging session
|
||||
*
|
||||
* This function must return before calling IUwbAdapterCallbacks
|
||||
* #onRangingStarted, #onRangingClosed, or #onRangingResult.
|
||||
* This function must return before calling any functions in
|
||||
* IUwbAdapterCallbacks.
|
||||
*
|
||||
* A ranging session does not need to be started before returning.
|
||||
* This function does not start the ranging session, but all necessary
|
||||
* components must be initialized and ready to start a new ranging
|
||||
* session prior to calling IUwbAdapterCallback#onRangingOpened.
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingStarted must be called within
|
||||
* RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being called
|
||||
* if the ranging session is scheduled to start successfully.
|
||||
* IUwbAdapterCallbacks#onRangingOpened must be called within
|
||||
* RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being
|
||||
* called if the ranging session is opened successfully.
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingStartFailed must be called within
|
||||
* RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being called
|
||||
* if the ranging session fails to be scheduled to start successfully.
|
||||
* IUwbAdapterCallbacks#onRangingOpenFailed must be called within
|
||||
* RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called
|
||||
* if the ranging session fails to be opened.
|
||||
*
|
||||
* @param rangingCallbacks the callbacks used to deliver ranging information
|
||||
* @param parameters the configuration to use for ranging
|
||||
* @return a SessionHandle used to identify this ranging request
|
||||
*/
|
||||
SessionHandle startRanging(in IUwbRangingCallbacks rangingCallbacks,
|
||||
in PersistableBundle parameters);
|
||||
SessionHandle openRanging(in IUwbRangingCallbacks rangingCallbacks,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Stop and close ranging for the session associated with the given handle
|
||||
* Request to start ranging
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingStarted must be called within
|
||||
* RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being
|
||||
* called if the ranging session starts successfully.
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingStartFailed must be called within
|
||||
* RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being
|
||||
* called if the ranging session fails to be started.
|
||||
*
|
||||
* @param sessionHandle the session handle to start ranging for
|
||||
* @param parameters additional configuration required to start ranging
|
||||
*/
|
||||
void startRanging(in SessionHandle sessionHandle,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Request to reconfigure ranging
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingReconfigured must be called after
|
||||
* successfully reconfiguring the session.
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingReconfigureFailed must be called after
|
||||
* failing to reconfigure the session.
|
||||
*
|
||||
* A session must not be modified by a failed call to #reconfigureRanging.
|
||||
*
|
||||
* @param sessionHandle the session handle to start ranging for
|
||||
* @param parameters the parameters to reconfigure and their new values
|
||||
*/
|
||||
void reconfigureRanging(in SessionHandle sessionHandle,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Request to stop ranging
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingStopped must be called after
|
||||
* successfully stopping the session.
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingStopFailed must be called after failing
|
||||
* to stop the session.
|
||||
*
|
||||
* @param sessionHandle the session handle to stop ranging for
|
||||
*/
|
||||
void stopRanging(in SessionHandle sessionHandle);
|
||||
|
||||
/**
|
||||
* Close ranging for the session associated with the given handle
|
||||
*
|
||||
* Calling with an invalid handle or a handle that has already been closed
|
||||
* is a no-op.
|
||||
*
|
||||
* IUwbAdapterCallbacks#onRangingClosed must be called within
|
||||
* RANGING_SESSION_CLOSE_THRESHOLD_MS of #stopRanging being called.
|
||||
* RANGING_SESSION_CLOSE_THRESHOLD_MS of #closeRanging being called.
|
||||
*
|
||||
* @param sessionHandle the session handle to stop ranging for
|
||||
* @param sessionHandle the session handle to close ranging for
|
||||
*/
|
||||
void closeRanging(in SessionHandle sessionHandle);
|
||||
|
||||
/**
|
||||
* The maximum allowed time to open a ranging session.
|
||||
*/
|
||||
const int RANGING_SESSION_OPEN_THRESHOLD_MS = 3000; // Value TBD
|
||||
|
||||
/**
|
||||
* The maximum allowed time to start a ranging session.
|
||||
*/
|
||||
|
||||
@@ -17,15 +17,32 @@
|
||||
package android.uwb;
|
||||
|
||||
import android.os.PersistableBundle;
|
||||
import android.uwb.CloseReason;
|
||||
import android.uwb.RangingChangeReason;
|
||||
import android.uwb.RangingReport;
|
||||
import android.uwb.SessionHandle;
|
||||
import android.uwb.StartFailureReason;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
interface IUwbRangingCallbacks {
|
||||
/**
|
||||
* Called when the ranging session has been opened
|
||||
*
|
||||
* @param sessionHandle the session the callback is being invoked for
|
||||
*/
|
||||
void onRangingOpened(in SessionHandle sessionHandle);
|
||||
|
||||
/**
|
||||
* Called when a ranging session fails to start
|
||||
*
|
||||
* @param sessionHandle the session the callback is being invoked for
|
||||
* @param reason the reason the session failed to start
|
||||
* @param parameters protocol specific parameters
|
||||
*/
|
||||
void onRangingOpenFailed(in SessionHandle sessionHandle,
|
||||
RangingChangeReason reason,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Called when ranging has started
|
||||
*
|
||||
@@ -47,8 +64,49 @@ interface IUwbRangingCallbacks {
|
||||
* @param reason the reason the session failed to start
|
||||
* @param parameters protocol specific parameters
|
||||
*/
|
||||
void onRangingStartFailed(in SessionHandle sessionHandle, StartFailureReason reason,
|
||||
void onRangingStartFailed(in SessionHandle sessionHandle,
|
||||
RangingChangeReason reason,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Called when ranging has been reconfigured
|
||||
*
|
||||
* @param sessionHandle the session the callback is being invoked for
|
||||
* @param parameters the updated ranging configuration
|
||||
*/
|
||||
void onRangingReconfigured(in SessionHandle sessionHandle,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Called when a ranging session fails to be reconfigured
|
||||
*
|
||||
* @param sessionHandle the session the callback is being invoked for
|
||||
* @param reason the reason the session failed to reconfigure
|
||||
* @param parameters protocol specific parameters
|
||||
*/
|
||||
void onRangingReconfigureFailed(in SessionHandle sessionHandle,
|
||||
RangingChangeReason reason,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Called when the ranging session has been stopped
|
||||
*
|
||||
* @param sessionHandle the session the callback is being invoked for
|
||||
*/
|
||||
|
||||
void onRangingStopped(in SessionHandle sessionHandle);
|
||||
|
||||
/**
|
||||
* Called when a ranging session fails to stop
|
||||
*
|
||||
* @param sessionHandle the session the callback is being invoked for
|
||||
* @param reason the reason the session failed to stop
|
||||
* @param parameters protocol specific parameters
|
||||
*/
|
||||
void onRangingStopFailed(in SessionHandle sessionHandle,
|
||||
RangingChangeReason reason,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Called when a ranging session is closed
|
||||
*
|
||||
@@ -56,7 +114,8 @@ interface IUwbRangingCallbacks {
|
||||
* @param reason the reason the session was closed
|
||||
* @param parameters protocol specific parameters
|
||||
*/
|
||||
void onRangingClosed(in SessionHandle sessionHandle, CloseReason reason,
|
||||
void onRangingClosed(in SessionHandle sessionHandle,
|
||||
RangingChangeReason reason,
|
||||
in PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,39 +20,44 @@ package android.uwb;
|
||||
* @hide
|
||||
*/
|
||||
@Backing(type="int")
|
||||
enum CloseReason {
|
||||
enum RangingChangeReason {
|
||||
/**
|
||||
* Unknown reason
|
||||
*/
|
||||
UNKNOWN,
|
||||
|
||||
/**
|
||||
* A local API call triggered the close, such as a call to
|
||||
* IUwbAdapter.stopRanging.
|
||||
* A local API call triggered the change, such as a call to
|
||||
* IUwbAdapter.closeRanging.
|
||||
*/
|
||||
LOCAL_API,
|
||||
|
||||
/**
|
||||
* The maximum number of sessions has been reached. This error may be generated
|
||||
* for an active session if a higher priority session begins.
|
||||
* The maximum number of sessions has been reached. This may be generated for
|
||||
* an active session if a higher priority session begins.
|
||||
*/
|
||||
MAX_SESSIONS_REACHED,
|
||||
|
||||
/**
|
||||
* The system state has changed resulting in the session ending (e.g. the user
|
||||
* disables UWB, or the user's locale changes and an active channel is no longer
|
||||
* permitted to be used).
|
||||
* The system state has changed resulting in the session changing (e.g. the
|
||||
* user disables UWB, or the user's locale changes and an active channel is no
|
||||
* longer permitted to be used).
|
||||
*/
|
||||
SYSTEM_POLICY,
|
||||
|
||||
/**
|
||||
* The remote device has requested to terminate the session
|
||||
* The remote device has requested to change the session
|
||||
*/
|
||||
REMOTE_REQUEST,
|
||||
|
||||
/**
|
||||
* The session was closed for a protocol specific reason
|
||||
* The session changed for a protocol specific reason
|
||||
*/
|
||||
PROTOCOL_SPECIFIC,
|
||||
|
||||
/**
|
||||
* The provided parameters were invalid
|
||||
*/
|
||||
BAD_PARAMETERS,
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
@NonNull RangingSession.Callback callbacks) {
|
||||
SessionHandle sessionHandle;
|
||||
try {
|
||||
sessionHandle = mAdapter.startRanging(this, params);
|
||||
sessionHandle = mAdapter.openRanging(this, params);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
if (hasSession(sessionHandle)) {
|
||||
Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle");
|
||||
executor.execute(() -> callbacks.onClosed(
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_GENERIC_ERROR,
|
||||
RangingSession.Callback.REASON_GENERIC_ERROR,
|
||||
new PersistableBundle()));
|
||||
}
|
||||
|
||||
@@ -74,6 +74,67 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
return mRangingSessionTable.containsKey(sessionHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingOpened(SessionHandle sessionHandle) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG,
|
||||
"onRangingOpened - received unexpected SessionHandle: " + sessionHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingOpened();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingOpenFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
|
||||
PersistableBundle parameters) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG,
|
||||
"onRangingOpened - received unexpected SessionHandle: " + sessionHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingOpenFailed(convertToReason(reason), parameters);
|
||||
mRangingSessionTable.remove(sessionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingReconfigured(SessionHandle sessionHandle, PersistableBundle parameters) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG,
|
||||
"onRangingReconfigured - received unexpected SessionHandle: "
|
||||
+ sessionHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingReconfigured(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingReconfigureFailed(SessionHandle sessionHandle,
|
||||
@RangingChangeReason int reason, PersistableBundle params) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG, "onRangingStartFailed - received unexpected SessionHandle: "
|
||||
+ sessionHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingReconfigureFailed(convertToReason(reason), params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRangingStarted(SessionHandle sessionHandle, PersistableBundle parameters) {
|
||||
synchronized (this) {
|
||||
@@ -89,7 +150,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingStartFailed(SessionHandle sessionHandle, int reason,
|
||||
public void onRangingStartFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
|
||||
PersistableBundle params) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
@@ -99,13 +160,42 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingClosed(convertStartFailureToCloseReason(reason), params);
|
||||
mRangingSessionTable.remove(sessionHandle);
|
||||
session.onRangingStartFailed(convertToReason(reason), params);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingClosed(SessionHandle sessionHandle, int reason, PersistableBundle params) {
|
||||
public void onRangingStopped(SessionHandle sessionHandle) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG, "onRangingStopped - received unexpected SessionHandle: "
|
||||
+ sessionHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingStopped();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingStopFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
|
||||
PersistableBundle parameters) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG, "onRangingStopFailed - received unexpected SessionHandle: "
|
||||
+ sessionHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingStopFailed(convertToReason(reason), parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangingClosed(SessionHandle sessionHandle, @RangingChangeReason int reason,
|
||||
PersistableBundle params) {
|
||||
synchronized (this) {
|
||||
if (!hasSession(sessionHandle)) {
|
||||
Log.w(TAG, "onRangingClosed - received unexpected SessionHandle: " + sessionHandle);
|
||||
@@ -113,7 +203,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
}
|
||||
|
||||
RangingSession session = mRangingSessionTable.get(sessionHandle);
|
||||
session.onRangingClosed(convertToCloseReason(reason), params);
|
||||
session.onRangingClosed(convertToReason(reason), params);
|
||||
mRangingSessionTable.remove(sessionHandle);
|
||||
}
|
||||
}
|
||||
@@ -131,48 +221,30 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@RangingSession.Callback.CloseReason
|
||||
private static int convertToCloseReason(@CloseReason int reason) {
|
||||
@RangingSession.Callback.Reason
|
||||
private static int convertToReason(@RangingChangeReason int reason) {
|
||||
switch (reason) {
|
||||
case CloseReason.LOCAL_API:
|
||||
return RangingSession.Callback.CLOSE_REASON_LOCAL_CLOSE_API;
|
||||
case RangingChangeReason.LOCAL_API:
|
||||
return RangingSession.Callback.REASON_LOCAL_REQUEST;
|
||||
|
||||
case CloseReason.MAX_SESSIONS_REACHED:
|
||||
return RangingSession.Callback.CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED;
|
||||
case RangingChangeReason.MAX_SESSIONS_REACHED:
|
||||
return RangingSession.Callback.REASON_MAX_SESSIONS_REACHED;
|
||||
|
||||
case CloseReason.SYSTEM_POLICY:
|
||||
return RangingSession.Callback.CLOSE_REASON_LOCAL_SYSTEM_POLICY;
|
||||
case RangingChangeReason.SYSTEM_POLICY:
|
||||
return RangingSession.Callback.REASON_SYSTEM_POLICY;
|
||||
|
||||
case CloseReason.REMOTE_REQUEST:
|
||||
return RangingSession.Callback.CLOSE_REASON_REMOTE_REQUEST;
|
||||
case RangingChangeReason.REMOTE_REQUEST:
|
||||
return RangingSession.Callback.REASON_REMOTE_REQUEST;
|
||||
|
||||
case CloseReason.PROTOCOL_SPECIFIC:
|
||||
return RangingSession.Callback.CLOSE_REASON_PROTOCOL_SPECIFIC;
|
||||
case RangingChangeReason.PROTOCOL_SPECIFIC:
|
||||
return RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR;
|
||||
|
||||
case CloseReason.UNKNOWN:
|
||||
case RangingChangeReason.BAD_PARAMETERS:
|
||||
return RangingSession.Callback.REASON_BAD_PARAMETERS;
|
||||
|
||||
case RangingChangeReason.UNKNOWN:
|
||||
default:
|
||||
return RangingSession.Callback.CLOSE_REASON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@RangingSession.Callback.CloseReason
|
||||
private static int convertStartFailureToCloseReason(@StartFailureReason int reason) {
|
||||
switch (reason) {
|
||||
case StartFailureReason.BAD_PARAMETERS:
|
||||
return RangingSession.Callback.CLOSE_REASON_LOCAL_BAD_PARAMETERS;
|
||||
|
||||
case StartFailureReason.MAX_SESSIONS_REACHED:
|
||||
return RangingSession.Callback.CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED;
|
||||
|
||||
case StartFailureReason.SYSTEM_POLICY:
|
||||
return RangingSession.Callback.CLOSE_REASON_LOCAL_SYSTEM_POLICY;
|
||||
|
||||
case StartFailureReason.PROTOCOL_SPECIFIC:
|
||||
return RangingSession.Callback.CLOSE_REASON_PROTOCOL_SPECIFIC;
|
||||
|
||||
case StartFailureReason.UNKNOWN:
|
||||
default:
|
||||
return RangingSession.Callback.CLOSE_REASON_UNKNOWN;
|
||||
return RangingSession.Callback.REASON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ import java.util.concurrent.Executor;
|
||||
* <p>To get an instance of {@link RangingSession}, first use
|
||||
* {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} to request to open a
|
||||
* session. Once the session is opened, a {@link RangingSession} object is provided through
|
||||
* {@link RangingSession.Callback#onOpenSuccess(RangingSession, PersistableBundle)}. If opening a
|
||||
* session fails, the failure is reported through
|
||||
* {@link RangingSession.Callback#onClosed(int, PersistableBundle)} with the failure reason.
|
||||
* {@link RangingSession.Callback#onOpened(RangingSession)}. If opening a session fails, the failure
|
||||
* is reported through {@link RangingSession.Callback#onOpenFailed(int, PersistableBundle)} with the
|
||||
* failure reason.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -50,103 +50,162 @@ public final class RangingSession implements AutoCloseable {
|
||||
private final Callback mCallback;
|
||||
|
||||
private enum State {
|
||||
/**
|
||||
* The state of the {@link RangingSession} until
|
||||
* {@link RangingSession.Callback#onOpened(RangingSession)} is invoked
|
||||
*/
|
||||
INIT,
|
||||
OPEN,
|
||||
CLOSED,
|
||||
|
||||
/**
|
||||
* The {@link RangingSession} is initialized and ready to begin ranging
|
||||
*/
|
||||
IDLE,
|
||||
|
||||
/**
|
||||
* The {@link RangingSession} is actively ranging
|
||||
*/
|
||||
ACTIVE,
|
||||
|
||||
/**
|
||||
* The {@link RangingSession} is closed and may not be used for ranging.
|
||||
*/
|
||||
CLOSED
|
||||
}
|
||||
|
||||
private State mState;
|
||||
private State mState = State.INIT;
|
||||
|
||||
/**
|
||||
* Interface for receiving {@link RangingSession} events
|
||||
*/
|
||||
public interface Callback {
|
||||
/**
|
||||
* Invoked when {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
|
||||
* is successful
|
||||
*
|
||||
* @param session the newly opened {@link RangingSession}
|
||||
* @param sessionInfo session specific parameters from lower layers
|
||||
*/
|
||||
void onOpenSuccess(@NonNull RangingSession session, @NonNull PersistableBundle sessionInfo);
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
CLOSE_REASON_UNKNOWN,
|
||||
CLOSE_REASON_LOCAL_CLOSE_API,
|
||||
CLOSE_REASON_LOCAL_BAD_PARAMETERS,
|
||||
CLOSE_REASON_LOCAL_GENERIC_ERROR,
|
||||
CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED,
|
||||
CLOSE_REASON_LOCAL_SYSTEM_POLICY,
|
||||
CLOSE_REASON_REMOTE_GENERIC_ERROR,
|
||||
CLOSE_REASON_REMOTE_REQUEST})
|
||||
@interface CloseReason {}
|
||||
REASON_UNKNOWN,
|
||||
REASON_LOCAL_REQUEST,
|
||||
REASON_REMOTE_REQUEST,
|
||||
REASON_BAD_PARAMETERS,
|
||||
REASON_GENERIC_ERROR,
|
||||
REASON_MAX_SESSIONS_REACHED,
|
||||
REASON_SYSTEM_POLICY,
|
||||
REASON_PROTOCOL_SPECIFIC_ERROR})
|
||||
@interface Reason {}
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed or failed to open due to an unknown reason
|
||||
*/
|
||||
int CLOSE_REASON_UNKNOWN = 0;
|
||||
int REASON_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed or failed to open because
|
||||
* {@link AutoCloseable#close()} or {@link RangingSession#close()} was called
|
||||
*/
|
||||
int CLOSE_REASON_LOCAL_CLOSE_API = 1;
|
||||
|
||||
/**
|
||||
* Indicates that the session failed to open due to erroneous parameters passed
|
||||
* to {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
|
||||
*/
|
||||
int CLOSE_REASON_LOCAL_BAD_PARAMETERS = 2;
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed due to some local error on this device besides the
|
||||
* error code already listed
|
||||
*/
|
||||
int CLOSE_REASON_LOCAL_GENERIC_ERROR = 3;
|
||||
|
||||
/**
|
||||
* Indicates that the session failed to open because the number of currently open sessions
|
||||
* is equal to {@link UwbManager#getMaxSimultaneousSessions()}
|
||||
*/
|
||||
int CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED = 4;
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed or failed to open due to local system policy, such
|
||||
* as privacy policy, power management policy, permissions, and more.
|
||||
*/
|
||||
int CLOSE_REASON_LOCAL_SYSTEM_POLICY = 5;
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed or failed to open due to an error with the remote
|
||||
* device besides error codes already listed.
|
||||
*/
|
||||
int CLOSE_REASON_REMOTE_GENERIC_ERROR = 6;
|
||||
int REASON_LOCAL_REQUEST = 1;
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed or failed to open due to an explicit request from
|
||||
* the remote device.
|
||||
*/
|
||||
int CLOSE_REASON_REMOTE_REQUEST = 7;
|
||||
int REASON_REMOTE_REQUEST = 2;
|
||||
|
||||
/**
|
||||
* Indicates that the session was closed for a protocol specific reason. The associated
|
||||
* {@link PersistableBundle} should be consulted for additional information.
|
||||
* Indicates that the session was closed or failed to open due to erroneous parameters
|
||||
*/
|
||||
int CLOSE_REASON_PROTOCOL_SPECIFIC = 8;
|
||||
int REASON_BAD_PARAMETERS = 3;
|
||||
|
||||
/**
|
||||
* Indicates an error on this device besides the error code already listed
|
||||
*/
|
||||
int REASON_GENERIC_ERROR = 4;
|
||||
|
||||
/**
|
||||
* Indicates that the number of currently open sessions is equal to
|
||||
* {@link UwbManager#getMaxSimultaneousSessions()} and additional sessions may not be
|
||||
* opened.
|
||||
*/
|
||||
int REASON_MAX_SESSIONS_REACHED = 5;
|
||||
|
||||
/**
|
||||
* Indicates that the local system policy caused the change, such
|
||||
* as privacy policy, power management policy, permissions, and more.
|
||||
*/
|
||||
int REASON_SYSTEM_POLICY = 6;
|
||||
|
||||
/**
|
||||
* Indicates a protocol specific error. The associated {@link PersistableBundle} should be
|
||||
* consulted for additional information.
|
||||
*/
|
||||
int REASON_PROTOCOL_SPECIFIC_ERROR = 7;
|
||||
|
||||
/**
|
||||
* Invoked when {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
|
||||
* is successful
|
||||
*
|
||||
* @param session the newly opened {@link RangingSession}
|
||||
*/
|
||||
void onOpened(@NonNull RangingSession session);
|
||||
|
||||
/**
|
||||
* Invoked if {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}}
|
||||
* fails
|
||||
*
|
||||
* @param reason the failure reason
|
||||
* @param params protocol specific parameters
|
||||
*/
|
||||
void onOpenFailed(@Reason int reason, @NonNull PersistableBundle params);
|
||||
|
||||
/**
|
||||
* Invoked when {@link RangingSession#start(PersistableBundle)} is successful
|
||||
* @param sessionInfo session specific parameters from the lower layers
|
||||
*/
|
||||
void onStarted(@NonNull PersistableBundle sessionInfo);
|
||||
|
||||
/**
|
||||
* Invoked when {@link RangingSession#start(PersistableBundle)} fails
|
||||
*
|
||||
* @param reason the failure reason
|
||||
* @param params protocol specific parameters
|
||||
*/
|
||||
void onStartFailed(@Reason int reason, @NonNull PersistableBundle params);
|
||||
|
||||
/**
|
||||
* Invoked when a request to reconfigure the session succeeds
|
||||
*
|
||||
* @param params the updated ranging configuration
|
||||
*/
|
||||
void onReconfigured(@NonNull PersistableBundle params);
|
||||
|
||||
/**
|
||||
* Invoked when a request to reconfigure the session fails
|
||||
*
|
||||
* @param reason reason the session failed to be reconfigured
|
||||
* @param params protocol specific failure reasons
|
||||
*/
|
||||
void onReconfigureFailed(@Reason int reason, @NonNull PersistableBundle params);
|
||||
|
||||
/**
|
||||
* Invoked when a request to stop the session succeeds
|
||||
*/
|
||||
void onStopped();
|
||||
|
||||
/**
|
||||
* Invoked when a request to stop the session fails
|
||||
*
|
||||
* @param reason reason the session failed to be stopped
|
||||
* @param params protocol specific failure reasons
|
||||
*/
|
||||
void onStopFailed(@Reason int reason, @NonNull PersistableBundle params);
|
||||
|
||||
/**
|
||||
* Invoked when session is either closed spontaneously, or per user request via
|
||||
* {@link RangingSession#close()} or {@link AutoCloseable#close()}, or when session failed
|
||||
* to open.
|
||||
* {@link RangingSession#close()} or {@link AutoCloseable#close()}.
|
||||
*
|
||||
* @param reason reason for the session closure
|
||||
* @param parameters protocol specific parameters related to the close reason
|
||||
*/
|
||||
void onClosed(@CloseReason int reason, @NonNull PersistableBundle parameters);
|
||||
void onClosed(@Reason int reason, @NonNull PersistableBundle parameters);
|
||||
|
||||
/**
|
||||
* Called once per ranging interval even when a ranging measurement fails
|
||||
@@ -172,12 +231,95 @@ public final class RangingSession implements AutoCloseable {
|
||||
* @hide
|
||||
*/
|
||||
public boolean isOpen() {
|
||||
return mState == State.OPEN;
|
||||
return mState == State.IDLE || mState == State.ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins ranging for the session.
|
||||
*
|
||||
* <p>On successfully starting a ranging session,
|
||||
* {@link RangingSession.Callback#onStarted(PersistableBundle)} is invoked.
|
||||
*
|
||||
* <p>On failure to start the session,
|
||||
* {@link RangingSession.Callback#onStartFailed(int, PersistableBundle)} is invoked.
|
||||
*
|
||||
* @param params configuration parameters for starting the session
|
||||
*/
|
||||
public void start(@NonNull PersistableBundle params) {
|
||||
if (mState != State.IDLE) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
try {
|
||||
mAdapter.startRanging(mSessionHandle, params);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to reconfigure the session with the given parameters
|
||||
* <p>This call may be made when the session is open.
|
||||
*
|
||||
* <p>On successfully reconfiguring the session
|
||||
* {@link RangingSession.Callback#onReconfigured(PersistableBundle)} is invoked.
|
||||
*
|
||||
* <p>On failure to reconfigure the session,
|
||||
* {@link RangingSession.Callback#onReconfigureFailed(int, PersistableBundle)} is invoked.
|
||||
*
|
||||
* @param params the parameters to reconfigure and their new values
|
||||
*/
|
||||
public void reconfigure(@NonNull PersistableBundle params) {
|
||||
if (mState != State.ACTIVE && mState != State.IDLE) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
try {
|
||||
mAdapter.reconfigureRanging(mSessionHandle, params);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops actively ranging
|
||||
*
|
||||
* <p>A session that has been stopped may be resumed by calling
|
||||
* {@link RangingSession#start(PersistableBundle)} without the need to open a new session.
|
||||
*
|
||||
* <p>Stopping a {@link RangingSession} is useful when the lower layers should not discard
|
||||
* the parameters of the session, or when a session needs to be able to be resumed quickly.
|
||||
*
|
||||
* <p>If the {@link RangingSession} is no longer needed, use {@link RangingSession#close()} to
|
||||
* completely close the session and allow lower layers of the stack to perform necessarily
|
||||
* cleanup.
|
||||
*
|
||||
* <p>Stopped sessions may be closed by the system at any time. In such a case,
|
||||
* {@link RangingSession.Callback#onClosed(int, PersistableBundle)} is invoked.
|
||||
*
|
||||
* <p>On failure to stop the session,
|
||||
* {@link RangingSession.Callback#onStopFailed(int, PersistableBundle)} is invoked.
|
||||
*/
|
||||
public void stop() {
|
||||
if (mState != State.ACTIVE) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
try {
|
||||
mAdapter.stopRanging(mSessionHandle);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the ranging session
|
||||
* <p>If this session is currently open, it will close and stop the session.
|
||||
*
|
||||
* <p>After calling this function, in order resume ranging, a new {@link RangingSession} must
|
||||
* be opened by calling
|
||||
* {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}.
|
||||
*
|
||||
* <p>If this session is currently ranging, it will stop and close the session.
|
||||
* <p>If the session is in the process of being opened, it will attempt to stop the session from
|
||||
* being opened.
|
||||
* <p>If the session is already closed, the registered
|
||||
@@ -192,7 +334,7 @@ public final class RangingSession implements AutoCloseable {
|
||||
public void close() {
|
||||
if (mState == State.CLOSED) {
|
||||
mExecutor.execute(() -> mCallback.onClosed(
|
||||
Callback.CLOSE_REASON_LOCAL_CLOSE_API, new PersistableBundle()));
|
||||
Callback.REASON_LOCAL_REQUEST, new PersistableBundle()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,6 +345,33 @@ public final class RangingSession implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingOpened() {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingOpened invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
mState = State.IDLE;
|
||||
executeCallback(() -> mCallback.onOpened(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingOpenFailed(@Callback.Reason int reason,
|
||||
@NonNull PersistableBundle params) {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingOpenFailed invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
mState = State.CLOSED;
|
||||
executeCallback(() -> mCallback.onOpenFailed(reason, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -212,26 +381,81 @@ public final class RangingSession implements AutoCloseable {
|
||||
return;
|
||||
}
|
||||
|
||||
mState = State.OPEN;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() -> mCallback.onOpenSuccess(this, parameters));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
mState = State.ACTIVE;
|
||||
executeCallback(() -> mCallback.onStarted(parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingClosed(@Callback.CloseReason int reason, PersistableBundle parameters) {
|
||||
mState = State.CLOSED;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() -> mCallback.onClosed(reason, parameters));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
public void onRangingStartFailed(@Callback.Reason int reason,
|
||||
@NonNull PersistableBundle params) {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingStartFailed invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
executeCallback(() -> mCallback.onStartFailed(reason, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingReconfigured(@NonNull PersistableBundle params) {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingReconfigured invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
executeCallback(() -> mCallback.onReconfigured(params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingReconfigureFailed(@Callback.Reason int reason,
|
||||
@NonNull PersistableBundle params) {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingReconfigureFailed invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
executeCallback(() -> mCallback.onReconfigureFailed(reason, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingStopped() {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingStopped invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
mState = State.IDLE;
|
||||
executeCallback(() -> mCallback.onStopped());
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingStopFailed(@Callback.Reason int reason,
|
||||
@NonNull PersistableBundle params) {
|
||||
if (mState == State.CLOSED) {
|
||||
Log.w(TAG, "onRangingStopFailed invoked for a closed session");
|
||||
return;
|
||||
}
|
||||
|
||||
executeCallback(() -> mCallback.onStopFailed(reason, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onRangingClosed(@Callback.Reason int reason,
|
||||
@NonNull PersistableBundle parameters) {
|
||||
mState = State.CLOSED;
|
||||
executeCallback(() -> mCallback.onClosed(reason, parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,9 +467,16 @@ public final class RangingSession implements AutoCloseable {
|
||||
return;
|
||||
}
|
||||
|
||||
executeCallback(() -> mCallback.onReportReceived(report));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
private void executeCallback(@NonNull Runnable runnable) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() -> mCallback.onReportReceived(report));
|
||||
mExecutor.execute(runnable);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.uwb;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Backing(type="int")
|
||||
enum StartFailureReason {
|
||||
/**
|
||||
* Unknown start failure reason
|
||||
*/
|
||||
UNKNOWN,
|
||||
|
||||
/**
|
||||
* The provided parameters were invalid and ranging could not start
|
||||
*/
|
||||
BAD_PARAMETERS,
|
||||
|
||||
/**
|
||||
* The maximum number of sessions has been reached. This error may be generated
|
||||
* for an active session if a higher priority session begins.
|
||||
*/
|
||||
MAX_SESSIONS_REACHED,
|
||||
|
||||
/**
|
||||
* The system state has changed resulting in the session ending (e.g. the user
|
||||
* disables UWB, or the user's locale changes and an active channel is no longer
|
||||
* permitted to be used).
|
||||
*/
|
||||
SYSTEM_POLICY,
|
||||
|
||||
/**
|
||||
* The session could not start because of a protocol specific reason.
|
||||
*/
|
||||
PROTOCOL_SPECIFIC,
|
||||
}
|
||||
|
||||
@@ -369,13 +369,13 @@ public final class UwbManager {
|
||||
|
||||
/**
|
||||
* Open a {@link RangingSession} with the given parameters
|
||||
* <p>This function is asynchronous and will return before ranging begins. The
|
||||
* {@link RangingSession.Callback#onOpenSuccess(RangingSession, PersistableBundle)} function is
|
||||
* called with a {@link RangingSession} object used to control ranging when the session is
|
||||
* successfully opened.
|
||||
* <p>The {@link RangingSession.Callback#onOpened(RangingSession)} function is called with a
|
||||
* {@link RangingSession} object used to control ranging when the session is successfully
|
||||
* opened.
|
||||
*
|
||||
* <p>If a session cannot be opened, then {@link RangingSession.Callback#onClosed(int)} will be
|
||||
* invoked with the appropriate {@link RangingSession.Callback.CloseReason}.
|
||||
* <p>If a session cannot be opened, then
|
||||
* {@link RangingSession.Callback#onClosed(int, PersistableBundle)} will be invoked with the
|
||||
* appropriate {@link RangingSession.Callback.Reason}.
|
||||
*
|
||||
* <p>An open {@link RangingSession} will be automatically closed if client application process
|
||||
* dies.
|
||||
@@ -391,7 +391,7 @@ public final class UwbManager {
|
||||
* @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a
|
||||
* {@link RangingSession} that has been requested through {@link #openRangingSession}
|
||||
* but has not yet been made available by
|
||||
* {@link RangingSession.Callback#onOpenSuccess}.
|
||||
* {@link RangingSession.Callback#onOpened(RangingSession)}.
|
||||
*/
|
||||
@NonNull
|
||||
public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
|
||||
|
||||
@@ -45,14 +45,14 @@ public class RangingManagerTest {
|
||||
private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class);
|
||||
private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
|
||||
private static final PersistableBundle PARAMS = new PersistableBundle();
|
||||
private static final @CloseReason int CLOSE_REASON = CloseReason.UNKNOWN;
|
||||
private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
|
||||
|
||||
@Test
|
||||
public void testOpenSession_StartRangingInvoked() throws RemoteException {
|
||||
public void testOpenSession_OpenRangingInvoked() throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
verify(ADAPTER, times(1)).startRanging(eq(rangingManager), eq(PARAMS));
|
||||
verify(ADAPTER, times(1)).openRanging(eq(rangingManager), eq(PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,7 +60,7 @@ public class RangingManagerTest {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
SessionHandle handle = new SessionHandle(1);
|
||||
when(ADAPTER.startRanging(any(), any())).thenReturn(handle);
|
||||
when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
|
||||
@@ -73,34 +73,34 @@ public class RangingManagerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingStarted_ValidSessionHandle() throws RemoteException {
|
||||
public void testOnRangingOpened_ValidSessionHandle() throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
SessionHandle handle = new SessionHandle(1);
|
||||
when(ADAPTER.startRanging(any(), any())).thenReturn(handle);
|
||||
when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.onRangingStarted(handle, PARAMS);
|
||||
verify(callback, times(1)).onOpenSuccess(any(), any());
|
||||
rangingManager.onRangingOpened(handle);
|
||||
verify(callback, times(1)).onOpened(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingStarted_InvalidSessionHandle() throws RemoteException {
|
||||
public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
|
||||
rangingManager.onRangingStarted(new SessionHandle(2), PARAMS);
|
||||
verify(callback, times(0)).onOpenSuccess(any(), any());
|
||||
rangingManager.onRangingOpened(new SessionHandle(2));
|
||||
verify(callback, times(0)).onOpened(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingStarted_MultipleSessionsRegistered() throws RemoteException {
|
||||
public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException {
|
||||
SessionHandle sessionHandle1 = new SessionHandle(1);
|
||||
SessionHandle sessionHandle2 = new SessionHandle(2);
|
||||
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
|
||||
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
|
||||
|
||||
when(ADAPTER.startRanging(any(), any()))
|
||||
when(ADAPTER.openRanging(any(), any()))
|
||||
.thenReturn(sessionHandle1)
|
||||
.thenReturn(sessionHandle2);
|
||||
|
||||
@@ -108,25 +108,50 @@ public class RangingManagerTest {
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
|
||||
|
||||
rangingManager.onRangingStarted(sessionHandle1, PARAMS);
|
||||
verify(callback1, times(1)).onOpenSuccess(any(), any());
|
||||
verify(callback2, times(0)).onOpenSuccess(any(), any());
|
||||
rangingManager.onRangingOpened(sessionHandle1);
|
||||
verify(callback1, times(1)).onOpened(any());
|
||||
verify(callback2, times(0)).onOpened(any());
|
||||
|
||||
rangingManager.onRangingStarted(sessionHandle2, PARAMS);
|
||||
verify(callback1, times(1)).onOpenSuccess(any(), any());
|
||||
verify(callback2, times(1)).onOpenSuccess(any(), any());
|
||||
rangingManager.onRangingOpened(sessionHandle2);
|
||||
verify(callback1, times(1)).onOpened(any());
|
||||
verify(callback2, times(1)).onOpened(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingClosed_OnRangingClosedCalled() throws RemoteException {
|
||||
public void testCorrectCallbackInvoked() throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
SessionHandle handle = new SessionHandle(1);
|
||||
when(ADAPTER.startRanging(any(), any())).thenReturn(handle);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
|
||||
|
||||
rangingManager.onRangingClosed(handle, CLOSE_REASON, PARAMS);
|
||||
verify(callback, times(1)).onClosed(anyInt(), any());
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.onRangingOpened(handle);
|
||||
verify(callback, times(1)).onOpened(any());
|
||||
|
||||
rangingManager.onRangingStarted(handle, PARAMS);
|
||||
verify(callback, times(1)).onStarted(eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingStartFailed(handle, REASON, PARAMS);
|
||||
verify(callback, times(1)).onStartFailed(eq(REASON), eq(PARAMS));
|
||||
|
||||
RangingReport report = UwbTestUtils.getRangingReports(1);
|
||||
rangingManager.onRangingResult(handle, report);
|
||||
verify(callback, times(1)).onReportReceived(eq(report));
|
||||
|
||||
rangingManager.onRangingReconfigured(handle, PARAMS);
|
||||
verify(callback, times(1)).onReconfigured(eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingReconfigureFailed(handle, REASON, PARAMS);
|
||||
verify(callback, times(1)).onReconfigureFailed(eq(REASON), eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingStopped(handle);
|
||||
verify(callback, times(1)).onStopped();
|
||||
|
||||
rangingManager.onRangingStopFailed(handle, REASON, PARAMS);
|
||||
verify(callback, times(1)).onStopFailed(eq(REASON), eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingClosed(handle, REASON, PARAMS);
|
||||
verify(callback, times(1)).onClosed(eq(REASON), eq(PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,7 +163,7 @@ public class RangingManagerTest {
|
||||
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
|
||||
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
|
||||
|
||||
when(ADAPTER.startRanging(any(), any()))
|
||||
when(ADAPTER.openRanging(any(), any()))
|
||||
.thenReturn(sessionHandle1)
|
||||
.thenReturn(sessionHandle2);
|
||||
|
||||
@@ -146,29 +171,15 @@ public class RangingManagerTest {
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
|
||||
|
||||
rangingManager.onRangingClosed(sessionHandle1, CLOSE_REASON, PARAMS);
|
||||
rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS);
|
||||
verify(callback1, times(1)).onClosed(anyInt(), any());
|
||||
verify(callback2, times(0)).onClosed(anyInt(), any());
|
||||
|
||||
rangingManager.onRangingClosed(sessionHandle2, CLOSE_REASON, PARAMS);
|
||||
rangingManager.onRangingClosed(sessionHandle2, REASON, PARAMS);
|
||||
verify(callback1, times(1)).onClosed(anyInt(), any());
|
||||
verify(callback2, times(1)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingReport_OnReportReceived() throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
SessionHandle handle = new SessionHandle(1);
|
||||
when(ADAPTER.startRanging(any(), any())).thenReturn(handle);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.onRangingStarted(handle, PARAMS);
|
||||
|
||||
RangingReport report = UwbTestUtils.getRangingReports(1);
|
||||
rangingManager.onRangingResult(handle, report);
|
||||
verify(callback, times(1)).onReportReceived(eq(report));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException {
|
||||
SessionHandle sessionHandle1 = new SessionHandle(1);
|
||||
@@ -176,7 +187,7 @@ public class RangingManagerTest {
|
||||
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
|
||||
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
|
||||
|
||||
when(ADAPTER.startRanging(any(), any()))
|
||||
when(ADAPTER.openRanging(any(), any()))
|
||||
.thenReturn(sessionHandle1)
|
||||
.thenReturn(sessionHandle2);
|
||||
|
||||
@@ -196,65 +207,54 @@ public class RangingManagerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClose_Reasons() throws RemoteException {
|
||||
runOnClose_Reason(CloseReason.LOCAL_API,
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_CLOSE_API);
|
||||
public void testReasons() throws RemoteException {
|
||||
runReason(RangingChangeReason.LOCAL_API,
|
||||
RangingSession.Callback.REASON_LOCAL_REQUEST);
|
||||
|
||||
runOnClose_Reason(CloseReason.MAX_SESSIONS_REACHED,
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED);
|
||||
runReason(RangingChangeReason.MAX_SESSIONS_REACHED,
|
||||
RangingSession.Callback.REASON_MAX_SESSIONS_REACHED);
|
||||
|
||||
runOnClose_Reason(CloseReason.PROTOCOL_SPECIFIC,
|
||||
RangingSession.Callback.CLOSE_REASON_PROTOCOL_SPECIFIC);
|
||||
runReason(RangingChangeReason.PROTOCOL_SPECIFIC,
|
||||
RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR);
|
||||
|
||||
runOnClose_Reason(CloseReason.REMOTE_REQUEST,
|
||||
RangingSession.Callback.CLOSE_REASON_REMOTE_REQUEST);
|
||||
runReason(RangingChangeReason.REMOTE_REQUEST,
|
||||
RangingSession.Callback.REASON_REMOTE_REQUEST);
|
||||
|
||||
runOnClose_Reason(CloseReason.SYSTEM_POLICY,
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_SYSTEM_POLICY);
|
||||
runReason(RangingChangeReason.SYSTEM_POLICY,
|
||||
RangingSession.Callback.REASON_SYSTEM_POLICY);
|
||||
|
||||
runOnClose_Reason(CloseReason.UNKNOWN,
|
||||
RangingSession.Callback.CLOSE_REASON_UNKNOWN);
|
||||
runReason(RangingChangeReason.BAD_PARAMETERS,
|
||||
RangingSession.Callback.REASON_BAD_PARAMETERS);
|
||||
|
||||
runReason(RangingChangeReason.UNKNOWN,
|
||||
RangingSession.Callback.REASON_UNKNOWN);
|
||||
}
|
||||
|
||||
private void runOnClose_Reason(@CloseReason int reasonIn,
|
||||
@RangingSession.Callback.CloseReason int reasonOut) throws RemoteException {
|
||||
private void runReason(@RangingChangeReason int reasonIn,
|
||||
@RangingSession.Callback.Reason int reasonOut) throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
SessionHandle handle = new SessionHandle(1);
|
||||
when(ADAPTER.startRanging(any(), any())).thenReturn(handle);
|
||||
when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
|
||||
rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS);
|
||||
verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
|
||||
|
||||
// Open a new session
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.onRangingOpened(handle);
|
||||
|
||||
rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
|
||||
verify(callback, times(1)).onStartFailed(eq(reasonOut), eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingReconfigureFailed(handle, reasonIn, PARAMS);
|
||||
verify(callback, times(1)).onReconfigureFailed(eq(reasonOut), eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingStopFailed(handle, reasonIn, PARAMS);
|
||||
verify(callback, times(1)).onStopFailed(eq(reasonOut), eq(PARAMS));
|
||||
|
||||
rangingManager.onRangingClosed(handle, reasonIn, PARAMS);
|
||||
verify(callback, times(1)).onClosed(eq(reasonOut), eq(PARAMS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartFailureReasons() throws RemoteException {
|
||||
runOnRangingStartFailed_Reason(StartFailureReason.BAD_PARAMETERS,
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_BAD_PARAMETERS);
|
||||
|
||||
runOnRangingStartFailed_Reason(StartFailureReason.MAX_SESSIONS_REACHED,
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED);
|
||||
|
||||
runOnRangingStartFailed_Reason(StartFailureReason.PROTOCOL_SPECIFIC,
|
||||
RangingSession.Callback.CLOSE_REASON_PROTOCOL_SPECIFIC);
|
||||
|
||||
runOnRangingStartFailed_Reason(StartFailureReason.SYSTEM_POLICY,
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_SYSTEM_POLICY);
|
||||
|
||||
runOnRangingStartFailed_Reason(StartFailureReason.UNKNOWN,
|
||||
RangingSession.Callback.CLOSE_REASON_UNKNOWN);
|
||||
}
|
||||
|
||||
private void runOnRangingStartFailed_Reason(@StartFailureReason int reasonIn,
|
||||
@RangingSession.Callback.CloseReason int reasonOut) throws RemoteException {
|
||||
RangingManager rangingManager = new RangingManager(ADAPTER);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
SessionHandle handle = new SessionHandle(1);
|
||||
when(ADAPTER.startRanging(any(), any())).thenReturn(handle);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
|
||||
rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
|
||||
verify(callback, times(1)).onClosed(eq(reasonOut), eq(PARAMS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@ package android.uwb;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -34,6 +36,8 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -43,47 +47,48 @@ import java.util.concurrent.Executor;
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class RangingSessionTest {
|
||||
private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class);
|
||||
private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
|
||||
private static final PersistableBundle PARAMS = new PersistableBundle();
|
||||
private static final @RangingSession.Callback.CloseReason int CLOSE_REASON =
|
||||
RangingSession.Callback.CLOSE_REASON_LOCAL_GENERIC_ERROR;
|
||||
private static final @RangingSession.Callback.Reason int REASON =
|
||||
RangingSession.Callback.REASON_GENERIC_ERROR;
|
||||
|
||||
@Test
|
||||
public void testOnRangingStarted_OnOpenSuccessCalled() {
|
||||
public void testOnRangingOpened_OnOpenSuccessCalled() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
verifyOpenState(session, false);
|
||||
|
||||
session.onRangingStarted(PARAMS);
|
||||
session.onRangingOpened();
|
||||
verifyOpenState(session, true);
|
||||
|
||||
// Verify that the onOpenSuccess callback was invoked
|
||||
verify(callback, times(1)).onOpenSuccess(eq(session), any());
|
||||
verify(callback, times(1)).onOpened(eq(session));
|
||||
verify(callback, times(0)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingStarted_CannotOpenClosedSession() {
|
||||
public void testOnRangingOpened_CannotOpenClosedSession() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
|
||||
session.onRangingStarted(PARAMS);
|
||||
session.onRangingOpened();
|
||||
verifyOpenState(session, true);
|
||||
verify(callback, times(1)).onOpenSuccess(eq(session), any());
|
||||
verify(callback, times(1)).onOpened(eq(session));
|
||||
verify(callback, times(0)).onClosed(anyInt(), any());
|
||||
|
||||
session.onRangingClosed(CLOSE_REASON, PARAMS);
|
||||
session.onRangingClosed(REASON, PARAMS);
|
||||
verifyOpenState(session, false);
|
||||
verify(callback, times(1)).onOpenSuccess(eq(session), any());
|
||||
verify(callback, times(1)).onOpened(eq(session));
|
||||
verify(callback, times(1)).onClosed(anyInt(), any());
|
||||
|
||||
// Now invoke the ranging started callback and ensure the session remains closed
|
||||
session.onRangingStarted(PARAMS);
|
||||
session.onRangingOpened();
|
||||
verifyOpenState(session, false);
|
||||
verify(callback, times(1)).onOpenSuccess(eq(session), any());
|
||||
verify(callback, times(1)).onOpened(eq(session));
|
||||
verify(callback, times(1)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@@ -91,27 +96,30 @@ public class RangingSessionTest {
|
||||
public void testOnRangingClosed_OnClosedCalledWhenSessionNotOpen() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
verifyOpenState(session, false);
|
||||
|
||||
session.onRangingClosed(CLOSE_REASON, PARAMS);
|
||||
session.onRangingClosed(REASON, PARAMS);
|
||||
verifyOpenState(session, false);
|
||||
|
||||
// Verify that the onOpenSuccess callback was invoked
|
||||
verify(callback, times(0)).onOpenSuccess(eq(session), any());
|
||||
verify(callback, times(0)).onOpened(eq(session));
|
||||
verify(callback, times(1)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test public void testOnRangingClosed_OnClosedCalled() {
|
||||
@Test
|
||||
public void testOnRangingClosed_OnClosedCalled() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
session.onRangingStarted(PARAMS);
|
||||
session.onRangingClosed(CLOSE_REASON, PARAMS);
|
||||
session.onRangingClosed(REASON, PARAMS);
|
||||
verify(callback, times(1)).onClosed(anyInt(), any());
|
||||
|
||||
verifyOpenState(session, false);
|
||||
session.onRangingClosed(CLOSE_REASON, PARAMS);
|
||||
session.onRangingClosed(REASON, PARAMS);
|
||||
verify(callback, times(2)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@@ -119,7 +127,8 @@ public class RangingSessionTest {
|
||||
public void testOnRangingResult_OnReportReceivedCalled() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
verifyOpenState(session, false);
|
||||
|
||||
session.onRangingStarted(PARAMS);
|
||||
@@ -131,11 +140,83 @@ public class RangingSessionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose() throws RemoteException {
|
||||
public void testStart_CannotStartIfAlreadyStarted() throws RemoteException {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any());
|
||||
session.onRangingOpened();
|
||||
|
||||
session.start(PARAMS);
|
||||
verify(callback, times(1)).onStarted(any());
|
||||
|
||||
// Calling start again should throw an illegal state
|
||||
verifyThrowIllegalState(() -> session.start(PARAMS));
|
||||
verify(callback, times(1)).onStarted(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStop_CannotStopIfAlreadyStopped() throws RemoteException {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any());
|
||||
doAnswer(new StopAnswer(session)).when(adapter).stopRanging(any());
|
||||
session.onRangingOpened();
|
||||
session.start(PARAMS);
|
||||
|
||||
verifyNoThrowIllegalState(session::stop);
|
||||
verify(callback, times(1)).onStopped();
|
||||
|
||||
// Calling stop again should throw an illegal state
|
||||
verifyThrowIllegalState(session::stop);
|
||||
verify(callback, times(1)).onStopped();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconfigure_OnlyWhenOpened() throws RemoteException {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any());
|
||||
doAnswer(new ReconfigureAnswer(session)).when(adapter).reconfigureRanging(any(), any());
|
||||
|
||||
verifyThrowIllegalState(() -> session.reconfigure(PARAMS));
|
||||
verify(callback, times(0)).onReconfigured(any());
|
||||
verifyOpenState(session, false);
|
||||
|
||||
session.onRangingOpened();
|
||||
verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS));
|
||||
verify(callback, times(1)).onReconfigured(any());
|
||||
verifyOpenState(session, true);
|
||||
|
||||
session.onRangingStarted(PARAMS);
|
||||
verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS));
|
||||
verify(callback, times(2)).onReconfigured(any());
|
||||
verifyOpenState(session, true);
|
||||
|
||||
session.onRangingStopped();
|
||||
verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS));
|
||||
verify(callback, times(3)).onReconfigured(any());
|
||||
verifyOpenState(session, true);
|
||||
|
||||
|
||||
session.onRangingClosed(REASON, PARAMS);
|
||||
verifyThrowIllegalState(() -> session.reconfigure(PARAMS));
|
||||
verify(callback, times(3)).onReconfigured(any());
|
||||
verifyOpenState(session, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose_NoCallbackUntilInvoked() throws RemoteException {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
session.onRangingOpened();
|
||||
|
||||
// Calling close multiple times should invoke closeRanging until the session receives
|
||||
// the onClosed callback.
|
||||
@@ -143,7 +224,7 @@ public class RangingSessionTest {
|
||||
for (int i = 1; i <= totalCallsBeforeOnRangingClosed; i++) {
|
||||
session.close();
|
||||
verifyOpenState(session, true);
|
||||
verify(ADAPTER, times(i)).closeRanging(handle);
|
||||
verify(adapter, times(i)).closeRanging(handle);
|
||||
verify(callback, times(0)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@@ -151,18 +232,47 @@ public class RangingSessionTest {
|
||||
// the session's close.
|
||||
final int totalCallsAfterOnRangingClosed = 2;
|
||||
for (int i = 1; i <= totalCallsAfterOnRangingClosed; i++) {
|
||||
session.onRangingClosed(CLOSE_REASON, PARAMS);
|
||||
session.onRangingClosed(REASON, PARAMS);
|
||||
verifyOpenState(session, false);
|
||||
verify(ADAPTER, times(totalCallsBeforeOnRangingClosed)).closeRanging(handle);
|
||||
verify(adapter, times(totalCallsBeforeOnRangingClosed)).closeRanging(handle);
|
||||
verify(callback, times(i)).onClosed(anyInt(), any());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose_OnClosedCalled() throws RemoteException {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any());
|
||||
session.onRangingOpened();
|
||||
|
||||
session.close();
|
||||
verify(callback, times(1)).onClosed(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose_CannotInteractFurther() throws RemoteException {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any());
|
||||
session.close();
|
||||
|
||||
verifyThrowIllegalState(() -> session.start(PARAMS));
|
||||
verifyThrowIllegalState(() -> session.reconfigure(PARAMS));
|
||||
verifyThrowIllegalState(() -> session.stop());
|
||||
verifyNoThrowIllegalState(() -> session.close());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRangingResult_OnReportReceivedCalledWhenOpen() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
|
||||
assertFalse(session.isOpen());
|
||||
session.onRangingStarted(PARAMS);
|
||||
@@ -178,7 +288,8 @@ public class RangingSessionTest {
|
||||
public void testOnRangingResult_OnReportReceivedNotCalledWhenNotOpen() {
|
||||
SessionHandle handle = new SessionHandle(123);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, ADAPTER, handle);
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
|
||||
|
||||
assertFalse(session.isOpen());
|
||||
|
||||
@@ -191,4 +302,77 @@ public class RangingSessionTest {
|
||||
private void verifyOpenState(RangingSession session, boolean expected) {
|
||||
assertEquals(expected, session.isOpen());
|
||||
}
|
||||
|
||||
private void verifyThrowIllegalState(Runnable runnable) {
|
||||
try {
|
||||
runnable.run();
|
||||
fail();
|
||||
} catch (IllegalStateException e) {
|
||||
// Pass
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyNoThrowIllegalState(Runnable runnable) {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (IllegalStateException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AdapterAnswer implements Answer {
|
||||
protected RangingSession mSession;
|
||||
|
||||
protected AdapterAnswer(RangingSession session) {
|
||||
mSession = session;
|
||||
}
|
||||
}
|
||||
|
||||
class StartAnswer extends AdapterAnswer {
|
||||
StartAnswer(RangingSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
mSession.onRangingStarted(PARAMS);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ReconfigureAnswer extends AdapterAnswer {
|
||||
ReconfigureAnswer(RangingSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
mSession.onRangingReconfigured(PARAMS);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class StopAnswer extends AdapterAnswer {
|
||||
StopAnswer(RangingSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
mSession.onRangingStopped();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class CloseAnswer extends AdapterAnswer {
|
||||
CloseAnswer(RangingSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
mSession.onRangingClosed(REASON, PARAMS);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user