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:
Roshan Pius
2021-04-01 11:14:15 -07:00
parent 9d350e3a06
commit a88aa31269
5 changed files with 44 additions and 24 deletions

View File

@@ -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);
}

View File

@@ -722,7 +722,7 @@ public final class SystemServiceRegistry {
new CachedServiceFetcher<UwbManager>() {
@Override
public UwbManager createService(ContextImpl ctx) {
return UwbManager.getInstance();
return UwbManager.getInstance(ctx);
}
});

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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);