Merge "RCS Provisioning APIs for Single Registration"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f47a6b0..37e009d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -59,6 +59,7 @@
<protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE" />
<protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
<protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
+ <protected-broadcast android:name= "com.android.internal.telephony.PROVISION" />
<protected-broadcast android:name= "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED" />
<protected-broadcast android:name= "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED" />
<protected-broadcast android:name= "com.android.intent.isim_refresh" />
@@ -88,6 +89,7 @@
<protected-broadcast android:name= "android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
<protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED" />
<protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED" />
+ <protected-broadcast android:name= "android.telephony.action.TOGGLE_PROVISION" />
<protected-broadcast android:name= "android.telephony.action.NETWORK_COUNTRY_CHANGED" />
<protected-broadcast android:name= "android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED" />
<protected-broadcast android:name= "android.telephony.action.MULTI_SIM_CONFIG_CHANGED" />
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index 52069b8..12c8cda 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -466,6 +466,24 @@
}
}
+ @Override
+ public void triggerNetworkRegistration(int subId, ISipDelegate connection, int sipCode,
+ String sipReason) {
+ enforceModifyPermission();
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ SipTransportController transport = getRcsFeatureController(subId).getFeature(
+ SipTransportController.class);
+ if (transport == null) {
+ return;
+ }
+ transport.triggerFullNetworkRegistration(subId, connection, sipCode, sipReason);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
/**
* Registers for updates to the RcsFeature connection through the IImsServiceFeatureCallback
* callback.
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 796efd0..9b2cac7 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -31,7 +31,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -2260,7 +2259,7 @@
mApp.getSystemService(AppOpsManager.class)
.checkPackage(Binder.getCallingUid(), callingPackage);
- final int targetSdk = getTargetSdk(callingPackage);
+ final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
if (targetSdk > android.os.Build.VERSION_CODES.R) {
// Callers targeting S have no business invoking this method.
return;
@@ -2695,30 +2694,11 @@
android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
}
- /**
- * Returns the target SDK version number for a given package name.
- *
- * This call MUST be invoked before clearing the calling UID.
- *
- * @return target SDK if the package is found or INT_MAX.
- */
- private int getTargetSdk(String packageName) {
- try {
- final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
- packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
- if (ai != null) return ai.targetSdkVersion;
- } catch (PackageManager.NameNotFoundException unexpected) {
- loge("Failed to get package info for pkg="
- + packageName + ", uid=" + Binder.getCallingUid());
- }
- return Integer.MAX_VALUE;
- }
-
@Override
@SuppressWarnings("unchecked")
public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
String callingFeatureId) {
- final int targetSdk = getTargetSdk(callingPackage);
+ final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
throw new SecurityException(
"getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
@@ -2777,7 +2757,7 @@
return new ArrayList<>();
}
- final int targetSdk = getTargetSdk(callingPackage);
+ final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
return getCachedCellInfo();
}
@@ -2830,13 +2810,15 @@
.build());
switch (locationResult) {
case DENIED_HARD:
- if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
+ if (TelephonyPermissions
+ .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
// Safetynet logging for b/154934934
EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
}
throw new SecurityException("Not allowed to access cell info");
case DENIED_SOFT:
- if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
+ if (TelephonyPermissions
+ .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
// Safetynet logging for b/154934934
EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
}
@@ -4561,7 +4543,7 @@
@Override
public int getNetworkTypeForSubscriber(int subId, String callingPackage,
String callingFeatureId) {
- final int targetSdk = getTargetSdk(callingPackage);
+ final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
if (targetSdk > android.os.Build.VERSION_CODES.Q) {
return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
} else if (targetSdk == android.os.Build.VERSION_CODES.Q
diff --git a/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java b/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
index 39e9965..9d2c5d6 100644
--- a/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
+++ b/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
@@ -19,10 +19,11 @@
import android.telephony.ims.DelegateRegistrationState;
import android.telephony.ims.DelegateRequest;
import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateConnection;
import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.SipDelegateManager;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
-import android.telephony.ims.aidl.ISipTransport;
import com.android.internal.annotations.VisibleForTesting;
@@ -61,8 +62,8 @@
* denied. See {@link SipDelegateBinderConnectionStub} and
* {@link SipDelegateBinderConnection}
*/
- DelegateBinderStateManager create(int subId, ISipTransport sipTransport,
- DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+ DelegateBinderStateManager create(int subId, DelegateRequest requestedConfig,
+ Set<FeatureTagState> transportDeniedTags,
Executor executor, List<StateCallback> stateCallbacks);
}
@@ -89,4 +90,11 @@
* Contains the reason the SipDelegate reported it was destroyed.
*/
void destroy(int reason, Consumer<Integer> destroyedConsumer);
+
+ /**
+ * Called by IMS application, see
+ * {@link SipDelegateManager#triggerFullNetworkRegistration(SipDelegateConnection, int, String)}
+ * for more information about when this is called.
+ */
+ void triggerFullNetworkRegistration(int sipCode, String sipReason);
}
diff --git a/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
index 1a77f2b..3f6f269 100644
--- a/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
@@ -24,6 +24,7 @@
import android.telephony.ims.FeatureTagState;
import android.telephony.ims.SipDelegateImsConfiguration;
import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
import android.telephony.ims.aidl.ISipDelegateStateCallback;
@@ -118,6 +119,7 @@
};
private final ISipTransport mSipTransport;
+ private final IImsRegistration mImsRegistration;
private final DelegateRequest mRequestedConfig;
private ISipDelegate mDelegateBinder;
@@ -129,6 +131,8 @@
* {@link SipDelegate}.
* @param subId The subid that this SipDelegate is being created for.
* @param sipTransport The SipTransport implementation that will be used to manage SipDelegates.
+ * @param registrationImpl The ImsRegistration implementation that will be used to manage
+ * registration changes in relation to the SipDelegates.
* @param requestedConfig The DelegateRequest to be sent to the ImsService.
* @param transportDeniedTags The feature tags that have already been denied by the
* SipTransportController and should not be requested.
@@ -138,10 +142,12 @@
* SipDelegate changes. This will be called on the supplied executor.
*/
public SipDelegateBinderConnection(int subId, ISipTransport sipTransport,
- DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
- Executor executor, List<StateCallback> stateCallbacks) {
+ IImsRegistration registrationImpl, DelegateRequest requestedConfig,
+ Set<FeatureTagState> transportDeniedTags, Executor executor,
+ List<StateCallback> stateCallbacks) {
mSubId = subId;
mSipTransport = sipTransport;
+ mImsRegistration = registrationImpl;
mRequestedConfig = requestedConfig;
mDeniedTags = transportDeniedTags;
mExecutor = executor;
@@ -184,6 +190,15 @@
}
}
+ @Override
+ public void triggerFullNetworkRegistration(int sipCode, String sipReason) {
+ try {
+ mImsRegistration.triggerFullNetworkRegistration(sipCode, sipReason);
+ } catch (RemoteException e) {
+ logw("triggerFullNetworkRegistration called on unreachable ImsRegistration:" + e);
+ }
+ }
+
private void notifySipDelegateCreated(ISipDelegate delegate,
List<FeatureTagState> deniedFeatureTags) {
logi("Delegate Created: " + delegate + ", deniedTags:" + deniedFeatureTags);
diff --git a/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java b/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
index 888af94..ef12eb8 100644
--- a/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
@@ -77,4 +77,10 @@
destroyedConsumer.accept(reason);
});
}
+
+ @Override
+ public void triggerFullNetworkRegistration(int sipCode, String sipReason) {
+ // This stub is not connected to an ImsService, so this method is intentionally not
+ // implemented.
+ }
}
diff --git a/src/com/android/services/telephony/rcs/SipDelegateController.java b/src/com/android/services/telephony/rcs/SipDelegateController.java
index ed50778..4b3176a 100644
--- a/src/com/android/services/telephony/rcs/SipDelegateController.java
+++ b/src/com/android/services/telephony/rcs/SipDelegateController.java
@@ -21,6 +21,7 @@
import android.telephony.ims.FeatureTagState;
import android.telephony.ims.SipDelegateConnection;
import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
@@ -49,10 +50,18 @@
public class SipDelegateController {
static final String LOG_TAG = "SipDelegateC";
- private DelegateBinderStateManager.Factory mBinderConnectionFactory =
- new DelegateBinderStateManager.Factory() {
+ private class BinderConnectionFactory implements DelegateBinderStateManager.Factory {
+
+ private final ISipTransport mSipTransportImpl;
+ private final IImsRegistration mImsRegistrationImpl;
+
+ BinderConnectionFactory(ISipTransport transport, IImsRegistration registration) {
+ mSipTransportImpl = transport;
+ mImsRegistrationImpl = registration;
+ }
+
@Override
- public DelegateBinderStateManager create(int subId, ISipTransport sipTransport,
+ public DelegateBinderStateManager create(int subId,
DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
Executor executor, List<DelegateBinderStateManager.StateCallback> stateCallbacks) {
// We should not actually create a SipDelegate in this case.
@@ -60,32 +69,33 @@
return new SipDelegateBinderConnectionStub(transportDeniedTags, executor,
stateCallbacks);
}
- return new SipDelegateBinderConnection(mSubId, mSipTransportImpl, requestedConfig,
- transportDeniedTags, mExecutorService, stateCallbacks);
+ return new SipDelegateBinderConnection(mSubId, mSipTransportImpl, mImsRegistrationImpl,
+ requestedConfig, transportDeniedTags, mExecutorService, stateCallbacks);
}
- };
+ }
private final int mSubId;
private final String mPackageName;
private final DelegateRequest mInitialRequest;
- private final ISipTransport mSipTransportImpl;
private final ScheduledExecutorService mExecutorService;
private final MessageTransportStateTracker mMessageTransportStateTracker;
private final DelegateStateTracker mDelegateStateTracker;
+ private final DelegateBinderStateManager.Factory mBinderConnectionFactory;
private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
private DelegateBinderStateManager mBinderConnection;
private Set<String> mTrackedFeatureTags;
public SipDelegateController(int subId, DelegateRequest initialRequest, String packageName,
- ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+ ISipTransport transportImpl, IImsRegistration registrationImpl,
+ ScheduledExecutorService executorService,
ISipDelegateConnectionStateCallback stateCallback,
ISipDelegateMessageCallback messageCallback) {
mSubId = subId;
mPackageName = packageName;
mInitialRequest = initialRequest;
- mSipTransportImpl = sipTransportImpl;
mExecutorService = executorService;
+ mBinderConnectionFactory = new BinderConnectionFactory(transportImpl, registrationImpl);
mMessageTransportStateTracker = new MessageTransportStateTracker(mSubId, executorService,
messageCallback);
@@ -98,14 +108,13 @@
*/
@VisibleForTesting
public SipDelegateController(int subId, DelegateRequest initialRequest, String packageName,
- ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+ ScheduledExecutorService executorService,
MessageTransportStateTracker messageTransportStateTracker,
DelegateStateTracker delegateStateTracker,
DelegateBinderStateManager.Factory connectionFactory) {
mSubId = subId;
mInitialRequest = initialRequest;
mPackageName = packageName;
- mSipTransportImpl = sipTransportImpl;
mExecutorService = executorService;
mMessageTransportStateTracker = messageTransportStateTracker;
mDelegateStateTracker = delegateStateTracker;
@@ -249,6 +258,21 @@
}, mExecutorService);
};
+ /**
+ * The IMS application is notifying the ImsService that it has received a response to a request
+ * that will require that the IMS registration be torn down and brought back up.
+ *<p>
+ * See {@link SipDelegateManager#triggerFullNetworkRegistration} for more information.
+ */
+ public void triggerFullNetworkRegistration(int sipCode, String sipReason) {
+ logi("triggerFullNetworkRegistration, code=" + sipCode + ", reason=" + sipReason);
+ if (mBinderConnection != null) {
+ mBinderConnection.triggerFullNetworkRegistration(sipCode, sipReason);
+ } else {
+ logw("triggerFullNetworkRegistration called when binder connection is null");
+ }
+ }
+
private static int getMessageFailReasonFromDestroyReason(int destroyReason) {
switch (destroyReason) {
case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD:
@@ -340,7 +364,7 @@
stateCallbacks.add(mDelegateStateTracker);
stateCallbacks.add(mMessageTransportStateTracker);
- return mBinderConnectionFactory.create(mSubId, mSipTransportImpl,
+ return mBinderConnectionFactory.create(mSubId,
new DelegateRequest(supportedSet), deniedSet, mExecutorService, stateCallbacks);
}
diff --git a/src/com/android/services/telephony/rcs/SipTransportController.java b/src/com/android/services/telephony/rcs/SipTransportController.java
index 5d817ba..028e49f 100644
--- a/src/com/android/services/telephony/rcs/SipTransportController.java
+++ b/src/com/android/services/telephony/rcs/SipTransportController.java
@@ -19,12 +19,14 @@
import android.app.role.OnRoleHoldersChangedListener;
import android.app.role.RoleManager;
import android.content.Context;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.ims.DelegateRequest;
import android.telephony.ims.FeatureTagState;
import android.telephony.ims.ImsException;
import android.telephony.ims.ImsService;
import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
@@ -206,7 +208,8 @@
public interface SipDelegateControllerFactory {
/** See {@link SipDelegateController} */
SipDelegateController create(int subId, DelegateRequest initialRequest, String packageName,
- ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+ ISipTransport sipTransportImpl, IImsRegistration registrationImpl,
+ ScheduledExecutorService executorService,
ISipDelegateConnectionStateCallback stateCallback,
ISipDelegateMessageCallback messageCallback);
}
@@ -348,6 +351,16 @@
}
/**
+ * The remote IMS application has requested that the ImsService tear down and re-register for
+ * IMS features due to an error it received on the network in response to a SIP request.
+ */
+ public void triggerFullNetworkRegistration(int subId, ISipDelegate connection, int sipCode,
+ String sipReason) {
+ mExecutorService.execute(() -> triggerFullNetworkRegistrationInternal(subId, connection,
+ sipCode, sipReason));
+ }
+
+ /**
* @return Whether or not SipTransports are supported on the connected ImsService. This can
* change based on the capabilities of the ImsService.
* @throws ImsException if the ImsService connected to this controller is currently down.
@@ -366,11 +379,13 @@
ISipDelegateMessageCallback delegateMessage,
Consumer<ImsException> startedErrorConsumer) {
ISipTransport transport;
+ IImsRegistration registration;
// Send back any errors via Consumer early in creation process if it is clear that the
// SipDelegate will never be created.
try {
checkStateOfController(subId);
transport = mRcsManager.getSipTransport();
+ registration = mRcsManager.getImsRegistration();
if (transport == null) {
logw("createSipDelegateInternal, transport null during request.");
startedErrorConsumer.accept(new ImsException("SipTransport not supported",
@@ -387,7 +402,7 @@
}
SipDelegateController c = mDelegateControllerFactory.create(subId, request, packageName,
- transport, mExecutorService, delegateState, delegateMessage);
+ transport, registration, mExecutorService, delegateState, delegateMessage);
logi("createSipDelegateInternal: request= " + request + ", packageName= " + packageName
+ ", controller created: " + c);
addPendingCreateAndEvaluate(c);
@@ -420,43 +435,98 @@
addPendingDestroyAndEvaluate(match, reason);
}
+ private void triggerFullNetworkRegistrationInternal(int subId, ISipDelegate connection,
+ int sipCode, String sipReason) {
+ if (subId != mSubId) {
+ logw("triggerFullNetworkRegistrationInternal: ignoring network reg request, as this is"
+ + "about to be destroyed anyway due to subId change, delegate=" + connection);
+ return;
+ }
+ if (connection == null) {
+ logw("triggerFullNetworkRegistrationInternal: ignoring, null connection binder.");
+ return;
+ }
+ // Ensure the requester has a valid SipDelegate registered.
+ SipDelegateController match = null;
+ for (SipDelegateController controller : mDelegatePriorityQueue) {
+ if (Objects.equal(connection.asBinder(),
+ controller.getSipDelegateInterface().asBinder())) {
+ match = controller;
+ break;
+ }
+ }
+ if (match == null) {
+ logw("triggerFullNetworkRegistrationInternal: could not find matching connection, "
+ + "ignoring");
+ return;
+ }
+
+ match.triggerFullNetworkRegistration(sipCode, sipReason);
+ }
+
/**
* Cancel pending update IMS registration events if they exist and instead send a deregister
* event.
*/
private void triggerDeregistrationEvent() {
- if (mPendingUpdateRegistrationFuture != null
- && !mPendingUpdateRegistrationFuture.isDone()) {
- // Cancel pending update and replace with a call to deregister now.
- mPendingUpdateRegistrationFuture.cancel(false);
- logi("triggerDeregistrationEvent: cancelling existing reg update event: "
- + mPendingUpdateRegistrationFuture);
- }
logi("triggerDeregistrationEvent: Sending deregister event to ImsService");
- //TODO hook up registration apis
+ cancelPendingUpdateRegistration();
+
+ IImsRegistration registrationImpl = mRcsManager.getImsRegistration();
+ if (registrationImpl != null) {
+ try {
+ registrationImpl.triggerSipDelegateDeregistration();
+ } catch (RemoteException e) {
+ logi("triggerDeregistrationEvent: received RemoteException: " + e);
+ }
+ }
}
/**
* Schedule an update to the IMS registration. If there is an existing update scheduled, cancel
* it and reschedule.
+ * <p>
+ * We want to wait because this can directly result in changes to the IMS registration on the
+ * network, so we need to wait for a steady state where all changes have been made before
+ * triggering an update to the network registration.
*/
private void scheduleUpdateRegistration() {
- if (mPendingUpdateRegistrationFuture != null
- && !mPendingUpdateRegistrationFuture.isDone()) {
- // Cancel the old pending operation and reschedule again.
- mPendingUpdateRegistrationFuture.cancel(false);
- logi("scheduleUpdateRegistration: cancelling existing reg update event: "
- + mPendingUpdateRegistrationFuture);
- }
+ cancelPendingUpdateRegistration();
+
ScheduledFuture<?> f = mExecutorService.schedule(this::triggerUpdateRegistrationEvent,
mTimerAdapter.getUpdateRegistrationDelayMilliseconds(), TimeUnit.MILLISECONDS);
logi("scheduleUpdateRegistration: scheduling new event: " + f);
mPendingUpdateRegistrationFuture = f;
}
+ /**
+ * Cancel an existing pending task to update the IMS registration associated with SIP delegates.
+ */
+ private void cancelPendingUpdateRegistration() {
+ if (mPendingUpdateRegistrationFuture == null
+ || mPendingUpdateRegistrationFuture.isDone()) {
+ return;
+ }
+ // Cancel the old pending operation and reschedule again.
+ mPendingUpdateRegistrationFuture.cancel(false);
+ logi("scheduleUpdateRegistration: cancelling existing reg update event: "
+ + mPendingUpdateRegistrationFuture);
+ }
+
+ /**
+ * Triggers an event to update the IMS registration of the ImsService. Should only be called
+ * from {@link #scheduleUpdateRegistration()}.
+ */
private void triggerUpdateRegistrationEvent() {
logi("triggerUpdateRegistrationEvent: Sending update registration event to ImsService");
- //TODO hook up registration apis
+ IImsRegistration registrationImpl = mRcsManager.getImsRegistration();
+ if (registrationImpl != null) {
+ try {
+ registrationImpl.triggerUpdateSipDelegateRegistration();
+ } catch (RemoteException e) {
+ logi("triggerUpdateRegistrationEvent: received RemoteException: " + e);
+ }
+ }
}
/**
@@ -564,6 +634,9 @@
* by another delegate higher in the priority queue.
*/
private void reevaluateDelegates() {
+ // We need to cancel the pending update now and reschedule IMS registration update for
+ // after the reevaluate is complete.
+ cancelPendingUpdateRegistration();
if (mEvaluateCompleteFuture != null && !mEvaluateCompleteFuture.isDone()) {
logw("reevaluateDelegates: last evaluate not done, deferring new request");
// Defer re-evaluate until after the pending re-evaluate is complete.
@@ -614,10 +687,13 @@
}, mExecutorService);
}
- // Executor doesn't matter here, just adding an extra stage to print result.
+ // Executor doesn't matter here, schedule an event to update the IMS registration.
mEvaluateCompleteFuture = pendingChange
- .thenAccept((associatedFeatures) -> logi("reevaluateDelegates: reevaluate complete,"
- + " feature tags associated: " + associatedFeatures));
+ .thenAccept((associatedFeatures) -> {
+ logi("reevaluateDelegates: reevaluate complete," + " feature tags associated: "
+ + associatedFeatures);
+ scheduleUpdateRegistration();
+ });
logi("reevaluateDelegates: future created.");
}
@@ -666,13 +742,19 @@
// CarrierConfigManager
return;
}
- updateRoleCache();
- // new denied tags will be picked up when reevaluate completes.
- scheduleThrottledReevaluate();
+ boolean roleChanged = updateRoleCache();
+ if (roleChanged) {
+ triggerDeregistrationEvent();
+ // new denied tags will be picked up when reevaluate completes.
+ scheduleThrottledReevaluate();
+ }
}
- private void updateRoleCache() {
+ /**
+ * @return true, if the role cache has changed, false otherwise.
+ */
+ private boolean updateRoleCache() {
String newSmsRolePackageName = "";
try {
// Only one app can fulfill the SMS role.
@@ -685,9 +767,10 @@
logi("updateRoleCache: new packageName=" + newSmsRolePackageName);
if (TextUtils.equals(mCachedSmsRolePackageName, newSmsRolePackageName)) {
logi("updateRoleCache, skipping, role did not change");
- return;
+ return false;
}
mCachedSmsRolePackageName = newSmsRolePackageName;
+ return true;
}
/**
diff --git a/tests/src/com/android/TelephonyTestBase.java b/tests/src/com/android/TelephonyTestBase.java
index 502740d..09abb15 100644
--- a/tests/src/com/android/TelephonyTestBase.java
+++ b/tests/src/com/android/TelephonyTestBase.java
@@ -61,9 +61,7 @@
protected final boolean waitForExecutorAction(Executor executor, long timeoutMillis) {
final CountDownLatch lock = new CountDownLatch(1);
- Log.i("BRAD", "waitForExecutorAction");
executor.execute(() -> {
- Log.i("BRAD", "countdown");
lock.countDown();
});
while (lock.getCount() > 0) {
diff --git a/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java b/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java
index fa439dc..360fa21 100644
--- a/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java
+++ b/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java
@@ -32,6 +32,7 @@
import android.telephony.ims.FeatureTagState;
import android.telephony.ims.SipDelegateImsConfiguration;
import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
import android.telephony.ims.aidl.ISipDelegateStateCallback;
@@ -61,6 +62,7 @@
@Mock private ISipDelegate mMockDelegate;
@Mock private ISipTransport mMockTransport;
+ @Mock private IImsRegistration mMockRegistration;
@Mock private IBinder mTransportBinder;
@Mock private ISipDelegateMessageCallback mMessageCallback;
@Mock private DelegateBinderStateManager.StateCallback mMockStateCallback;
@@ -107,7 +109,8 @@
DelegateRequest request = getDelegateRequest();
ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
- mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+ mMockTransport, mMockRegistration, request, deniedTags, Runnable::run,
+ mStateCallbackList);
ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
// Send onCreated callback from SipDelegate
@@ -130,7 +133,8 @@
DelegateRequest request = getDelegateRequest();
ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
- mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+ mMockTransport, mMockRegistration, request, deniedTags, Runnable::run,
+ mStateCallbackList);
doThrow(new RemoteException()).when(mMockTransport).createSipDelegate(eq(TEST_SUB_ID),
any(), any(), any());
ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
@@ -143,7 +147,8 @@
DelegateRequest request = getDelegateRequest();
ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
- mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+ mMockTransport, mMockRegistration, request, deniedTags, Runnable::run,
+ mStateCallbackList);
ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
assertNotNull(cb);
cb.onCreated(mMockDelegate, null /*denied*/);
@@ -162,7 +167,8 @@
DelegateRequest request = getDelegateRequest();
ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
- mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+ mMockTransport, mMockRegistration, request, deniedTags, Runnable::run,
+ mStateCallbackList);
ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
assertNotNull(cb);
cb.onCreated(mMockDelegate, null /*denied*/);
@@ -181,7 +187,8 @@
DelegateRequest request = getDelegateRequest();
ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
- mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+ mMockTransport, mMockRegistration, request, deniedTags, Runnable::run,
+ mStateCallbackList);
ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
assertNotNull(cb);
cb.onCreated(mMockDelegate, new ArrayList<>(deniedTags));
diff --git a/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java b/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java
index 47b4808..27f896b 100644
--- a/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java
@@ -36,7 +36,6 @@
import android.telephony.ims.SipDelegateManager;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
-import android.telephony.ims.aidl.ISipTransport;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
@@ -65,7 +64,6 @@
private static final int TEST_SUB_ID = 1;
@Mock private ISipDelegate mMockSipDelegate;
- @Mock private ISipTransport mMockSipTransport;
@Mock private MessageTransportStateTracker mMockMessageTracker;
@Mock private ISipDelegateMessageCallback mMockMessageCallback;
@Mock private DelegateStateTracker mMockDelegateStateTracker;
@@ -243,9 +241,9 @@
private SipDelegateController getTestDelegateController(DelegateRequest request,
Set<FeatureTagState> deniedSet) {
- return new SipDelegateController(TEST_SUB_ID, request, "", mMockSipTransport,
- mExecutorService, mMockMessageTracker, mMockDelegateStateTracker,
- (a, b, c, deniedFeatureSet, e, f) -> {
+ return new SipDelegateController(TEST_SUB_ID, request, "", mExecutorService,
+ mMockMessageTracker, mMockDelegateStateTracker,
+ (a, b, deniedFeatureSet, d, e) -> {
assertEquals(deniedSet, deniedFeatureSet);
return mMockBinderConnection;
});
diff --git a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
index 8e10757..fa27775 100644
--- a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
@@ -40,6 +40,7 @@
import android.telephony.ims.FeatureTagState;
import android.telephony.ims.ImsException;
import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.ISipDelegate;
import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
@@ -102,6 +103,7 @@
@Mock private RcsFeatureManager mRcsManager;
@Mock private ISipTransport mSipTransport;
+ @Mock private IImsRegistration mImsRegistration;
@Mock private ISipDelegateConnectionStateCallback mMockStateCallback;
@Mock private ISipDelegateMessageCallback mMockMessageCallback;
@Mock private SipTransportController.SipDelegateControllerFactory
@@ -116,6 +118,7 @@
public void setUp() throws Exception {
super.setUp();
doReturn(mSmsPackageName).when(mMockRoleManager).getRoleHolders(RoleManager.ROLE_SMS);
+ doReturn(mImsRegistration).when(mRcsManager).getImsRegistration();
mSmsPackageName.add(TEST_PACKAGE_NAME);
doAnswer(invocation -> {
Integer subId = invocation.getArgument(0);
@@ -124,7 +127,7 @@
SipDelegateController c = getMockDelegateController(subId, packageName, request);
assertNotNull("create called with no corresponding controller set up", c);
return c;
- }).when(mMockDelegateControllerFactory).create(anyInt(), any(), anyString(), any(),
+ }).when(mMockDelegateControllerFactory).create(anyInt(), any(), anyString(), any(), any(),
any(), any(), any());
}
@@ -289,6 +292,8 @@
SipDelegateController c = injectMockDelegateController(TEST_PACKAGE_NAME, r);
createDelegateAndVerify(controller, c, r, r.getFeatureTags(), Collections.emptySet(),
TEST_PACKAGE_NAME);
+ verifyDelegateRegistrationChangedEvent(1 /*times*/, 0 /*waitMs*/);
+ triggerFullNetworkRegistrationAndVerify(controller, c);
}
@SmallTest
@@ -300,9 +305,12 @@
SipDelegateController c = injectMockDelegateController(TEST_PACKAGE_NAME, r);
createDelegateAndVerify(controller, c, r, r.getFeatureTags(), Collections.emptySet(),
TEST_PACKAGE_NAME);
+ verifyDelegateRegistrationChangedEvent(1, 0 /*throttle*/);
destroyDelegateAndVerify(controller, c, false,
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+ verifyDelegateRegistrationChangedEvent(2 /*times*/, 0 /*waitMs*/);
+ triggerFullNetworkRegistrationAndVerifyNever(controller, c);
}
@SmallTest
@@ -323,7 +331,8 @@
@SmallTest
@Test
public void createTwoAndDenyOverlappingTags() throws Exception {
- SipTransportController controller = setupLiveTransportController();
+ SipTransportController controller = setupLiveTransportController(0 /*reeval*/,
+ THROTTLE_MS);
// First delegate requests RCS message + File transfer
ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
@@ -333,6 +342,8 @@
firstDelegateRequest);
createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
Collections.emptySet(), TEST_PACKAGE_NAME);
+ // there is a delay in the indication to update reg, so it should not happen yet.
+ verifyNoDelegateRegistrationChangedEvent();
// First delegate requests RCS message + Group RCS message. For this delegate, single RCS
// message should be denied.
@@ -346,12 +357,14 @@
secondDelegateRequest);
createDelegateAndVerify(controller, c2, secondDelegateRequest, grantedAndDenied.first,
grantedAndDenied.second, TEST_PACKAGE_NAME, 1);
+ // a reg changed event should happen after wait.
+ verifyDelegateRegistrationChangedEvent(1, 2 * THROTTLE_MS);
}
@SmallTest
@Test
public void createTwoAndTriggerRoleChange() throws Exception {
- SipTransportController controller = setupLiveTransportController();
+ SipTransportController controller = setupLiveTransportController(0 /*reeval*/, THROTTLE_MS);
DelegateRequest firstDelegateRequest = getBaseDelegateRequest();
Set<FeatureTagState> firstDeniedTags = getDeniedTagsForReason(
@@ -361,6 +374,7 @@
firstDelegateRequest);
createDelegateAndVerify(controller, c1, firstDelegateRequest,
firstDelegateRequest.getFeatureTags(), Collections.emptySet(), TEST_PACKAGE_NAME);
+ verifyDelegateRegistrationChangedEvent(1 /*times*/, THROTTLE_MS);
DelegateRequest secondDelegateRequest = getBaseDelegateRequest();
Set<FeatureTagState> secondDeniedTags = getDeniedTagsForReason(
@@ -378,6 +392,10 @@
CompletableFuture<Boolean> pendingC2Change = setChangeSupportedFeatureTagsFuture(c2,
secondDelegateRequest.getFeatureTags(), Collections.emptySet());
setSmsRoleAndEvaluate(controller, TEST_PACKAGE_NAME_2);
+ // swapping roles should trigger a deregistration event on the ImsService side.
+ verifyDelegateDeregistrationEvent();
+ // there should also not be any new registration changed events
+ verifyDelegateRegistrationChangedEvent(1 /*times*/, THROTTLE_MS);
// trigger completion stage to run
waitForExecutorAction(mExecutorService, TIMEOUT_MS);
verify(c1).changeSupportedFeatureTags(Collections.emptySet(), firstDeniedTags);
@@ -394,12 +412,14 @@
// ensure we are not blocking executor here
waitForExecutorAction(mExecutorService, TIMEOUT_MS);
completePendingChange(pendingC2Change, true);
+ // verify we now get a second registration changed event
+ verifyDelegateRegistrationChangedEvent(2 /*times*/, THROTTLE_MS);
}
@SmallTest
@Test
public void createTwoAndDestroyOlder() throws Exception {
- SipTransportController controller = setupLiveTransportController();
+ SipTransportController controller = setupLiveTransportController(0 /*reeval*/, THROTTLE_MS);
// First delegate requests RCS message + File transfer
ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
@@ -409,6 +429,7 @@
firstDelegateRequest);
createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
Collections.emptySet(), TEST_PACKAGE_NAME);
+ verifyNoDelegateRegistrationChangedEvent();
// First delegate requests RCS message + Group RCS message. For this delegate, single RCS
// message should be denied.
@@ -422,6 +443,7 @@
secondDelegateRequest);
createDelegateAndVerify(controller, c2, secondDelegateRequest, grantedAndDenied.first,
grantedAndDenied.second, TEST_PACKAGE_NAME, 1);
+ verifyNoDelegateRegistrationChangedEvent();
// Destroy the firstDelegate, which should now cause all previously denied tags to be
// granted to the new delegate.
@@ -433,12 +455,14 @@
assertTrue(waitForExecutorAction(mExecutorService, TIMEOUT_MS));
verify(c2).changeSupportedFeatureTags(secondDelegate, Collections.emptySet());
completePendingChange(pendingC2Change, true);
+
+ verifyDelegateRegistrationChangedEvent(1 /*times*/, THROTTLE_MS);
}
@SmallTest
@Test
public void testThrottling() throws Exception {
- SipTransportController controller = setupLiveTransportController(THROTTLE_MS);
+ SipTransportController controller = setupLiveTransportController(THROTTLE_MS, THROTTLE_MS);
// First delegate requests RCS message + File transfer
ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
@@ -477,12 +501,14 @@
thirdDelegateRequest, grantedAndDeniedC3.first, grantedAndDeniedC3.second,
TEST_PACKAGE_NAME);
+ verifyNoDelegateRegistrationChangedEvent();
assertTrue(scheduleDelayedWait(2 * THROTTLE_MS));
verifyDelegateChanged(c1, pendingC1Change, firstDelegate, Collections.emptySet(), 0);
verifyDelegateChanged(c2, pendingC2Change, grantedAndDeniedC2.first,
grantedAndDeniedC2.second, 0);
verifyDelegateChanged(c3, pendingC3Change, grantedAndDeniedC3.first,
grantedAndDeniedC3.second, 0);
+ verifyDelegateRegistrationChangedEvent(1, 2 * THROTTLE_MS);
// Destroy the first and second controller in quick succession, this should only generate
// one reevaluate for the third controller.
@@ -505,6 +531,7 @@
verify(c3).changeSupportedFeatureTags(thirdDelegate, Collections.emptySet());
// In total reeval should have only been called twice.
verify(c3, times(2)).changeSupportedFeatureTags(any(), any());
+ verifyDelegateRegistrationChangedEvent(2 /*times*/, 2 * THROTTLE_MS);
}
@SmallTest
@@ -518,6 +545,7 @@
firstDelegateRequest);
createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
Collections.emptySet(), TEST_PACKAGE_NAME);
+ verifyDelegateRegistrationChangedEvent(1 /*times*/, 0 /*waitMs*/);
CompletableFuture<Integer> pendingDestroy = setDestroyFuture(c1, true,
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
@@ -525,6 +553,7 @@
waitForExecutorAction(mExecutorService, TIMEOUT_MS);
verifyDestroyDelegate(controller, c1, pendingDestroy, true /*force*/,
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+ verifyDelegateRegistrationChangedEvent(2 /*times*/, 0 /*waitMs*/);
}
@SmallTest
@@ -545,6 +574,7 @@
waitForExecutorAction(mExecutorService, TIMEOUT_MS);
verifyDestroyDelegate(controller, c1, pendingDestroy, true /*force*/,
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+ verifyDelegateRegistrationChangedEvent(1, 0 /*waitMs*/);
}
@SmallTest
@@ -563,6 +593,7 @@
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
controller.onDestroy();
waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+ verifyDelegateDeregistrationEvent();
// verify change was called.
verify(c1).destroy(true /*force*/,
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
@@ -575,7 +606,7 @@
@SmallTest
@Test
public void testTimingSubIdChangedAndCreateNewSubId() throws Exception {
- SipTransportController controller = setupLiveTransportController(THROTTLE_MS);
+ SipTransportController controller = setupLiveTransportController(THROTTLE_MS, 0);
ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
@@ -638,13 +669,14 @@
}
private SipTransportController setupLiveTransportController() throws Exception {
- return setupLiveTransportController(0 /*throttleMs*/);
+ return setupLiveTransportController(0 /*throttleMs*/, 0 /*regDelayMs*/);
}
- private SipTransportController setupLiveTransportController(int throttleMs) throws Exception {
+ private SipTransportController setupLiveTransportController(int throttleMs, int regDelayMs)
+ throws Exception {
mExecutorService = Executors.newSingleThreadScheduledExecutor();
SipTransportController controller = createControllerAndThrottle(mExecutorService,
- throttleMs);
+ throttleMs, regDelayMs);
doReturn(mSipTransport).when(mRcsManager).getSipTransport();
controller.onAssociatedSubscriptionUpdated(TEST_SUB_ID);
controller.onRcsConnected(mRcsManager);
@@ -743,6 +775,24 @@
completePendingDestroy(pendingDestroy, reason);
}
+ private void triggerFullNetworkRegistrationAndVerify(SipTransportController controller,
+ SipDelegateController delegateController) {
+ controller.triggerFullNetworkRegistration(TEST_SUB_ID,
+ delegateController.getSipDelegateInterface(), 403, "forbidden");
+ // move to internal & trigger event
+ waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+ verify(delegateController).triggerFullNetworkRegistration(403, "forbidden");
+ }
+
+ private void triggerFullNetworkRegistrationAndVerifyNever(SipTransportController controller,
+ SipDelegateController delegateController) {
+ controller.triggerFullNetworkRegistration(TEST_SUB_ID,
+ delegateController.getSipDelegateInterface(), 403, "forbidden");
+ // move to internal & potentially trigger event
+ waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+ verify(delegateController, never()).triggerFullNetworkRegistration(anyInt(), anyString());
+ }
+
private DelegateRequest getBaseDelegateRequest() {
Set<String> featureTags = new ArraySet<>();
featureTags.add(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG);
@@ -807,12 +857,31 @@
waitForExecutorAction(mExecutorService, TIMEOUT_MS);
}
+ private void verifyNoDelegateRegistrationChangedEvent() throws Exception {
+ // event is scheduled and then executed.
+ waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+ verify(mImsRegistration, never()).triggerUpdateSipDelegateRegistration();
+ }
+
+ private void verifyDelegateRegistrationChangedEvent(int times, int waitMs)
+ throws Exception {
+ // event is scheduled and then executed.
+ assertTrue(scheduleDelayedWait(waitMs));
+ waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+ verify(mImsRegistration, times(times)).triggerUpdateSipDelegateRegistration();
+ }
+
+
+ private void verifyDelegateDeregistrationEvent() throws Exception {
+ verify(mImsRegistration).triggerSipDelegateDeregistration();
+ }
+
private SipTransportController createController(ScheduledExecutorService e) {
- return createControllerAndThrottle(e, 0 /*throttleMs*/);
+ return createControllerAndThrottle(e, 0 /*throttleMs*/, 0 /*regDelayMs*/);
}
private SipTransportController createControllerAndThrottle(ScheduledExecutorService e,
- int throttleMs) {
+ int throttleMs, int regDelayMs) {
return new SipTransportController(mContext, 0 /*slotId*/, TEST_SUB_ID,
mMockDelegateControllerFactory, mMockRoleManager,
// Remove delays for testing.
@@ -824,7 +893,7 @@
@Override
public int getUpdateRegistrationDelayMilliseconds() {
- return 0;
+ return regDelayMs;
}
}, e);
}