Merge "Add OWNERS for BatteryService"
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1984ddc..acce0a8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6409,12 +6409,12 @@
package android.net.vcn {
public class VcnManager {
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+ method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
- method public void removeVcnNetworkPolicyListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+ method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
}
- public static interface VcnManager.VcnNetworkPolicyListener {
+ public static interface VcnManager.VcnNetworkPolicyChangeListener {
method public void onPolicyChanged();
}
@@ -12300,6 +12300,7 @@
package android.uwb {
public final class AngleMeasurement implements android.os.Parcelable {
+ ctor public AngleMeasurement(double, double, double);
method public int describeContents();
method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians();
@@ -12308,14 +12309,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleMeasurement> CREATOR;
}
- public static final class AngleMeasurement.Builder {
- ctor public AngleMeasurement.Builder();
- method @NonNull public android.uwb.AngleMeasurement build();
- method @NonNull public android.uwb.AngleMeasurement.Builder setConfidenceLevel(double);
- method @NonNull public android.uwb.AngleMeasurement.Builder setErrorRadians(double);
- method @NonNull public android.uwb.AngleMeasurement.Builder setRadians(double);
- }
-
public final class AngleOfArrivalMeasurement implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.uwb.AngleMeasurement getAltitude();
@@ -12325,10 +12318,9 @@
}
public static final class AngleOfArrivalMeasurement.Builder {
- ctor public AngleOfArrivalMeasurement.Builder();
+ ctor public AngleOfArrivalMeasurement.Builder(@NonNull android.uwb.AngleMeasurement);
method @NonNull public android.uwb.AngleOfArrivalMeasurement build();
method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement);
- method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAzimuth(@NonNull android.uwb.AngleMeasurement);
}
public final class DistanceMeasurement implements android.os.Parcelable {
@@ -12428,7 +12420,7 @@
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 AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
+ 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 @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);
}
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index 8ebf757..062438c 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -73,7 +73,8 @@
public class VcnManager {
@NonNull private static final String TAG = VcnManager.class.getSimpleName();
- private static final Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+ private static final Map<
+ VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
@NonNull private final Context mContext;
@@ -93,13 +94,13 @@
}
/**
- * Get all currently registered VcnNetworkPolicyListeners for testing purposes.
+ * Get all currently registered VcnNetworkPolicyChangeListeners for testing purposes.
*
* @hide
*/
@VisibleForTesting(visibility = Visibility.PRIVATE)
@NonNull
- public static Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+ public static Map<VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
getAllPolicyListeners() {
return Collections.unmodifiableMap(REGISTERED_POLICY_LISTENERS);
}
@@ -162,14 +163,14 @@
}
// TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using
- // the new VcnNetworkPolicyListener API
+ // the new VcnNetworkPolicyChangeListener API
/**
* VcnUnderlyingNetworkPolicyListener is the interface through which internal system components
* can register to receive updates for VCN-underlying Network policies from the System Server.
*
* @hide
*/
- public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyListener {}
+ public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyChangeListener {}
/**
* Add a listener for VCN-underlying network policy updates.
@@ -185,7 +186,7 @@
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
public void addVcnUnderlyingNetworkPolicyListener(
@NonNull Executor executor, @NonNull VcnUnderlyingNetworkPolicyListener listener) {
- addVcnNetworkPolicyListener(executor, listener);
+ addVcnNetworkPolicyChangeListener(executor, listener);
}
/**
@@ -198,7 +199,7 @@
*/
public void removeVcnUnderlyingNetworkPolicyListener(
@NonNull VcnUnderlyingNetworkPolicyListener listener) {
- removeVcnNetworkPolicyListener(listener);
+ removeVcnNetworkPolicyChangeListener(listener);
}
/**
@@ -233,20 +234,20 @@
}
/**
- * VcnNetworkPolicyListener is the interface through which internal system components (e.g.
- * Network Factories) can register to receive updates for VCN-underlying Network policies from
- * the System Server.
+ * VcnNetworkPolicyChangeListener is the interface through which internal system components
+ * (e.g. Network Factories) can register to receive updates for VCN-underlying Network policies
+ * from the System Server.
*
* <p>Any Network Factory that brings up Networks capable of being VCN-underlying Networks
- * should register a VcnNetworkPolicyListener. VcnManager will then use this listener to notify
- * the registrant when VCN Network policies change. Upon receiving this signal, the listener
- * must check {@link VcnManager} for the current Network policy result for each of its Networks
- * via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
+ * should register a VcnNetworkPolicyChangeListener. VcnManager will then use this listener to
+ * notify the registrant when VCN Network policies change. Upon receiving this signal, the
+ * listener must check {@link VcnManager} for the current Network policy result for each of its
+ * Networks via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
*
* @hide
*/
@SystemApi
- public interface VcnNetworkPolicyListener {
+ public interface VcnNetworkPolicyChangeListener {
/**
* Notifies the implementation that the VCN's underlying Network policy has changed.
*
@@ -260,20 +261,21 @@
/**
* Add a listener for VCN-underlying Network policy updates.
*
- * <p>A {@link VcnNetworkPolicyListener} is eligible to begin receiving callbacks once it is
- * registered. No callbacks are guaranteed upon registration.
+ * <p>A {@link VcnNetworkPolicyChangeListener} is eligible to begin receiving callbacks once it
+ * is registered. No callbacks are guaranteed upon registration.
*
* @param executor the Executor that will be used for invoking all calls to the specified
* Listener
- * @param listener the VcnNetworkPolicyListener to be added
+ * @param listener the VcnNetworkPolicyChangeListener to be added
* @throws SecurityException if the caller does not have permission NETWORK_FACTORY
- * @throws IllegalStateException if the specified VcnNetworkPolicyListener is already registered
+ * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already
+ * registered
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public void addVcnNetworkPolicyListener(
- @NonNull Executor executor, @NonNull VcnNetworkPolicyListener listener) {
+ public void addVcnNetworkPolicyChangeListener(
+ @NonNull Executor executor, @NonNull VcnNetworkPolicyChangeListener listener) {
requireNonNull(executor, "executor must not be null");
requireNonNull(listener, "listener must not be null");
@@ -292,15 +294,18 @@
}
/**
- * Remove the specified VcnNetworkPolicyListener from VcnManager.
+ * Remove the specified VcnNetworkPolicyChangeListener from VcnManager.
*
* <p>If the specified listener is not currently registered, this is a no-op.
*
- * @param listener the VcnNetworkPolicyListener that will be removed
+ * @param listener the VcnNetworkPolicyChangeListener that will be removed
+ * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
* @hide
*/
@SystemApi
- public void removeVcnNetworkPolicyListener(@NonNull VcnNetworkPolicyListener listener) {
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public void removeVcnNetworkPolicyChangeListener(
+ @NonNull VcnNetworkPolicyChangeListener listener) {
requireNonNull(listener, "listener must not be null");
VcnUnderlyingNetworkPolicyListenerBinder binder =
@@ -320,8 +325,9 @@
* Applies the network policy for a {@link android.net.Network} with the given parameters.
*
* <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy
- * may have changed via {@link VcnNetworkPolicyListener#onPolicyChanged()}, a Network Provider
- * MUST poll for the updated Network policy based on that Network's capabilities and properties.
+ * may have changed via {@link VcnNetworkPolicyChangeListener#onPolicyChanged()}, a Network
+ * Provider MUST poll for the updated Network policy based on that Network's capabilities and
+ * properties.
*
* @param networkCapabilities the NetworkCapabilities to be used in determining the Network
* policy result for this Network.
@@ -532,17 +538,18 @@
}
/**
- * Binder wrapper for added VcnNetworkPolicyListeners to receive signals from System Server.
+ * Binder wrapper for added VcnNetworkPolicyChangeListeners to receive signals from System
+ * Server.
*
* @hide
*/
private static class VcnUnderlyingNetworkPolicyListenerBinder
extends IVcnUnderlyingNetworkPolicyListener.Stub {
@NonNull private final Executor mExecutor;
- @NonNull private final VcnNetworkPolicyListener mListener;
+ @NonNull private final VcnNetworkPolicyChangeListener mListener;
private VcnUnderlyingNetworkPolicyListenerBinder(
- Executor executor, VcnNetworkPolicyListener listener) {
+ Executor executor, VcnNetworkPolicyChangeListener listener) {
mExecutor = executor;
mListener = listener;
}
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index 9df213b..8c771ba 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -38,9 +38,30 @@
private final double mErrorRadians;
private final double mConfidenceLevel;
- private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+ /**
+ * Constructs a new {@link AngleMeasurement} object
+ *
+ * @param radians the angle in radians
+ * @param errorRadians the error of the angle measurement in radians
+ * @param confidenceLevel confidence level of the angle measurement
+ *
+ * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of
+ * allowed range
+ */
+ public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+ if (radians < -Math.PI || radians > Math.PI) {
+ throw new IllegalArgumentException("Invalid radians: " + radians);
+ }
mRadians = radians;
+
+ if (errorRadians < 0.0 || errorRadians > Math.PI) {
+ throw new IllegalArgumentException("Invalid error radians: " + errorRadians);
+ }
mErrorRadians = errorRadians;
+
+ if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
+ throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel);
+ }
mConfidenceLevel = confidenceLevel;
}
@@ -122,11 +143,7 @@
new Creator<AngleMeasurement>() {
@Override
public AngleMeasurement createFromParcel(Parcel in) {
- Builder builder = new Builder();
- builder.setRadians(in.readDouble());
- builder.setErrorRadians(in.readDouble());
- builder.setConfidenceLevel(in.readDouble());
- return builder.build();
+ return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble());
}
@Override
@@ -134,82 +151,4 @@
return new AngleMeasurement[size];
}
};
-
- /**
- * Builder class for {@link AngleMeasurement}.
- */
- public static final class Builder {
- private double mRadians = Double.NaN;
- private double mErrorRadians = Double.NaN;
- private double mConfidenceLevel = Double.NaN;
-
- /**
- * Set the angle in radians
- *
- * @param radians angle in radians
- * @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI]
- */
- @NonNull
- public Builder setRadians(double radians) {
- if (radians < -Math.PI || radians > Math.PI) {
- throw new IllegalArgumentException("Invalid radians: " + radians);
- }
- mRadians = radians;
- return this;
- }
-
- /**
- * Set the angle error in radians
- *
- * @param errorRadians error of the angle in radians
- * @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI]
- */
- @NonNull
- public Builder setErrorRadians(double errorRadians) {
- if (errorRadians < 0.0 || errorRadians > Math.PI) {
- throw new IllegalArgumentException(
- "Invalid error radians: " + errorRadians);
- }
- mErrorRadians = errorRadians;
- return this;
- }
-
- /**
- * Set the angle confidence level
- *
- * @param confidenceLevel level of confidence of the angle measurement
- * @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0]
- */
- @NonNull
- public Builder setConfidenceLevel(double confidenceLevel) {
- if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
- throw new IllegalArgumentException(
- "Invalid confidence level: " + confidenceLevel);
- }
- mConfidenceLevel = confidenceLevel;
- return this;
- }
-
- /**
- * Build the {@link AngleMeasurement} object
- *
- * @throws IllegalStateException if angle, error, or confidence values are missing
- */
- @NonNull
- public AngleMeasurement build() {
- if (Double.isNaN(mRadians)) {
- throw new IllegalStateException("Angle is not set");
- }
-
- if (Double.isNaN(mErrorRadians)) {
- throw new IllegalStateException("Angle error is not set");
- }
-
- if (Double.isNaN(mConfidenceLevel)) {
- throw new IllegalStateException("Angle confidence level is not set");
- }
-
- return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel);
- }
- }
}
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index 3d8626b..db04ad1 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -116,9 +116,8 @@
new Creator<AngleOfArrivalMeasurement>() {
@Override
public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
- Builder builder = new Builder();
-
- builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader()));
+ Builder builder =
+ new Builder(in.readParcelable(AngleMeasurement.class.getClassLoader()));
builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader()));
@@ -135,18 +134,16 @@
* Builder class for {@link AngleOfArrivalMeasurement}.
*/
public static final class Builder {
- private AngleMeasurement mAzimuthAngleMeasurement = null;
+ private final AngleMeasurement mAzimuthAngleMeasurement;
private AngleMeasurement mAltitudeAngleMeasurement = null;
/**
- * Set the azimuth angle
+ * Constructs an {@link AngleOfArrivalMeasurement} object
*
- * @param azimuthAngle azimuth angle
+ * @param azimuthAngle the azimuth angle of the measurement
*/
- @NonNull
- public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) {
+ public Builder(@NonNull AngleMeasurement azimuthAngle) {
mAzimuthAngleMeasurement = azimuthAngle;
- return this;
}
/**
@@ -162,15 +159,9 @@
/**
* Build the {@link AngleOfArrivalMeasurement} object
- *
- * @throws IllegalStateException if the required azimuth angle is not provided
*/
@NonNull
public AngleOfArrivalMeasurement build() {
- if (mAzimuthAngleMeasurement == null) {
- throw new IllegalStateException("Azimuth angle measurement is not set");
- }
-
return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement,
mAltitudeAngleMeasurement);
}
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index 468a69c..4036892 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -62,9 +62,6 @@
/**
* Request to open a new ranging session
*
- * This function must return before calling any functions in
- * IUwbAdapterCallbacks.
- *
* 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.
@@ -77,12 +74,16 @@
* RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called
* if the ranging session fails to be opened.
*
+ * If the provided sessionHandle is already open for the calling client, then
+ * #onRangingOpenFailed must be called and the new session must not be opened.
+ *
+ * @param sessionHandle the session handle to open ranging for
* @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 openRanging(in IUwbRangingCallbacks rangingCallbacks,
- in PersistableBundle parameters);
+ void openRanging(in SessionHandle sessionHandle,
+ in IUwbRangingCallbacks rangingCallbacks,
+ in PersistableBundle parameters);
/**
* Request to start ranging
diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java
index c0d8187..85f2c1c 100644
--- a/core/java/android/uwb/RangingManager.java
+++ b/core/java/android/uwb/RangingManager.java
@@ -17,6 +17,7 @@
package android.uwb;
import android.annotation.NonNull;
+import android.os.CancellationSignal;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.Log;
@@ -32,6 +33,7 @@
private final IUwbAdapter mAdapter;
private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>();
+ private int mNextSessionId = 1;
public RangingManager(IUwbAdapter adapter) {
mAdapter = adapter;
@@ -44,29 +46,26 @@
* @param executor {@link Executor} to run callbacks
* @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
* that is being opened.
- * @return a new {@link RangingSession}
+ * @return a {@link CancellationSignal} that may be used to cancel the opening of the
+ * {@link RangingSession}.
*/
- public RangingSession openSession(@NonNull PersistableBundle params, @NonNull Executor executor,
+ public CancellationSignal openSession(@NonNull PersistableBundle params,
+ @NonNull Executor executor,
@NonNull RangingSession.Callback callbacks) {
- SessionHandle sessionHandle;
- try {
- sessionHandle = mAdapter.openRanging(this, params);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
synchronized (this) {
- if (hasSession(sessionHandle)) {
- Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle");
- executor.execute(() -> callbacks.onClosed(
- RangingSession.Callback.REASON_GENERIC_ERROR,
- new PersistableBundle()));
- }
-
+ SessionHandle sessionHandle = new SessionHandle(mNextSessionId++);
RangingSession session =
new RangingSession(executor, callbacks, mAdapter, sessionHandle);
mRangingSessionTable.put(sessionHandle, session);
- return session;
+ try {
+ mAdapter.openRanging(sessionHandle, this, params);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ CancellationSignal cancellationSignal = new CancellationSignal();
+ cancellationSignal.setOnCancelListener(() -> session.close());
+ return cancellationSignal;
}
}
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 63a6d05..844bbbe 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -25,6 +25,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -228,14 +229,14 @@
* @param callbacks {@link RangingSession.Callback} to associate with the
* {@link RangingSession} that is being opened.
*
- * @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a
+ * @return an {@link CancellationSignal} that is able to be used to 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#onOpened(RangingSession)}.
*/
@NonNull
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
- public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
+ public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
@NonNull @CallbackExecutor Executor executor,
@NonNull RangingSession.Callback callbacks) {
return mRangingManager.openSession(parameters, executor, callbacks);
diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
index c01bb75..e41805d 100644
--- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
@@ -22,7 +22,6 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -32,6 +31,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import java.util.concurrent.Executor;
@@ -42,51 +42,23 @@
@RunWith(AndroidJUnit4.class)
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 @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
@Test
public void testOpenSession_OpenRangingInvoked() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
rangingManager.openSession(PARAMS, EXECUTOR, callback);
- verify(ADAPTER, times(1)).openRanging(eq(rangingManager), eq(PARAMS));
- }
-
- @Test
- public void testOpenSession_ErrorIfSameSessionHandleReturned() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
-
- // Calling openSession will cause the same session handle to be returned. The onClosed
- // callback should be invoked
- RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback2);
- verify(callback, times(0)).onClosed(anyInt(), any());
- verify(callback2, times(1)).onClosed(anyInt(), any());
- }
-
- @Test
- 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.openRanging(any(), any())).thenReturn(handle);
-
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
- rangingManager.onRangingOpened(handle);
- verify(callback, times(1)).onOpened(any());
+ verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS));
}
@Test
public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
rangingManager.onRangingOpened(new SessionHandle(2));
@@ -95,18 +67,20 @@
@Test
public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException {
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
-
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ RangingManager rangingManager = new RangingManager(adapter);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(sessionHandle1);
verify(callback1, times(1)).onOpened(any());
@@ -119,12 +93,17 @@
@Test
public void testCorrectCallbackInvoked() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle handle = sessionHandleCaptor.getValue();
+
rangingManager.onRangingOpened(handle);
verify(callback, times(1)).onOpened(any());
@@ -156,20 +135,23 @@
@Test
public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException {
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
// Verify that if multiple sessions are registered, only the session that is
// requested to close receives the associated callbacks
- 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.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
+ RangingManager rangingManager = new RangingManager(adapter);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- RangingManager rangingManager = new RangingManager(ADAPTER);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS);
verify(callback1, times(1)).onClosed(anyInt(), any());
@@ -182,19 +164,22 @@
@Test
public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException {
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ RangingManager rangingManager = new RangingManager(adapter);
rangingManager.openSession(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);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingStarted(sessionHandle2, PARAMS);
rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1));
@@ -232,17 +217,24 @@
private void runReason(@RangingChangeReason int reasonIn,
@RangingSession.Callback.Reason int reasonOut) throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
+
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS);
verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
// Open a new session
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(handle);
rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
index 8e7f7c56..75c6924 100644
--- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -16,34 +16,23 @@
package android.uwb;
-import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.SystemClock;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.Executor;
public class UwbTestUtils {
private UwbTestUtils() {}
- public static boolean isUwbSupported(Context context) {
- PackageManager packageManager = context.getPackageManager();
- return packageManager.hasSystemFeature(PackageManager.FEATURE_UWB);
- }
-
public static AngleMeasurement getAngleMeasurement() {
- return new AngleMeasurement.Builder()
- .setRadians(getDoubleInRange(-Math.PI, Math.PI))
- .setErrorRadians(getDoubleInRange(0, Math.PI))
- .setConfidenceLevel(getDoubleInRange(0, 1))
- .build();
+ return new AngleMeasurement(
+ getDoubleInRange(-Math.PI, Math.PI),
+ getDoubleInRange(0, Math.PI),
+ getDoubleInRange(0, 1));
}
public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
- return new AngleOfArrivalMeasurement.Builder()
+ return new AngleOfArrivalMeasurement.Builder(getAngleMeasurement())
.setAltitude(getAngleMeasurement())
- .setAzimuth(getAngleMeasurement())
.build();
}
@@ -69,14 +58,6 @@
.build();
}
- public static List<RangingMeasurement> getRangingMeasurements(int num) {
- List<RangingMeasurement> result = new ArrayList<>();
- for (int i = 0; i < num; i++) {
- result.add(getRangingMeasurement());
- }
- return result;
- }
-
public static RangingReport getRangingReports(int numMeasurements) {
RangingReport.Builder builder = new RangingReport.Builder();
for (int i = 0; i < numMeasurements; i++) {
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 502e74a..1ef93f4 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -667,6 +667,10 @@
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
requireNonNull(listener, "listener was null");
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_FACTORY,
+ "Must have permission NETWORK_FACTORY to unregister a policy listener");
+
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
PolicyListenerBinderDeath listenerBinderDeath =
diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
index cedf48b..9c28c36 100644
--- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
+++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
@@ -25,7 +25,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
-import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -389,22 +388,6 @@
* The optional timestamp indicating the data and time of the status change of this tuple.
* Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
* string per RFC3339.
- * @hide
- */
- public @NonNull Builder setTimestamp(@NonNull String timestamp) {
- try {
- mPresenceTuple.mTimestamp =
- DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp, Instant::from);
- } catch (DateTimeParseException e) {
- Log.d(LOG_TAG, "Parse timestamp failed " + e);
- }
- return this;
- }
-
- /**
- * The optional timestamp indicating the data and time of the status change of this tuple.
- * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
- * string per RFC3339.
*/
public @NonNull Builder setTime(@NonNull Instant timestamp) {
mPresenceTuple.mTimestamp = timestamp;
@@ -534,14 +517,6 @@
return mContactUri;
}
- /**
- * @return the timestamp element contained in the tuple if it exists
- * @hide
- */
- public @Nullable String getTimestamp() {
- return (mTimestamp == null) ? null : mTimestamp.toString();
- }
-
/** @return the timestamp element contained in the tuple if it exists */
public @Nullable Instant getTime() {
return mTimestamp;
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 815c08d..dd91026 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -439,8 +439,7 @@
/**
* The pending request has resulted in an error and may need to be retried, depending on the
- * error code. The callback {@link #onCapabilitiesReceived(List)}
- * for each contacts is required to be called before {@link #onError} is called.
+ * error code.
* @param errorCode The reason for the framework being unable to process the request.
* @param retryIntervalMillis The time in milliseconds the requesting application should
* wait before retrying, if non-zero.
@@ -487,93 +486,6 @@
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
* @hide
*/
- @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
- Manifest.permission.READ_CONTACTS})
- public void requestCapabilities(@NonNull List<Uri> contactNumbers,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull CapabilitiesCallback c) throws ImsException {
- if (c == null) {
- throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
- }
- if (executor == null) {
- throw new IllegalArgumentException("Must include a non-null Executor.");
- }
- if (contactNumbers == null) {
- throw new IllegalArgumentException("Must include non-null contact number list.");
- }
-
- IImsRcsController imsRcsController = getIImsRcsController();
- if (imsRcsController == null) {
- Log.e(TAG, "requestCapabilities: IImsRcsController is null");
- throw new ImsException("Can not find remote IMS service",
- ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
- }
-
- IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
- @Override
- public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities));
- } finally {
- restoreCallingIdentity(callingIdentity);
- }
- }
- @Override
- public void onComplete() {
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> c.onComplete());
- } finally {
- restoreCallingIdentity(callingIdentity);
- }
- }
- @Override
- public void onError(int errorCode, long retryAfterMilliseconds) {
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
- } finally {
- restoreCallingIdentity(callingIdentity);
- }
- }
- };
-
- try {
- imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(),
- mContext.getAttributionTag(), contactNumbers, internalCallback);
- } catch (ServiceSpecificException e) {
- throw new ImsException(e.toString(), e.errorCode);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
- throw new ImsException("Remote IMS Service is not available",
- ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
- }
- }
-
- /**
- * Request the User Capability Exchange capabilities for one or more contacts.
- * <p>
- * This will return the cached capabilities of the contact and will not perform a capability
- * poll on the network unless there are contacts being queried with stale information.
- * <p>
- * Be sure to check the availability of this feature using
- * {@link ImsRcsManager#isAvailable(int, int)} and ensuring
- * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
- * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else
- * this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
- *
- * @param contactNumbers A list of numbers that the capabilities are being requested for.
- * @param executor The executor that will be used when the request is completed and the
- * {@link CapabilitiesCallback} is called.
- * @param c A one-time callback for when the request for capabilities completes or there is an
- * error processing the request.
- * @throws ImsException if the subscription associated with this instance of
- * {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
- * available. This can happen if the ImsService has crashed, for example, or if the subscription
- * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
- * @hide
- */
@SystemApi
@RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
Manifest.permission.READ_CONTACTS})
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
index 00c9168..03e17fb 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -386,41 +386,6 @@
* {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the
* framework to finish listening for NOTIFY responses.
*
- * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
- * capabilities for.
- * @param cb The callback of the subscribe request.
- * @hide
- */
- // executor used is defined in the constructor.
- @SuppressLint("ExecutorRegistration")
- public void subscribeForCapabilities(@NonNull List<Uri> uris,
- @NonNull SubscribeResponseCallback cb) {
- // Stub - to be implemented by service
- Log.w(LOG_TAG, "subscribeForCapabilities called with no implementation.");
- try {
- cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
- } catch (ImsException e) {
- // Do not do anything, this is a stub implementation.
- }
- }
-
- /**
- * The user capabilities of one or multiple contacts have been requested by the framework.
- * <p>
- * The implementer must follow up this call with an
- * {@link SubscribeResponseCallback#onCommandError} call to indicate this operation has failed.
- * The response from the network to the SUBSCRIBE request must be sent back to the framework
- * using {@link SubscribeResponseCallback#onNetworkResponse(int, String)}.
- * As NOTIFY requests come in from the network, the requested contact’s capabilities should be
- * sent back to the framework using
- * {@link SubscribeResponseCallback#onNotifyCapabilitiesUpdate(List<String>}) and
- * {@link SubscribeResponseCallback#onResourceTerminated(List<Pair<Uri, String>>)}
- * should be called with the presence information for the contacts specified.
- * <p>
- * Once the subscription is terminated,
- * {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the
- * framework to finish listening for NOTIFY responses.
- *
* @param uris A {@link Collection} of the {@link Uri}s that the framework is requesting the
* UCE capabilities for.
* @param cb The callback of the subscribe request.
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 11498de..a0200275 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -593,6 +593,16 @@
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
}
+ @Test(expected = SecurityException.class)
+ public void testRemoveVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
+ doThrow(new SecurityException())
+ .when(mMockContext)
+ .enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.NETWORK_FACTORY), any());
+
+ mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+ }
+
@Test
public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() {
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);