public class WifiRttManager {
method public boolean isAvailable();
- method public void startRanging(android.net.wifi.rtt.RangingRequest, android.net.wifi.rtt.RangingResultCallback, android.os.Handler);
+ method public void startRanging(android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback);
field public static final java.lang.String ACTION_WIFI_RTT_STATE_CHANGED = "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
}
public class WifiRttManager {
method public void cancelRanging(android.os.WorkSource);
- method public void startRanging(android.os.WorkSource, android.net.wifi.rtt.RangingRequest, android.net.wifi.rtt.RangingResultCallback, android.os.Handler);
+ method public void startRanging(android.os.WorkSource, android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback);
}
}
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.RangingResultCallback;
import android.net.wifi.rtt.WifiRttManager;
-import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
* Request to start an RTT ranging
* <p>
* This method is deprecated. Please use the
- * {@link WifiRttManager#startRanging(RangingRequest, RangingResultCallback, Handler)} API.
+ * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}
+ * API.
*
* @param params -- RTT request Parameters
* @param listener -- Call back to inform RTT result
android.net.wifi.rtt.ResponderConfig.fromScanResult(reconstructed));
}
try {
- mNewService.startRanging(builder.build(), new RangingResultCallback() {
+ mNewService.startRanging(builder.build(),
+ mContext.getMainExecutor(),
+ new RangingResultCallback() {
@Override
public void onRangingFailure(int code) {
int localCode = REASON_UNSPECIFIED;
}
listener.onSuccess(legacyResults);
}
- }, null);
+ });
} catch (IllegalArgumentException e) {
Log.e(TAG, "startRanging: invalid arguments - " + e);
listener.onFailure(REASON_INVALID_REQUEST, e.getMessage());
public static final int CMD_OP_REG_BINDER = BASE + 9;
private final WifiRttManager mNewService;
+ private final Context mContext;
private RttCapabilities mRttCapabilities;
/**
*/
public RttManager(Context context, WifiRttManager service) {
mNewService = service;
+ mContext = context;
boolean rttSupported = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_RTT);
* Defines the ranging request to other devices. The ranging request is built using
* {@link RangingRequest.Builder}.
* A ranging request is executed using
- * {@link WifiRttManager#startRanging(RangingRequest, RangingResultCallback, Handler)}.
+ * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
* <p>
* The ranging request is a batch request - specifying a set of devices (specified using
* {@link RangingRequest.Builder#addAccessPoint(ScanResult)} and
/**
* Ranging result for a request started by
- * {@link WifiRttManager#startRanging(RangingRequest, RangingResultCallback, Handler)}. Results are
- * returned in {@link RangingResultCallback#onRangingResults(List)}.
+ * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
+ * Results are returned in {@link RangingResultCallback#onRangingResults(List)}.
* <p>
* A ranging result is the distance measurement result for a single device specified in the
* {@link RangingRequest}.
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.os.Handler;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Base class for ranging result callbacks. Should be extended by applications and set when calling
- * {@link WifiRttManager#startRanging(RangingRequest, RangingResultCallback, Handler)}. If the
- * ranging operation fails in whole (not attempted) then {@link #onRangingFailure(int)} will be
- * called with a failure code. If the ranging operation is performed for each of the requested
- * peers then the {@link #onRangingResults(List)} will be called with the set of results (@link
- * {@link RangingResult}, each of which has its own success/failure code
+ * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}.
+ * If the ranging operation fails in whole (not attempted) then {@link #onRangingFailure(int)}
+ * will be called with a failure code. If the ranging operation is performed for each of the
+ * requested peers then the {@link #onRangingResults(List)} will be called with the set of
+ * results (@link {@link RangingResult}, each of which has its own success/failure code
* {@link RangingResult#getStatus()}.
*/
public abstract class RangingResultCallback {
import static android.Manifest.permission.CHANGE_WIFI_STATE;
import static android.Manifest.permission.LOCATION_HARDWARE;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* This class provides the primary API for measuring distance (range) to other devices using the
* <li>Wi-Fi Aware peers
* <p>
* Ranging requests are triggered using
- * {@link #startRanging(RangingRequest, RangingResultCallback, Handler)}. Results (in case of
+ * {@link #startRanging(RangingRequest, Executor, RangingResultCallback)}. Results (in case of
* successful operation) are returned in the {@link RangingResultCallback#onRangingResults(List)}
* callback.
* <p>
*
* @param request A request specifying a set of devices whose distance measurements are
* requested.
+ * @param executor The Executor on which to run the callback.
* @param callback A callback for the result of the ranging request.
- * @param handler The Handler on whose thread to execute the callbacks of the {@code
- * callback} object. If a null is provided then the application's main thread
- * will be used.
*/
@RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, CHANGE_WIFI_STATE, ACCESS_WIFI_STATE})
public void startRanging(@NonNull RangingRequest request,
- @NonNull RangingResultCallback callback, @Nullable Handler handler) {
- startRanging(null, request, callback, handler);
+ @NonNull @CallbackExecutor Executor executor, @NonNull RangingResultCallback callback) {
+ startRanging(null, request, executor, callback);
}
/**
* @param workSource A mechanism to specify an alternative work-source for the request.
* @param request A request specifying a set of devices whose distance measurements are
* requested.
+ * @param executor The Executor on which to run the callback.
* @param callback A callback for the result of the ranging request.
- * @param handler The Handler on whose thread to execute the callbacks of the {@code
- * callback} object. If a null is provided then the application's main thread
- * will be used.
*
* @hide
*/
@RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_COARSE_LOCATION, CHANGE_WIFI_STATE,
ACCESS_WIFI_STATE})
public void startRanging(@Nullable WorkSource workSource, @NonNull RangingRequest request,
- @NonNull RangingResultCallback callback, @Nullable Handler handler) {
+ @NonNull @CallbackExecutor Executor executor, @NonNull RangingResultCallback callback) {
if (VDBG) {
Log.v(TAG, "startRanging: workSource=" + workSource + ", request=" + request
- + ", callback=" + callback + ", handler=" + handler);
+ + ", callback=" + callback + ", executor=" + executor);
}
+ if (executor == null) {
+ throw new IllegalArgumentException("Null executor provided");
+ }
if (callback == null) {
throw new IllegalArgumentException("Null callback provided");
}
- Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper();
Binder binder = new Binder();
try {
mService.startRanging(binder, mContext.getOpPackageName(), workSource, request,
- new RttCallbackProxy(looper, callback));
+ new IRttCallback.Stub() {
+ @Override
+ public void onRangingFailure(int status) throws RemoteException {
+ clearCallingIdentity();
+ executor.execute(() -> callback.onRangingFailure(status));
+ }
+
+ @Override
+ public void onRangingResults(List<RangingResult> results)
+ throws RemoteException {
+ clearCallingIdentity();
+ executor.execute(() -> callback.onRangingResults(results));
+ }
+ });
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
/**
* Cancel all ranging requests for the specified work sources. The requests have been requested
- * using {@link #startRanging(WorkSource, RangingRequest, RangingResultCallback, Handler)}.
+ * using {@link #startRanging(WorkSource, RangingRequest, Executor, RangingResultCallback)}.
*
* @param workSource The work-sources of the requesters.
*
throw e.rethrowFromSystemServer();
}
}
-
- private static class RttCallbackProxy extends IRttCallback.Stub {
- private final Handler mHandler;
- private final RangingResultCallback mCallback;
-
- RttCallbackProxy(Looper looper, RangingResultCallback callback) {
- mHandler = new Handler(looper);
- mCallback = callback;
- }
-
- @Override
- public void onRangingFailure(int status) throws RemoteException {
- if (VDBG) Log.v(TAG, "RttCallbackProxy: onRangingFailure: status=" + status);
- mHandler.post(() -> {
- mCallback.onRangingFailure(status);
- });
- }
-
- @Override
- public void onRangingResults(List<RangingResult> results) throws RemoteException {
- if (VDBG) Log.v(TAG, "RttCallbackProxy: onRanginResults: results=" + results);
- mHandler.post(() -> {
- mCallback.onRangingResults(results);
- });
- }
- }
}
import android.net.MacAddress;
import android.net.wifi.ScanResult;
import android.net.wifi.aware.PeerHandle;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.test.TestLooper;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Unit test harness for WifiRttManager class.
public class WifiRttManagerTest {
private WifiRttManager mDut;
private TestLooper mMockLooper;
- private Handler mMockLooperHandler;
+ private Executor mMockLooperExecutor;
private final String packageName = "some.package.name.for.rtt.app";
mDut = new WifiRttManager(mockContext, mockRttService);
mMockLooper = new TestLooper();
- mMockLooperHandler = new Handler(mMockLooper.getLooper());
+ mMockLooperExecutor = mMockLooper.getNewExecutor();
when(mockContext.getOpPackageName()).thenReturn(packageName);
}
ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
// verify ranging request passed to service
- mDut.startRanging(request, callbackMock, mMockLooperHandler);
+ mDut.startRanging(request, mMockLooperExecutor, callbackMock);
verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null),
eq(request), callbackCaptor.capture());
ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
// verify ranging request passed to service
- mDut.startRanging(request, callbackMock, mMockLooperHandler);
+ mDut.startRanging(request, mMockLooperExecutor, callbackMock);
verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null),
eq(request), callbackCaptor.capture());