UwbManager: Use AttributionSource for runtime permission enforcement
This attribution source is going to be used by Gmscore to proxy the blame for uwb_ranging runtime permission check (since Gmscore which is the direct caller of this surface is in most cases proxying the request from 1p/3p apps). Note: This CL just adds the skeletal API to start the API reviews. The actual implementation needs a major refactor of the stack which is WIP. Bug: 183904955 Test: atest android.uwb Change-Id: Ia0338b573306f44c493bf1c136e68b4f46877816
This commit is contained in:
@@ -14237,7 +14237,7 @@ package android.uwb {
|
||||
public final class UwbManager {
|
||||
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
|
||||
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.UWB_PRIVILEGED, android.Manifest.permission.UWB_RANGING}) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
|
||||
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
|
||||
}
|
||||
|
||||
@@ -722,7 +722,7 @@ public final class SystemServiceRegistry {
|
||||
new CachedServiceFetcher<UwbManager>() {
|
||||
@Override
|
||||
public UwbManager createService(ContextImpl ctx) {
|
||||
return UwbManager.getInstance();
|
||||
return UwbManager.getInstance(ctx);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.uwb;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.AttributionSource;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
@@ -42,6 +43,9 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
/**
|
||||
* Open a new ranging session
|
||||
*
|
||||
* @param attributionSource Attribution source to use for the enforcement of
|
||||
* {@link android.Manifest.permission#ULTRAWIDEBAND_RANGING} runtime
|
||||
* permission.
|
||||
* @param params the parameters that define the ranging session
|
||||
* @param executor {@link Executor} to run callbacks
|
||||
* @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
|
||||
@@ -49,7 +53,8 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
* @return a {@link CancellationSignal} that may be used to cancel the opening of the
|
||||
* {@link RangingSession}.
|
||||
*/
|
||||
public CancellationSignal openSession(@NonNull PersistableBundle params,
|
||||
public CancellationSignal openSession(@NonNull AttributionSource attributionSource,
|
||||
@NonNull PersistableBundle params,
|
||||
@NonNull Executor executor,
|
||||
@NonNull RangingSession.Callback callbacks) {
|
||||
synchronized (this) {
|
||||
@@ -58,6 +63,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
|
||||
new RangingSession(executor, callbacks, mAdapter, sessionHandle);
|
||||
mRangingSessionTable.put(sessionHandle, session);
|
||||
try {
|
||||
// TODO: Pass in the attributionSource to the service.
|
||||
mAdapter.openRanging(sessionHandle, this, params);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package android.uwb;
|
||||
|
||||
import android.Manifest;
|
||||
import android.Manifest.permission;
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
@@ -24,7 +24,9 @@ import android.annotation.RequiresPermission;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.AttributionSource;
|
||||
import android.content.Context;
|
||||
import android.content.ContextParams;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.IBinder;
|
||||
import android.os.PersistableBundle;
|
||||
@@ -47,9 +49,10 @@ import java.util.concurrent.Executor;
|
||||
@SystemApi
|
||||
@SystemService(Context.UWB_SERVICE)
|
||||
public final class UwbManager {
|
||||
private IUwbAdapter mUwbAdapter;
|
||||
private static final String SERVICE_NAME = "uwb";
|
||||
|
||||
private final Context mContext;
|
||||
private final IUwbAdapter mUwbAdapter;
|
||||
private final AdapterStateListener mAdapterStateListener;
|
||||
private final RangingManager mRangingManager;
|
||||
|
||||
@@ -116,9 +119,11 @@ public final class UwbManager {
|
||||
/**
|
||||
* Use <code>Context.getSystemService(UwbManager.class)</code> to get an instance.
|
||||
*
|
||||
* @param ctx Context of the client.
|
||||
* @param adapter an instance of an {@link android.uwb.IUwbAdapter}
|
||||
*/
|
||||
private UwbManager(IUwbAdapter adapter) {
|
||||
private UwbManager(@NonNull Context ctx, @NonNull IUwbAdapter adapter) {
|
||||
mContext = ctx;
|
||||
mUwbAdapter = adapter;
|
||||
mAdapterStateListener = new AdapterStateListener(adapter);
|
||||
mRangingManager = new RangingManager(adapter);
|
||||
@@ -127,7 +132,7 @@ public final class UwbManager {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static UwbManager getInstance() {
|
||||
public static UwbManager getInstance(@NonNull Context ctx) {
|
||||
IBinder b = ServiceManager.getService(SERVICE_NAME);
|
||||
if (b == null) {
|
||||
return null;
|
||||
@@ -138,7 +143,7 @@ public final class UwbManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new UwbManager(adapter);
|
||||
return new UwbManager(ctx, adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +158,7 @@ public final class UwbManager {
|
||||
* @param executor an {@link Executor} to execute given callback
|
||||
* @param callback user implementation of the {@link AdapterStateCallback}
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
|
||||
@RequiresPermission(permission.UWB_PRIVILEGED)
|
||||
public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull AdapterStateCallback callback) {
|
||||
mAdapterStateListener.register(executor, callback);
|
||||
@@ -168,7 +173,7 @@ public final class UwbManager {
|
||||
*
|
||||
* @param callback user implementation of the {@link AdapterStateCallback}
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
|
||||
@RequiresPermission(permission.UWB_PRIVILEGED)
|
||||
public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
|
||||
mAdapterStateListener.unregister(callback);
|
||||
}
|
||||
@@ -182,7 +187,7 @@ public final class UwbManager {
|
||||
* @return {@link PersistableBundle} of the device's supported UWB protocols and parameters
|
||||
*/
|
||||
@NonNull
|
||||
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
|
||||
@RequiresPermission(permission.UWB_PRIVILEGED)
|
||||
public PersistableBundle getSpecificationInfo() {
|
||||
try {
|
||||
return mUwbAdapter.getSpecificationInfo();
|
||||
@@ -199,7 +204,7 @@ public final class UwbManager {
|
||||
* @return the timestamp resolution in nanoseconds
|
||||
*/
|
||||
@SuppressLint("MethodNameUnits")
|
||||
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
|
||||
@RequiresPermission(permission.UWB_PRIVILEGED)
|
||||
public long elapsedRealtimeResolutionNanos() {
|
||||
try {
|
||||
return mUwbAdapter.getTimestampResolutionNanos();
|
||||
@@ -235,10 +240,14 @@ public final class UwbManager {
|
||||
* {@link RangingSession.Callback#onOpened(RangingSession)}.
|
||||
*/
|
||||
@NonNull
|
||||
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
|
||||
@RequiresPermission(allOf = {
|
||||
permission.UWB_PRIVILEGED,
|
||||
permission.UWB_RANGING
|
||||
})
|
||||
public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull RangingSession.Callback callbacks) {
|
||||
return mRangingManager.openSession(parameters, executor, callbacks);
|
||||
return mRangingManager.openSession(
|
||||
mContext.getAttributionSource(), parameters, executor, callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.AttributionSource;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
@@ -45,13 +46,17 @@ public class RangingManagerTest {
|
||||
private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
|
||||
private static final PersistableBundle PARAMS = new PersistableBundle();
|
||||
private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
|
||||
private static final int UID = 343453;
|
||||
private static final String PACKAGE_NAME = "com.uwb.test";
|
||||
private static final AttributionSource ATTRIBUTION_SOURCE =
|
||||
new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build();
|
||||
|
||||
@Test
|
||||
public void testOpenSession_OpenRangingInvoked() throws RemoteException {
|
||||
IUwbAdapter adapter = mock(IUwbAdapter.class);
|
||||
RangingManager rangingManager = new RangingManager(adapter);
|
||||
RangingSession.Callback callback = mock(RangingSession.Callback.class);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
|
||||
verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS));
|
||||
}
|
||||
|
||||
@@ -74,11 +79,11 @@ public class RangingManagerTest {
|
||||
ArgumentCaptor.forClass(SessionHandle.class);
|
||||
|
||||
RangingManager rangingManager = new RangingManager(adapter);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1);
|
||||
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2);
|
||||
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
|
||||
|
||||
@@ -100,7 +105,7 @@ public class RangingManagerTest {
|
||||
ArgumentCaptor<SessionHandle> sessionHandleCaptor =
|
||||
ArgumentCaptor.forClass(SessionHandle.class);
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
|
||||
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle handle = sessionHandleCaptor.getValue();
|
||||
|
||||
@@ -145,11 +150,11 @@ public class RangingManagerTest {
|
||||
ArgumentCaptor<SessionHandle> sessionHandleCaptor =
|
||||
ArgumentCaptor.forClass(SessionHandle.class);
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1);
|
||||
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2);
|
||||
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
|
||||
|
||||
@@ -172,12 +177,12 @@ public class RangingManagerTest {
|
||||
ArgumentCaptor.forClass(SessionHandle.class);
|
||||
|
||||
RangingManager rangingManager = new RangingManager(adapter);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1);
|
||||
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
|
||||
|
||||
rangingManager.onRangingStarted(sessionHandle1, PARAMS);
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2);
|
||||
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
|
||||
rangingManager.onRangingStarted(sessionHandle2, PARAMS);
|
||||
@@ -224,7 +229,7 @@ public class RangingManagerTest {
|
||||
ArgumentCaptor<SessionHandle> sessionHandleCaptor =
|
||||
ArgumentCaptor.forClass(SessionHandle.class);
|
||||
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
|
||||
verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
SessionHandle handle = sessionHandleCaptor.getValue();
|
||||
|
||||
@@ -232,7 +237,7 @@ public class RangingManagerTest {
|
||||
verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
|
||||
|
||||
// Open a new session
|
||||
rangingManager.openSession(PARAMS, EXECUTOR, callback);
|
||||
rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback);
|
||||
verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
|
||||
handle = sessionHandleCaptor.getValue();
|
||||
rangingManager.onRangingOpened(handle);
|
||||
|
||||
Reference in New Issue
Block a user