Loading src/java/com/android/internal/telephony/imsphone/ImsPhone.java +142 −8 Original line number Diff line number Diff line Loading @@ -77,7 +77,9 @@ import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsSsData; import android.telephony.ims.ImsSsInfo; import android.telephony.ims.RegistrationManager; import android.telephony.ims.feature.ImsFeature; import android.text.TextUtils; import android.util.LocalLog; import com.android.ims.FeatureConnector; import com.android.ims.ImsEcbm; Loading Loading @@ -106,8 +108,11 @@ import com.android.internal.telephony.dataconnection.TransportManager; import com.android.internal.telephony.emergency.EmergencyNumberTracker; import com.android.internal.telephony.gsm.GsmMmiCode; import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.util.NotificationChannelController; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -220,7 +225,12 @@ public class ImsPhone extends ImsPhoneBase { private final RegistrantList mSilentRedialRegistrants = new RegistrantList(); private int mImsRegistrationState = RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; private final LocalLog mRegLocalLog = new LocalLog(100); private TelephonyMetrics mMetrics; // The helper class to receive and store the MmTel and RCS registration status updated. private ImsRegistrationCallbackHelper mImsMmTelRegistrationHelper; private ImsRegistrationCallbackHelper mImsRcsRegistrationHelper; private boolean mRoaming = false; Loading Loading @@ -318,6 +328,10 @@ public class ImsPhone extends ImsPhoneBase { mPhoneId = mDefaultPhone.getPhoneId(); mMetrics = TelephonyMetrics.getInstance(); initImsRegistration(); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); mWakeLock.setReferenceCounted(false); Loading Loading @@ -428,11 +442,19 @@ public class ImsPhone extends ImsPhoneBase { public void connectionReady(RcsFeatureManager manager) throws ImsException { logi("RcsFeatureManager is ready"); mRcsManager = manager; // Listen to the IMS RCS registration status changed mRcsManager.registerImsRegistrationCallback( mImsRcsRegistrationHelper.getCallbackBinder()); } @Override public void connectionUnavailable() { logi("RcsFeatureManager is unavailable"); resetImsRegistrationState(ImsFeature.FEATURE_RCS); if (mRcsManager != null) { mRcsManager.release(); } mRcsManager = null; } }; Loading Loading @@ -1845,9 +1867,23 @@ public class ImsPhone extends ImsPhoneBase { mCT.getImsRegistrationTech(callback); } /** * Get the IMS RCS registration technology for this Phone. */ public void getImsRcsRegistrationTech(Consumer<Integer> callback) { mRcsManager.getImsRegistrationTech(callback); } @Override public void getImsRegistrationState(Consumer<Integer> callback) { callback.accept(mImsRegistrationState); callback.accept(mImsMmTelRegistrationHelper.getImsRegistrationState()); } /** * Retrieve the current RCS registration state. */ public void getImsRcsRegistrationState(Consumer<Integer> callback) { callback.accept(mImsRcsRegistrationHelper.getImsRegistrationState()); } @Override Loading @@ -1857,18 +1893,20 @@ public class ImsPhone extends ImsPhoneBase { @Override public boolean isImsRegistered() { return mImsRegistrationState == RegistrationManager.REGISTRATION_STATE_REGISTERED; return mImsMmTelRegistrationHelper.isImsRegistered(); } // Not used, but not removed due to UnsupportedAppUsage tag. @UnsupportedAppUsage public void setImsRegistered(boolean isRegistered) { mImsRegistrationState = isRegistered ? RegistrationManager.REGISTRATION_STATE_REGISTERED : RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; mImsMmTelRegistrationHelper.updateRegistrationState( isRegistered ? RegistrationManager.REGISTRATION_STATE_REGISTERED : RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); } public void setImsRegistrationState(@RegistrationManager.ImsRegistrationState int value) { mImsRegistrationState = value; if (DBG) logd("setImsRegistrationState: " + value); mImsMmTelRegistrationHelper.updateRegistrationState(value); } @Override Loading Loading @@ -2125,8 +2163,97 @@ public class ImsPhone extends ImsPhoneBase { && psInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_IWLAN; } public RegistrationManager.RegistrationCallback getImsMmTelRegistrationCallback() { return mImsMmTelRegistrationHelper.getCallback(); } /** * Reset the IMS registration state. */ public void resetImsRegistrationState(int featureType) { if (DBG) logd("resetImsRegistrationState: feature=" + featureType); if (featureType == ImsFeature.FEATURE_MMTEL) { mImsMmTelRegistrationHelper.reset(); } else if (featureType == ImsFeature.FEATURE_RCS) { mImsRcsRegistrationHelper.reset(); } } private void initImsRegistration() { mImsMmTelRegistrationHelper = new ImsRegistrationCallbackHelper(mMmTelRegistrationUpdate); mImsRcsRegistrationHelper = new ImsRegistrationCallbackHelper(mRcsRegistrationUpdate); } private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mMmTelRegistrationUpdate = new ImsRegistrationCallbackHelper.ImsRegistrationUpdate() { @Override public void handleImsRegistered(int imsRadioTech) { if (DBG) { logd("onImsMmTelConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsMmTelConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); setServiceState(ServiceState.STATE_IN_SERVICE); mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.CONNECTED, null); } @Override public void handleImsRegistering(int imsRadioTech) { if (DBG) { logd("onImsMmTelProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsMmTelProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.PROGRESSING, null); } @Override public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) { if (DBG) logd("onImsMmTelDisconnected imsReasonInfo=" + imsReasonInfo); mRegLocalLog.log("onImsMmTelDisconnected imsRadioTech=" + imsReasonInfo); setServiceState(ServiceState.STATE_OUT_OF_SERVICE); processDisconnectReason(imsReasonInfo); mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.DISCONNECTED, imsReasonInfo); } @Override public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) { if (DBG) logd("handleImsSubscriberAssociatedUriChanged"); setCurrentSubscriberUris(uris); } }; private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mRcsRegistrationUpdate = new ImsRegistrationCallbackHelper.ImsRegistrationUpdate() { @Override public void handleImsRegistered(int imsRadioTech) { if (DBG) logd("handle RCS registered"); } @Override public void handleImsRegistering(int imsRadioTech) { if (DBG) logd("handle RCS registering"); } @Override public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) { if (DBG) logd("handle RCS unregistered"); } @Override public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) { if (DBG) logd("handle RCS SubscriberAssociatedUriChanged"); } }; @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println("ImsPhone extends:"); super.dump(fd, pw, args); pw.flush(); Loading @@ -2140,9 +2267,16 @@ public class ImsPhone extends ImsPhoneBase { pw.println(" mIsPhoneInEcmState = " + isInEcm()); pw.println(" mEcmExitRespRegistrant = " + mEcmExitRespRegistrant); pw.println(" mSilentRedialRegistrants = " + mSilentRedialRegistrants); pw.println(" mImsRegistrationState = " + mImsRegistrationState); pw.println(" mImsMmTelRegistrationState = " + mImsMmTelRegistrationHelper.getImsRegistrationState()); pw.println(" mImsRcsRegistrationState = " + mImsRcsRegistrationHelper.getImsRegistrationState()); pw.println(" mRoaming = " + mRoaming); pw.println(" mSsnRegistrants = " + mSsnRegistrants); pw.println(" Registration Log:"); pw.increaseIndent(); mRegLocalLog.dump(pw); pw.decreaseIndent(); pw.flush(); } Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +2 −63 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkStats; import android.net.Uri; import android.os.AsyncResult; import android.os.Bundle; import android.os.Handler; Loading @@ -47,7 +46,6 @@ import android.provider.Settings; import android.sysprop.TelephonyProperties; import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.telephony.AccessNetworkConstants; import android.telephony.CallQuality; import android.telephony.CarrierConfigManager; import android.telephony.DisconnectCause; Loading @@ -64,7 +62,6 @@ import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.ImsSuppServiceNotification; import android.telephony.ims.ProvisioningManager; import android.telephony.ims.RegistrationManager; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; Loading Loading @@ -108,7 +105,6 @@ import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.imsphone.ImsPhone.ImsDialArgs; import com.android.internal.telephony.metrics.CallQualityMetrics; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState; import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession; import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.ImsCommand; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -669,7 +665,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { log("startListeningForCalls"); mOperationLocalLog.log("startListeningForCalls - Connecting to ImsService"); mImsManager.open(mMmTelFeatureListener); mImsManager.addRegistrationCallback(mImsRegistrationCallback); mImsManager.addRegistrationCallback(mPhone.getImsMmTelRegistrationCallback()); mImsManager.addCapabilitiesCallback(mImsCapabilityCallback); mImsManager.setConfigListener(mImsConfigListener); Loading Loading @@ -3205,58 +3201,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } }; private final RegistrationManager.RegistrationCallback mImsRegistrationCallback = new RegistrationManager.RegistrationCallback() { @Override public void onRegistered(int imsRadioTech) { if (DBG) { log("onImsConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); mPhone.setServiceState(ServiceState.STATE_IN_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_REGISTERED); mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(), ImsConnectionState.State.CONNECTED, null); } @Override public void onRegistering(int imsRadioTech) { if (DBG) { log("onImsProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_REGISTERING); mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(), ImsConnectionState.State.PROGRESSING, null); } @Override public void onUnregistered(ImsReasonInfo imsReasonInfo) { if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo); mRegLocalLog.log("onImsDisconnected imsRadioTech=" + imsReasonInfo); mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); mPhone.processDisconnectReason(imsReasonInfo); mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(), ImsConnectionState.State.DISCONNECTED, imsReasonInfo); } @Override public void onSubscriberAssociatedUriChanged(Uri[] uris) { if (DBG) log("registrationAssociatedUriChanged"); mPhone.setCurrentSubscriberUris(uris); } }; private final ImsMmTelManager.CapabilityCallback mImsCapabilityCallback = new ImsMmTelManager.CapabilityCallback() { @Override Loading Loading @@ -3753,10 +3697,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { pw.println(" mCallQualityMetrics=" + mCallQualityMetrics); pw.println(" mCallQualityMetricsHistory=" + mCallQualityMetricsHistory); pw.println(" mIsConferenceEventPackageHandlingEnabled=" + mIsConferenceEventPackageEnabled); pw.println(" Registration Log:"); pw.increaseIndent(); mRegLocalLog.dump(pw); pw.decreaseIndent(); pw.println(" Event Log:"); pw.increaseIndent(); mOperationLocalLog.dump(pw); Loading Loading @@ -4257,8 +4197,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { boolean tmpIsVideoCallEnabled = isVideoCallEnabled(); mMmTelCapabilities = new MmTelFeature.MmTelCapabilities(); mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); mPhone.resetImsRegistrationState(ImsFeature.FEATURE_MMTEL); mPhone.processDisconnectReason(new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN, ImsReasonInfo.CODE_UNSPECIFIED)); boolean isVideoEnabled = isVideoCallEnabled(); Loading src/java/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelper.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony.imsphone; import android.annotation.NonNull; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; import com.android.internal.telephony.util.HandlerExecutor; import java.util.concurrent.Executor; /** * A helper class to manager the ImsRegistrationCallback can notify the state changed to listener. */ public class ImsRegistrationCallbackHelper { private static final String TAG = "ImsRegCallbackHelper"; /** * The interface to receive IMS registration updated. */ public interface ImsRegistrationUpdate { /** * Handle the callback when IMS is registered. */ void handleImsRegistered(int imsRadioTech); /** * Handle the callback when IMS is registering. */ void handleImsRegistering(int imsRadioTech); /** * Handle the callback when IMS is unregistered. */ void handleImsUnregistered(ImsReasonInfo imsReasonInfo); /** * Handle the callback when the list of subscriber {@link Uri}s associated with this IMS * subscription changed. */ void handleImsSubscriberAssociatedUriChanged(Uri[] uris); } private ImsRegistrationUpdate mImsRegistrationUpdate; private int mRegistrationState = RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; private final RegistrationManager.RegistrationCallback mImsRegistrationCallback = new RegistrationManager.RegistrationCallback() { @Override public void onRegistered(int imsRadioTech) { updateRegistrationState(RegistrationManager.REGISTRATION_STATE_REGISTERED); mImsRegistrationUpdate.handleImsRegistered(imsRadioTech); } @Override public void onRegistering(int imsRadioTech) { updateRegistrationState(RegistrationManager.REGISTRATION_STATE_REGISTERING); mImsRegistrationUpdate.handleImsRegistering(imsRadioTech); } @Override public void onUnregistered(ImsReasonInfo imsReasonInfo) { updateRegistrationState(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); mImsRegistrationUpdate.handleImsUnregistered(imsReasonInfo); } @Override public void onSubscriberAssociatedUriChanged(Uri[] uris) { mImsRegistrationUpdate.handleImsSubscriberAssociatedUriChanged(uris); } }; public ImsRegistrationCallbackHelper(@NonNull ImsRegistrationUpdate registrationUpdate) { mImsRegistrationCallback.setExecutor(getThreadExecutor()); mImsRegistrationUpdate = registrationUpdate; } /** * Reset the IMS registration state. */ public void reset() { Log.d(TAG, "reset"); updateRegistrationState(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); } /** * Update the latest IMS registration state. */ public synchronized void updateRegistrationState( @RegistrationManager.ImsRegistrationState int newState) { Log.d(TAG, "updateRegistrationState: registration state from " + mRegistrationState + " to " + newState); mRegistrationState = newState; } public int getImsRegistrationState() { return mRegistrationState; } public boolean isImsRegistered() { return mRegistrationState == RegistrationManager.REGISTRATION_STATE_REGISTERED; } public RegistrationManager.RegistrationCallback getCallback() { return mImsRegistrationCallback; } public IImsRegistrationCallback getCallbackBinder() { return mImsRegistrationCallback.getBinder(); } private Executor getThreadExecutor() { if (Looper.myLooper() == null) { Looper.prepare(); } return new HandlerExecutor(new Handler(Looper.myLooper())); } } tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +0 −41 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import android.telephony.ims.ImsCallSession; import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.RegistrationManager; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; Loading Loading @@ -88,7 +87,6 @@ import org.mockito.stubbing.Answer; public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsPhoneCallTracker mCTUT; private MmTelFeature.Listener mMmTelListener; private RegistrationManager.RegistrationCallback mRegistrationCallback; private ImsMmTelManager.CapabilityCallback mCapabilityCallback; private ImsCall.Listener mImsCallListener; private ImsCall mImsCall; Loading Loading @@ -196,12 +194,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { }).when(mImsManager).makeCall(eq(mImsCallProfile), (String []) any(), (ImsCall.Listener) any()); doAnswer(invocation -> { mRegistrationCallback = invocation.getArgument(0); return mRegistrationCallback; }).when(mImsManager).addRegistrationCallback( any(RegistrationManager.RegistrationCallback.class)); doAnswer(invocation -> { mCapabilityCallback = (ImsMmTelManager.CapabilityCallback) invocation.getArguments()[0]; return mCapabilityCallback; Loading Loading @@ -238,39 +230,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { super.tearDown(); } @Test @SmallTest public void testImsRegistered() { // when IMS is registered mRegistrationCallback.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN); // then service state should be IN_SERVICE and ImsPhone state set to registered verify(mImsPhone).setServiceState(eq(ServiceState.STATE_IN_SERVICE)); verify(mImsPhone).setImsRegistrationState(eq( RegistrationManager.REGISTRATION_STATE_REGISTERED)); } @Test @SmallTest public void testImsRegistering() { // when IMS is registering mRegistrationCallback.onRegistering(ImsRegistrationImplBase.REGISTRATION_TECH_LTE); // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE)); verify(mImsPhone).setImsRegistrationState(eq( RegistrationManager.REGISTRATION_STATE_REGISTERING)); } @Test @SmallTest public void testImsDeregistered() { // when IMS is deregistered mRegistrationCallback.onUnregistered(new ImsReasonInfo()); // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE)); verify(mImsPhone).setImsRegistrationState(eq( RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED)); } @Test @SmallTest public void testVowifiDisabledOnLte() { Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.telephony.ServiceState; import android.telephony.ims.ImsCallProfile; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; Loading Loading @@ -665,6 +666,27 @@ public class ImsPhoneTest extends TelephonyTest { intent.getValue().getStringExtra(Phone.EXTRA_KEY_NOTIFICATION_MESSAGE)); } @Test @SmallTest public void testRegisteringImsRcsRegistrationCallback() throws Exception { RcsFeatureManager rcsFeatureManager = mock(RcsFeatureManager.class); // When initialized RcsFeatureManager and mImsPhoneUT.initRcsFeatureManager(); assertNotNull(mImsPhoneUT.mRcsManagerConnector); // When connection is ready, the register IMS registration callback should be called. mImsPhoneUT.mRcsFeatureConnectorListener.connectionReady(rcsFeatureManager); verify(rcsFeatureManager).registerImsRegistrationCallback( any(IImsRegistrationCallback.class)); // When connection is unavailable, the IMS registration state should be not registered. mImsPhoneUT.mRcsFeatureConnectorListener.connectionUnavailable(); Consumer<Integer> registrationState = mock(Consumer.class); mImsPhoneUT.getImsRcsRegistrationState(registrationState); verify(registrationState).accept(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); } @Test @SmallTest public void testImsRegistered() throws Exception { Loading Loading
src/java/com/android/internal/telephony/imsphone/ImsPhone.java +142 −8 Original line number Diff line number Diff line Loading @@ -77,7 +77,9 @@ import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsSsData; import android.telephony.ims.ImsSsInfo; import android.telephony.ims.RegistrationManager; import android.telephony.ims.feature.ImsFeature; import android.text.TextUtils; import android.util.LocalLog; import com.android.ims.FeatureConnector; import com.android.ims.ImsEcbm; Loading Loading @@ -106,8 +108,11 @@ import com.android.internal.telephony.dataconnection.TransportManager; import com.android.internal.telephony.emergency.EmergencyNumberTracker; import com.android.internal.telephony.gsm.GsmMmiCode; import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.util.NotificationChannelController; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -220,7 +225,12 @@ public class ImsPhone extends ImsPhoneBase { private final RegistrantList mSilentRedialRegistrants = new RegistrantList(); private int mImsRegistrationState = RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; private final LocalLog mRegLocalLog = new LocalLog(100); private TelephonyMetrics mMetrics; // The helper class to receive and store the MmTel and RCS registration status updated. private ImsRegistrationCallbackHelper mImsMmTelRegistrationHelper; private ImsRegistrationCallbackHelper mImsRcsRegistrationHelper; private boolean mRoaming = false; Loading Loading @@ -318,6 +328,10 @@ public class ImsPhone extends ImsPhoneBase { mPhoneId = mDefaultPhone.getPhoneId(); mMetrics = TelephonyMetrics.getInstance(); initImsRegistration(); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); mWakeLock.setReferenceCounted(false); Loading Loading @@ -428,11 +442,19 @@ public class ImsPhone extends ImsPhoneBase { public void connectionReady(RcsFeatureManager manager) throws ImsException { logi("RcsFeatureManager is ready"); mRcsManager = manager; // Listen to the IMS RCS registration status changed mRcsManager.registerImsRegistrationCallback( mImsRcsRegistrationHelper.getCallbackBinder()); } @Override public void connectionUnavailable() { logi("RcsFeatureManager is unavailable"); resetImsRegistrationState(ImsFeature.FEATURE_RCS); if (mRcsManager != null) { mRcsManager.release(); } mRcsManager = null; } }; Loading Loading @@ -1845,9 +1867,23 @@ public class ImsPhone extends ImsPhoneBase { mCT.getImsRegistrationTech(callback); } /** * Get the IMS RCS registration technology for this Phone. */ public void getImsRcsRegistrationTech(Consumer<Integer> callback) { mRcsManager.getImsRegistrationTech(callback); } @Override public void getImsRegistrationState(Consumer<Integer> callback) { callback.accept(mImsRegistrationState); callback.accept(mImsMmTelRegistrationHelper.getImsRegistrationState()); } /** * Retrieve the current RCS registration state. */ public void getImsRcsRegistrationState(Consumer<Integer> callback) { callback.accept(mImsRcsRegistrationHelper.getImsRegistrationState()); } @Override Loading @@ -1857,18 +1893,20 @@ public class ImsPhone extends ImsPhoneBase { @Override public boolean isImsRegistered() { return mImsRegistrationState == RegistrationManager.REGISTRATION_STATE_REGISTERED; return mImsMmTelRegistrationHelper.isImsRegistered(); } // Not used, but not removed due to UnsupportedAppUsage tag. @UnsupportedAppUsage public void setImsRegistered(boolean isRegistered) { mImsRegistrationState = isRegistered ? RegistrationManager.REGISTRATION_STATE_REGISTERED : RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; mImsMmTelRegistrationHelper.updateRegistrationState( isRegistered ? RegistrationManager.REGISTRATION_STATE_REGISTERED : RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); } public void setImsRegistrationState(@RegistrationManager.ImsRegistrationState int value) { mImsRegistrationState = value; if (DBG) logd("setImsRegistrationState: " + value); mImsMmTelRegistrationHelper.updateRegistrationState(value); } @Override Loading Loading @@ -2125,8 +2163,97 @@ public class ImsPhone extends ImsPhoneBase { && psInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_IWLAN; } public RegistrationManager.RegistrationCallback getImsMmTelRegistrationCallback() { return mImsMmTelRegistrationHelper.getCallback(); } /** * Reset the IMS registration state. */ public void resetImsRegistrationState(int featureType) { if (DBG) logd("resetImsRegistrationState: feature=" + featureType); if (featureType == ImsFeature.FEATURE_MMTEL) { mImsMmTelRegistrationHelper.reset(); } else if (featureType == ImsFeature.FEATURE_RCS) { mImsRcsRegistrationHelper.reset(); } } private void initImsRegistration() { mImsMmTelRegistrationHelper = new ImsRegistrationCallbackHelper(mMmTelRegistrationUpdate); mImsRcsRegistrationHelper = new ImsRegistrationCallbackHelper(mRcsRegistrationUpdate); } private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mMmTelRegistrationUpdate = new ImsRegistrationCallbackHelper.ImsRegistrationUpdate() { @Override public void handleImsRegistered(int imsRadioTech) { if (DBG) { logd("onImsMmTelConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsMmTelConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); setServiceState(ServiceState.STATE_IN_SERVICE); mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.CONNECTED, null); } @Override public void handleImsRegistering(int imsRadioTech) { if (DBG) { logd("onImsMmTelProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsMmTelProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.PROGRESSING, null); } @Override public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) { if (DBG) logd("onImsMmTelDisconnected imsReasonInfo=" + imsReasonInfo); mRegLocalLog.log("onImsMmTelDisconnected imsRadioTech=" + imsReasonInfo); setServiceState(ServiceState.STATE_OUT_OF_SERVICE); processDisconnectReason(imsReasonInfo); mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.DISCONNECTED, imsReasonInfo); } @Override public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) { if (DBG) logd("handleImsSubscriberAssociatedUriChanged"); setCurrentSubscriberUris(uris); } }; private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mRcsRegistrationUpdate = new ImsRegistrationCallbackHelper.ImsRegistrationUpdate() { @Override public void handleImsRegistered(int imsRadioTech) { if (DBG) logd("handle RCS registered"); } @Override public void handleImsRegistering(int imsRadioTech) { if (DBG) logd("handle RCS registering"); } @Override public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) { if (DBG) logd("handle RCS unregistered"); } @Override public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) { if (DBG) logd("handle RCS SubscriberAssociatedUriChanged"); } }; @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println("ImsPhone extends:"); super.dump(fd, pw, args); pw.flush(); Loading @@ -2140,9 +2267,16 @@ public class ImsPhone extends ImsPhoneBase { pw.println(" mIsPhoneInEcmState = " + isInEcm()); pw.println(" mEcmExitRespRegistrant = " + mEcmExitRespRegistrant); pw.println(" mSilentRedialRegistrants = " + mSilentRedialRegistrants); pw.println(" mImsRegistrationState = " + mImsRegistrationState); pw.println(" mImsMmTelRegistrationState = " + mImsMmTelRegistrationHelper.getImsRegistrationState()); pw.println(" mImsRcsRegistrationState = " + mImsRcsRegistrationHelper.getImsRegistrationState()); pw.println(" mRoaming = " + mRoaming); pw.println(" mSsnRegistrants = " + mSsnRegistrants); pw.println(" Registration Log:"); pw.increaseIndent(); mRegLocalLog.dump(pw); pw.decreaseIndent(); pw.flush(); } Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +2 −63 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkStats; import android.net.Uri; import android.os.AsyncResult; import android.os.Bundle; import android.os.Handler; Loading @@ -47,7 +46,6 @@ import android.provider.Settings; import android.sysprop.TelephonyProperties; import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.telephony.AccessNetworkConstants; import android.telephony.CallQuality; import android.telephony.CarrierConfigManager; import android.telephony.DisconnectCause; Loading @@ -64,7 +62,6 @@ import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.ImsSuppServiceNotification; import android.telephony.ims.ProvisioningManager; import android.telephony.ims.RegistrationManager; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; Loading Loading @@ -108,7 +105,6 @@ import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.imsphone.ImsPhone.ImsDialArgs; import com.android.internal.telephony.metrics.CallQualityMetrics; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState; import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession; import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.ImsCommand; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -669,7 +665,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { log("startListeningForCalls"); mOperationLocalLog.log("startListeningForCalls - Connecting to ImsService"); mImsManager.open(mMmTelFeatureListener); mImsManager.addRegistrationCallback(mImsRegistrationCallback); mImsManager.addRegistrationCallback(mPhone.getImsMmTelRegistrationCallback()); mImsManager.addCapabilitiesCallback(mImsCapabilityCallback); mImsManager.setConfigListener(mImsConfigListener); Loading Loading @@ -3205,58 +3201,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } }; private final RegistrationManager.RegistrationCallback mImsRegistrationCallback = new RegistrationManager.RegistrationCallback() { @Override public void onRegistered(int imsRadioTech) { if (DBG) { log("onImsConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsConnected imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); mPhone.setServiceState(ServiceState.STATE_IN_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_REGISTERED); mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(), ImsConnectionState.State.CONNECTED, null); } @Override public void onRegistering(int imsRadioTech) { if (DBG) { log("onImsProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); } mRegLocalLog.log("onImsProgressing imsRadioTech=" + AccessNetworkConstants.transportTypeToString(imsRadioTech)); mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_REGISTERING); mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(), ImsConnectionState.State.PROGRESSING, null); } @Override public void onUnregistered(ImsReasonInfo imsReasonInfo) { if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo); mRegLocalLog.log("onImsDisconnected imsRadioTech=" + imsReasonInfo); mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); mPhone.processDisconnectReason(imsReasonInfo); mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(), ImsConnectionState.State.DISCONNECTED, imsReasonInfo); } @Override public void onSubscriberAssociatedUriChanged(Uri[] uris) { if (DBG) log("registrationAssociatedUriChanged"); mPhone.setCurrentSubscriberUris(uris); } }; private final ImsMmTelManager.CapabilityCallback mImsCapabilityCallback = new ImsMmTelManager.CapabilityCallback() { @Override Loading Loading @@ -3753,10 +3697,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { pw.println(" mCallQualityMetrics=" + mCallQualityMetrics); pw.println(" mCallQualityMetricsHistory=" + mCallQualityMetricsHistory); pw.println(" mIsConferenceEventPackageHandlingEnabled=" + mIsConferenceEventPackageEnabled); pw.println(" Registration Log:"); pw.increaseIndent(); mRegLocalLog.dump(pw); pw.decreaseIndent(); pw.println(" Event Log:"); pw.increaseIndent(); mOperationLocalLog.dump(pw); Loading Loading @@ -4257,8 +4197,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { boolean tmpIsVideoCallEnabled = isVideoCallEnabled(); mMmTelCapabilities = new MmTelFeature.MmTelCapabilities(); mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE); mPhone.setImsRegistrationState( RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); mPhone.resetImsRegistrationState(ImsFeature.FEATURE_MMTEL); mPhone.processDisconnectReason(new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN, ImsReasonInfo.CODE_UNSPECIFIED)); boolean isVideoEnabled = isVideoCallEnabled(); Loading
src/java/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelper.java 0 → 100644 +138 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony.imsphone; import android.annotation.NonNull; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; import com.android.internal.telephony.util.HandlerExecutor; import java.util.concurrent.Executor; /** * A helper class to manager the ImsRegistrationCallback can notify the state changed to listener. */ public class ImsRegistrationCallbackHelper { private static final String TAG = "ImsRegCallbackHelper"; /** * The interface to receive IMS registration updated. */ public interface ImsRegistrationUpdate { /** * Handle the callback when IMS is registered. */ void handleImsRegistered(int imsRadioTech); /** * Handle the callback when IMS is registering. */ void handleImsRegistering(int imsRadioTech); /** * Handle the callback when IMS is unregistered. */ void handleImsUnregistered(ImsReasonInfo imsReasonInfo); /** * Handle the callback when the list of subscriber {@link Uri}s associated with this IMS * subscription changed. */ void handleImsSubscriberAssociatedUriChanged(Uri[] uris); } private ImsRegistrationUpdate mImsRegistrationUpdate; private int mRegistrationState = RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; private final RegistrationManager.RegistrationCallback mImsRegistrationCallback = new RegistrationManager.RegistrationCallback() { @Override public void onRegistered(int imsRadioTech) { updateRegistrationState(RegistrationManager.REGISTRATION_STATE_REGISTERED); mImsRegistrationUpdate.handleImsRegistered(imsRadioTech); } @Override public void onRegistering(int imsRadioTech) { updateRegistrationState(RegistrationManager.REGISTRATION_STATE_REGISTERING); mImsRegistrationUpdate.handleImsRegistering(imsRadioTech); } @Override public void onUnregistered(ImsReasonInfo imsReasonInfo) { updateRegistrationState(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); mImsRegistrationUpdate.handleImsUnregistered(imsReasonInfo); } @Override public void onSubscriberAssociatedUriChanged(Uri[] uris) { mImsRegistrationUpdate.handleImsSubscriberAssociatedUriChanged(uris); } }; public ImsRegistrationCallbackHelper(@NonNull ImsRegistrationUpdate registrationUpdate) { mImsRegistrationCallback.setExecutor(getThreadExecutor()); mImsRegistrationUpdate = registrationUpdate; } /** * Reset the IMS registration state. */ public void reset() { Log.d(TAG, "reset"); updateRegistrationState(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); } /** * Update the latest IMS registration state. */ public synchronized void updateRegistrationState( @RegistrationManager.ImsRegistrationState int newState) { Log.d(TAG, "updateRegistrationState: registration state from " + mRegistrationState + " to " + newState); mRegistrationState = newState; } public int getImsRegistrationState() { return mRegistrationState; } public boolean isImsRegistered() { return mRegistrationState == RegistrationManager.REGISTRATION_STATE_REGISTERED; } public RegistrationManager.RegistrationCallback getCallback() { return mImsRegistrationCallback; } public IImsRegistrationCallback getCallbackBinder() { return mImsRegistrationCallback.getBinder(); } private Executor getThreadExecutor() { if (Looper.myLooper() == null) { Looper.prepare(); } return new HandlerExecutor(new Handler(Looper.myLooper())); } }
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +0 −41 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import android.telephony.ims.ImsCallSession; import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsStreamMediaProfile; import android.telephony.ims.RegistrationManager; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; Loading Loading @@ -88,7 +87,6 @@ import org.mockito.stubbing.Answer; public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsPhoneCallTracker mCTUT; private MmTelFeature.Listener mMmTelListener; private RegistrationManager.RegistrationCallback mRegistrationCallback; private ImsMmTelManager.CapabilityCallback mCapabilityCallback; private ImsCall.Listener mImsCallListener; private ImsCall mImsCall; Loading Loading @@ -196,12 +194,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { }).when(mImsManager).makeCall(eq(mImsCallProfile), (String []) any(), (ImsCall.Listener) any()); doAnswer(invocation -> { mRegistrationCallback = invocation.getArgument(0); return mRegistrationCallback; }).when(mImsManager).addRegistrationCallback( any(RegistrationManager.RegistrationCallback.class)); doAnswer(invocation -> { mCapabilityCallback = (ImsMmTelManager.CapabilityCallback) invocation.getArguments()[0]; return mCapabilityCallback; Loading Loading @@ -238,39 +230,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { super.tearDown(); } @Test @SmallTest public void testImsRegistered() { // when IMS is registered mRegistrationCallback.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN); // then service state should be IN_SERVICE and ImsPhone state set to registered verify(mImsPhone).setServiceState(eq(ServiceState.STATE_IN_SERVICE)); verify(mImsPhone).setImsRegistrationState(eq( RegistrationManager.REGISTRATION_STATE_REGISTERED)); } @Test @SmallTest public void testImsRegistering() { // when IMS is registering mRegistrationCallback.onRegistering(ImsRegistrationImplBase.REGISTRATION_TECH_LTE); // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE)); verify(mImsPhone).setImsRegistrationState(eq( RegistrationManager.REGISTRATION_STATE_REGISTERING)); } @Test @SmallTest public void testImsDeregistered() { // when IMS is deregistered mRegistrationCallback.onUnregistered(new ImsReasonInfo()); // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE)); verify(mImsPhone).setImsRegistrationState(eq( RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED)); } @Test @SmallTest public void testVowifiDisabledOnLte() { Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.telephony.ServiceState; import android.telephony.ims.ImsCallProfile; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; Loading Loading @@ -665,6 +666,27 @@ public class ImsPhoneTest extends TelephonyTest { intent.getValue().getStringExtra(Phone.EXTRA_KEY_NOTIFICATION_MESSAGE)); } @Test @SmallTest public void testRegisteringImsRcsRegistrationCallback() throws Exception { RcsFeatureManager rcsFeatureManager = mock(RcsFeatureManager.class); // When initialized RcsFeatureManager and mImsPhoneUT.initRcsFeatureManager(); assertNotNull(mImsPhoneUT.mRcsManagerConnector); // When connection is ready, the register IMS registration callback should be called. mImsPhoneUT.mRcsFeatureConnectorListener.connectionReady(rcsFeatureManager); verify(rcsFeatureManager).registerImsRegistrationCallback( any(IImsRegistrationCallback.class)); // When connection is unavailable, the IMS registration state should be not registered. mImsPhoneUT.mRcsFeatureConnectorListener.connectionUnavailable(); Consumer<Integer> registrationState = mock(Consumer.class); mImsPhoneUT.getImsRcsRegistrationState(registrationState); verify(registrationState).accept(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); } @Test @SmallTest public void testImsRegistered() throws Exception { Loading