Merge "Make action provision protected broadcast"
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 1fcf3b6..a28afbc 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;
@@ -2258,7 +2257,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;
@@ -2693,30 +2692,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.");
@@ -2775,7 +2755,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();
         }
@@ -2828,13 +2808,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());
                 }
@@ -4559,7 +4541,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..b5950aa 100644
--- a/src/com/android/services/telephony/rcs/SipTransportController.java
+++ b/src/com/android/services/telephony/rcs/SipTransportController.java
@@ -25,6 +25,7 @@
 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 +207,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 +350,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 +378,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 +401,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,6 +434,35 @@
         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.
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..89c3ce3 100644
--- a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
@@ -124,7 +124,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 +289,7 @@
         SipDelegateController c = injectMockDelegateController(TEST_PACKAGE_NAME, r);
         createDelegateAndVerify(controller, c, r, r.getFeatureTags(), Collections.emptySet(),
                 TEST_PACKAGE_NAME);
+        triggerFullNetworkRegistrationAndVerify(controller, c);
     }
 
     @SmallTest
@@ -303,6 +304,8 @@
 
         destroyDelegateAndVerify(controller, c, false,
                 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+
+        triggerFullNetworkRegistrationAndVerifyNever(controller, c);
     }
 
     @SmallTest
@@ -743,6 +746,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);