Loading src/java/com/android/internal/telephony/ImsSmsDispatcher.java +25 −111 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ package com.android.internal.telephony; import android.os.RemoteException; import android.os.Message; import android.provider.Telephony.Sms.Intents; import android.telephony.Rlog; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.aidl.IImsSmsListener; Loading @@ -26,12 +26,10 @@ import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.telephony.ims.stub.ImsSmsImplBase; import android.telephony.ims.stub.ImsSmsImplBase.SendStatusResult; import android.provider.Telephony.Sms.Intents; import android.util.Pair; import com.android.ims.ImsException; import com.android.ims.ImsManager; import com.android.ims.MmTelFeatureConnection; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; import com.android.internal.telephony.util.SMSDispatcherUtil; Loading @@ -47,12 +45,8 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide */ public class ImsSmsDispatcher extends SMSDispatcher { // Initial condition for ims connection retry. private static final int IMS_RETRY_STARTING_TIMEOUT_MS = 500; // ms // Ceiling bitshift amount for service query timeout, calculated as: // 2^mImsServiceRetryCount * IMS_RETRY_STARTING_TIMEOUT_MS, where // mImsServiceRetryCount ∊ [0, CEILING_SERVICE_RETRY_COUNT]. private static final int CEILING_SERVICE_RETRY_COUNT = 6; private static final String TAG = "ImsSmsDispacher"; @VisibleForTesting public Map<Integer, SmsTracker> mTrackers = new ConcurrentHashMap<>(); Loading @@ -62,20 +56,7 @@ public class ImsSmsDispatcher extends SMSDispatcher { private volatile boolean mIsSmsCapable; private volatile boolean mIsImsServiceUp; private volatile boolean mIsRegistered; private volatile int mImsServiceRetryCount; /** * Default implementation of interface that calculates the ImsService retry timeout. * Override-able for testing. */ private IRetryTimeout mRetryTimeout = () -> { int timeout = (1 << mImsServiceRetryCount) * IMS_RETRY_STARTING_TIMEOUT_MS; if (mImsServiceRetryCount <= CEILING_SERVICE_RETRY_COUNT) { mImsServiceRetryCount++; } return timeout; }; private final ImsManager.Connector mImsManagerConnector; /** * Listen to the IMS service state change * Loading Loading @@ -120,45 +101,6 @@ public class ImsSmsDispatcher extends SMSDispatcher { } }; // Callback fires when ImsManager MMTel Feature changes state private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback = new MmTelFeatureConnection.IFeatureUpdate() { @Override public void notifyStateChanged() { try { int status = getImsManager().getImsServiceState(); Rlog.d(TAG, "Status Changed: " + status); switch (status) { case android.telephony.ims.feature.ImsFeature.STATE_READY: { synchronized (mLock) { setListeners(); mIsImsServiceUp = true; } break; } case android.telephony.ims.feature.ImsFeature.STATE_INITIALIZING: // fall through case ImsFeature.STATE_UNAVAILABLE: synchronized (mLock) { mIsImsServiceUp = false; } break; default: { Rlog.w(TAG, "Unexpected State!"); } } } catch (ImsException e) { // Could not get the ImsService, retry! retryGetImsService(); } } @Override public void notifyUnavailable() { retryGetImsService(); } }; private final IImsSmsListener mImsSmsListener = new IImsSmsListener.Stub() { @Override public void onSendSmsResult(int token, int messageRef, @SendStatusResult int status, Loading Loading @@ -235,36 +177,26 @@ public class ImsSmsDispatcher extends SMSDispatcher { public ImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) { super(phone, smsDispatchersController); mImsServiceRetryCount = 0; // Send a message to connect to the Ims Service and open a connection through // getImsService(). sendEmptyMessage(EVENT_GET_IMS_SERVICE); mImsManagerConnector = new ImsManager.Connector(mContext, mPhone.getPhoneId(), new ImsManager.Connector.Listener() { @Override public void connectionReady(ImsManager manager) throws ImsException { Rlog.d(TAG, "ImsManager: connection ready."); synchronized (mLock) { setListeners(); mIsImsServiceUp = true; } } @Override public void handleMessage(Message msg) { switch (msg.what) { case EVENT_GET_IMS_SERVICE: try { getImsService(); } catch (ImsException e) { Rlog.e(TAG, "setListeners: " + e); retryGetImsService(); } break; default: super.handleMessage(msg); public void connectionUnavailable() { Rlog.d(TAG, "ImsManager: connection unavailable."); synchronized (mLock) { mIsImsServiceUp = false; } } private void getImsService() throws ImsException { Rlog.d(TAG, "getImsService"); // Adding to set, will be safe adding multiple times. If the ImsService is not active yet, // this method will throw an ImsException. getImsManager().addNotifyStatusChangedCallbackIfAvailable(mNotifyStatusChangedCallback); // Wait for ImsService.STATE_READY to start listening for SMS. // Call the callback right away for compatibility with older devices that do not use states. mNotifyStatusChangedCallback.notifyStateChanged(); }); mImsManagerConnector.connect(); } private void setListeners() throws ImsException { Loading @@ -272,25 +204,12 @@ public class ImsSmsDispatcher extends SMSDispatcher { getImsManager().addCapabilitiesCallback(mCapabilityCallback); getImsManager().setSmsListener(mImsSmsListener); getImsManager().onSmsReady(); mImsServiceRetryCount = 0; } private void retryGetImsService() { // The binder connection is already up. Do not try to get it again. if (getImsManager().isServiceAvailable()) { return; } // remove callback so we do not receive updates from old MmTelFeatureConnection when switching // between ImsServices. getImsManager().removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback); // Exponential backoff during retry, limited to 32 seconds. Rlog.e(TAG, "getImsService: Retrying getting ImsService..."); removeMessages(EVENT_GET_IMS_SERVICE); sendEmptyMessageDelayed(EVENT_GET_IMS_SERVICE, mRetryTimeout.get()); } public boolean isAvailable() { synchronized (mLock) { Rlog.d(TAG, "isAvailable: up=" + mIsImsServiceUp + ", reg= " + mIsRegistered + ", cap= " + mIsSmsCapable); return mIsImsServiceUp && mIsRegistered && mIsSmsCapable; } } Loading Loading @@ -382,9 +301,4 @@ public class ImsSmsDispatcher extends SMSDispatcher { protected boolean isCdmaMo() { return mSmsDispatchersController.isCdmaFormat(getFormat()); } @VisibleForTesting public interface IRetryTimeout { int get(); } } src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +28 −97 Original line number Diff line number Diff line Loading @@ -74,7 +74,6 @@ import com.android.ims.ImsException; import com.android.ims.ImsManager; import com.android.ims.ImsMultiEndpoint; import com.android.ims.ImsUtInterface; import com.android.ims.MmTelFeatureConnection; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsVideoCallProvider; import com.android.ims.internal.ImsVideoCallProviderWrapper; Loading Loading @@ -273,20 +272,12 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private static final int EVENT_EXIT_ECBM_BEFORE_PENDINGMO = 21; private static final int EVENT_VT_DATA_USAGE_UPDATE = 22; private static final int EVENT_DATA_ENABLED_CHANGED = 23; private static final int EVENT_GET_IMS_SERVICE = 24; private static final int EVENT_CHECK_FOR_WIFI_HANDOVER = 25; private static final int EVENT_ON_FEATURE_CAPABILITY_CHANGED = 26; private static final int EVENT_SUPP_SERVICE_INDICATION = 27; private static final int TIMEOUT_HANGUP_PENDINGMO = 500; // Initial condition for ims connection retry. private static final int IMS_RETRY_STARTING_TIMEOUT_MS = 500; // ms // Ceiling bitshift amount for service query timeout, calculated as: // 2^mImsServiceRetryCount * IMS_RETRY_STARTING_TIMEOUT_MS, where // mImsServiceRetryCount ∊ [0, CEILING_SERVICE_RETRY_COUNT]. private static final int CEILING_SERVICE_RETRY_COUNT = 6; private static final int HANDOVER_TO_WIFI_TIMEOUT_MS = 60000; // ms //***** Instance Variables Loading Loading @@ -325,7 +316,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private PhoneConstants.State mState = PhoneConstants.State.IDLE; private int mImsServiceRetryCount; private ImsManager mImsManager; private ImsUtInterface mUtInterface; Loading Loading @@ -677,58 +667,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return PhoneNumberUtils.isEmergencyNumber(string); }; // Callback fires when ImsManager MMTel Feature changes state private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback = new MmTelFeatureConnection.IFeatureUpdate() { @Override public void notifyStateChanged() { try { int status = mImsManager.getImsServiceState(); log("Status Changed: " + status); switch (status) { case ImsFeature.STATE_READY: { startListeningForCalls(); break; } case ImsFeature.STATE_INITIALIZING: // fall through case ImsFeature.STATE_UNAVAILABLE: { stopListeningForCalls(); break; } default: { Log.w(LOG_TAG, "Unexpected State!"); } } } catch (ImsException e) { // Could not get the ImsService, retry! retryGetImsService(); } } @Override public void notifyUnavailable() { retryGetImsService(); } }; @VisibleForTesting public interface IRetryTimeout { int get(); } /** * Default implementation of interface that calculates the ImsService retry timeout. * Override-able for testing. */ @VisibleForTesting public IRetryTimeout mRetryTimeout = () -> { int timeout = (1 << mImsServiceRetryCount) * IMS_RETRY_STARTING_TIMEOUT_MS; if (mImsServiceRetryCount <= CEILING_SERVICE_RETRY_COUNT) { mImsServiceRetryCount++; } return timeout; }; private final ImsManager.Connector mImsManagerConnector; //***** Events Loading @@ -749,8 +688,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getDefaultPhone().registerForDataEnabledChanged( this, EVENT_DATA_ENABLED_CHANGED, null); mImsServiceRetryCount = 0; final TelecomManager telecomManager = (TelecomManager) mPhone.getContext().getSystemService(Context.TELECOM_SERVICE); mDefaultDialerUid.set( Loading @@ -760,9 +697,20 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mVtDataUsageSnapshot = new NetworkStats(currentTime, 1); mVtDataUsageUidSnapshot = new NetworkStats(currentTime, 1); // Send a message to connect to the Ims Service and open a connection through // getImsService(). sendEmptyMessage(EVENT_GET_IMS_SERVICE); mImsManagerConnector = new ImsManager.Connector(phone.getContext(), phone.getPhoneId(), new ImsManager.Connector.Listener() { @Override public void connectionReady(ImsManager manager) throws ImsException { mImsManager = manager; startListeningForCalls(); } @Override public void connectionUnavailable() { stopListeningForCalls(); } }); mImsManagerConnector.connect(); } /** Loading @@ -784,6 +732,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhoneNumberUtilsProxy = phoneNumberUtilsProxy; } /** * Test-only method used to set the ImsService retry timeout. */ @VisibleForTesting public void setRetryTimeout(ImsManager.Connector.RetryTimeout retryTimeout) { mImsManagerConnector.mRetryTimeout = retryTimeout; } private int getPackageUid(Context context, String pkg) { if (pkg == null) { return NetworkStats.UID_ALL; Loading @@ -800,19 +756,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return uid; } private void getImsService() throws ImsException { if (DBG) log("getImsService"); mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()); // Adding to set, will be safe adding multiple times. If the ImsService is not active yet, // this method will throw an ImsException. mImsManager.addNotifyStatusChangedCallbackIfAvailable(mNotifyStatusChangedCallback); // Wait for ImsService.STATE_READY to start listening for calls. // Call the callback right away for compatibility with older devices that do not use states. mNotifyStatusChangedCallback.notifyStateChanged(); } private void startListeningForCalls() throws ImsException { mImsServiceRetryCount = 0; log("startListeningForCalls"); mImsManager.open(mMmTelFeatureListener); mImsManager.addRegistrationCallback(mImsRegistrationCallback); mImsManager.addCapabilitiesCallback(mImsCapabilityCallback); Loading Loading @@ -852,6 +797,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } private void stopListeningForCalls() { log("stopListeningForCalls"); resetImsCapabilities(); // Only close on valid session. if (mImsManager != null) { Loading @@ -877,7 +823,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } mPhone.getContext().unregisterReceiver(mReceiver); mPhone.getDefaultPhone().unregisterForDataEnabledChanged(this); removeMessages(EVENT_GET_IMS_SERVICE); mImsManagerConnector.disconnect(); } @Override Loading Loading @@ -3089,14 +3035,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { onDataEnabledChanged(p.first, p.second); } break; case EVENT_GET_IMS_SERVICE: try { getImsService(); } catch (ImsException e) { loge("getImsService: " + e); retryGetImsService(); } break; case EVENT_CHECK_FOR_WIFI_HANDOVER: if (msg.obj instanceof ImsCall) { ImsCall imsCall = (ImsCall) msg.obj; Loading Loading @@ -3347,15 +3285,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (mImsManager.isServiceAvailable()) { return; } // remove callback so we do not receive updates from old ImsServiceProxy when switching // between ImsServices. mImsManager.removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback); //Leave mImsManager as null, then CallStateException will be thrown when dialing mImsManager = null; // Exponential backoff during retry, limited to 32 seconds. loge("getImsService: Retrying getting ImsService..."); removeMessages(EVENT_GET_IMS_SERVICE); sendEmptyMessageDelayed(EVENT_GET_IMS_SERVICE, mRetryTimeout.get()); mImsManagerConnector.connect(); } private void setVideoCallProvider(ImsPhoneConnection conn, ImsCall imsCall) Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +5 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; Loading Loading @@ -223,6 +224,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { doReturn(mImsConfig).when(mImsManager).getConfigInterface(); doNothing().when(mImsManager).addNotifyStatusChangedCallbackIfAvailable(any()); mImsCTHandlerThread = new ImsCTHandlerThread(this.getClass().getSimpleName()); mImsCTHandlerThread.start(); Loading Loading @@ -615,7 +618,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { public void testDialImsServiceUnavailable() throws ImsException { doThrow(new ImsException("Test Exception", ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN)).when( mImsManager).createCallProfile(anyInt(), anyInt()); mCTUT.mRetryTimeout = () -> 0; //ms mCTUT.setRetryTimeout(() -> 0); assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState()); assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); Loading Loading @@ -644,7 +647,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { mImsManager).setUiTTYMode(nullable(Context.class), anyInt(), nullable(Message.class)); // Remove retry timeout delay mCTUT.mRetryTimeout = () -> 0; //ms mCTUT.setRetryTimeout(() -> 0); //ms mCTUT.setUiTTYMode(0, new Message()); Loading Loading
src/java/com/android/internal/telephony/ImsSmsDispatcher.java +25 −111 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ package com.android.internal.telephony; import android.os.RemoteException; import android.os.Message; import android.provider.Telephony.Sms.Intents; import android.telephony.Rlog; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.aidl.IImsSmsListener; Loading @@ -26,12 +26,10 @@ import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.telephony.ims.stub.ImsSmsImplBase; import android.telephony.ims.stub.ImsSmsImplBase.SendStatusResult; import android.provider.Telephony.Sms.Intents; import android.util.Pair; import com.android.ims.ImsException; import com.android.ims.ImsManager; import com.android.ims.MmTelFeatureConnection; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; import com.android.internal.telephony.util.SMSDispatcherUtil; Loading @@ -47,12 +45,8 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide */ public class ImsSmsDispatcher extends SMSDispatcher { // Initial condition for ims connection retry. private static final int IMS_RETRY_STARTING_TIMEOUT_MS = 500; // ms // Ceiling bitshift amount for service query timeout, calculated as: // 2^mImsServiceRetryCount * IMS_RETRY_STARTING_TIMEOUT_MS, where // mImsServiceRetryCount ∊ [0, CEILING_SERVICE_RETRY_COUNT]. private static final int CEILING_SERVICE_RETRY_COUNT = 6; private static final String TAG = "ImsSmsDispacher"; @VisibleForTesting public Map<Integer, SmsTracker> mTrackers = new ConcurrentHashMap<>(); Loading @@ -62,20 +56,7 @@ public class ImsSmsDispatcher extends SMSDispatcher { private volatile boolean mIsSmsCapable; private volatile boolean mIsImsServiceUp; private volatile boolean mIsRegistered; private volatile int mImsServiceRetryCount; /** * Default implementation of interface that calculates the ImsService retry timeout. * Override-able for testing. */ private IRetryTimeout mRetryTimeout = () -> { int timeout = (1 << mImsServiceRetryCount) * IMS_RETRY_STARTING_TIMEOUT_MS; if (mImsServiceRetryCount <= CEILING_SERVICE_RETRY_COUNT) { mImsServiceRetryCount++; } return timeout; }; private final ImsManager.Connector mImsManagerConnector; /** * Listen to the IMS service state change * Loading Loading @@ -120,45 +101,6 @@ public class ImsSmsDispatcher extends SMSDispatcher { } }; // Callback fires when ImsManager MMTel Feature changes state private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback = new MmTelFeatureConnection.IFeatureUpdate() { @Override public void notifyStateChanged() { try { int status = getImsManager().getImsServiceState(); Rlog.d(TAG, "Status Changed: " + status); switch (status) { case android.telephony.ims.feature.ImsFeature.STATE_READY: { synchronized (mLock) { setListeners(); mIsImsServiceUp = true; } break; } case android.telephony.ims.feature.ImsFeature.STATE_INITIALIZING: // fall through case ImsFeature.STATE_UNAVAILABLE: synchronized (mLock) { mIsImsServiceUp = false; } break; default: { Rlog.w(TAG, "Unexpected State!"); } } } catch (ImsException e) { // Could not get the ImsService, retry! retryGetImsService(); } } @Override public void notifyUnavailable() { retryGetImsService(); } }; private final IImsSmsListener mImsSmsListener = new IImsSmsListener.Stub() { @Override public void onSendSmsResult(int token, int messageRef, @SendStatusResult int status, Loading Loading @@ -235,36 +177,26 @@ public class ImsSmsDispatcher extends SMSDispatcher { public ImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) { super(phone, smsDispatchersController); mImsServiceRetryCount = 0; // Send a message to connect to the Ims Service and open a connection through // getImsService(). sendEmptyMessage(EVENT_GET_IMS_SERVICE); mImsManagerConnector = new ImsManager.Connector(mContext, mPhone.getPhoneId(), new ImsManager.Connector.Listener() { @Override public void connectionReady(ImsManager manager) throws ImsException { Rlog.d(TAG, "ImsManager: connection ready."); synchronized (mLock) { setListeners(); mIsImsServiceUp = true; } } @Override public void handleMessage(Message msg) { switch (msg.what) { case EVENT_GET_IMS_SERVICE: try { getImsService(); } catch (ImsException e) { Rlog.e(TAG, "setListeners: " + e); retryGetImsService(); } break; default: super.handleMessage(msg); public void connectionUnavailable() { Rlog.d(TAG, "ImsManager: connection unavailable."); synchronized (mLock) { mIsImsServiceUp = false; } } private void getImsService() throws ImsException { Rlog.d(TAG, "getImsService"); // Adding to set, will be safe adding multiple times. If the ImsService is not active yet, // this method will throw an ImsException. getImsManager().addNotifyStatusChangedCallbackIfAvailable(mNotifyStatusChangedCallback); // Wait for ImsService.STATE_READY to start listening for SMS. // Call the callback right away for compatibility with older devices that do not use states. mNotifyStatusChangedCallback.notifyStateChanged(); }); mImsManagerConnector.connect(); } private void setListeners() throws ImsException { Loading @@ -272,25 +204,12 @@ public class ImsSmsDispatcher extends SMSDispatcher { getImsManager().addCapabilitiesCallback(mCapabilityCallback); getImsManager().setSmsListener(mImsSmsListener); getImsManager().onSmsReady(); mImsServiceRetryCount = 0; } private void retryGetImsService() { // The binder connection is already up. Do not try to get it again. if (getImsManager().isServiceAvailable()) { return; } // remove callback so we do not receive updates from old MmTelFeatureConnection when switching // between ImsServices. getImsManager().removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback); // Exponential backoff during retry, limited to 32 seconds. Rlog.e(TAG, "getImsService: Retrying getting ImsService..."); removeMessages(EVENT_GET_IMS_SERVICE); sendEmptyMessageDelayed(EVENT_GET_IMS_SERVICE, mRetryTimeout.get()); } public boolean isAvailable() { synchronized (mLock) { Rlog.d(TAG, "isAvailable: up=" + mIsImsServiceUp + ", reg= " + mIsRegistered + ", cap= " + mIsSmsCapable); return mIsImsServiceUp && mIsRegistered && mIsSmsCapable; } } Loading Loading @@ -382,9 +301,4 @@ public class ImsSmsDispatcher extends SMSDispatcher { protected boolean isCdmaMo() { return mSmsDispatchersController.isCdmaFormat(getFormat()); } @VisibleForTesting public interface IRetryTimeout { int get(); } }
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +28 −97 Original line number Diff line number Diff line Loading @@ -74,7 +74,6 @@ import com.android.ims.ImsException; import com.android.ims.ImsManager; import com.android.ims.ImsMultiEndpoint; import com.android.ims.ImsUtInterface; import com.android.ims.MmTelFeatureConnection; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsVideoCallProvider; import com.android.ims.internal.ImsVideoCallProviderWrapper; Loading Loading @@ -273,20 +272,12 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private static final int EVENT_EXIT_ECBM_BEFORE_PENDINGMO = 21; private static final int EVENT_VT_DATA_USAGE_UPDATE = 22; private static final int EVENT_DATA_ENABLED_CHANGED = 23; private static final int EVENT_GET_IMS_SERVICE = 24; private static final int EVENT_CHECK_FOR_WIFI_HANDOVER = 25; private static final int EVENT_ON_FEATURE_CAPABILITY_CHANGED = 26; private static final int EVENT_SUPP_SERVICE_INDICATION = 27; private static final int TIMEOUT_HANGUP_PENDINGMO = 500; // Initial condition for ims connection retry. private static final int IMS_RETRY_STARTING_TIMEOUT_MS = 500; // ms // Ceiling bitshift amount for service query timeout, calculated as: // 2^mImsServiceRetryCount * IMS_RETRY_STARTING_TIMEOUT_MS, where // mImsServiceRetryCount ∊ [0, CEILING_SERVICE_RETRY_COUNT]. private static final int CEILING_SERVICE_RETRY_COUNT = 6; private static final int HANDOVER_TO_WIFI_TIMEOUT_MS = 60000; // ms //***** Instance Variables Loading Loading @@ -325,7 +316,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private PhoneConstants.State mState = PhoneConstants.State.IDLE; private int mImsServiceRetryCount; private ImsManager mImsManager; private ImsUtInterface mUtInterface; Loading Loading @@ -677,58 +667,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return PhoneNumberUtils.isEmergencyNumber(string); }; // Callback fires when ImsManager MMTel Feature changes state private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback = new MmTelFeatureConnection.IFeatureUpdate() { @Override public void notifyStateChanged() { try { int status = mImsManager.getImsServiceState(); log("Status Changed: " + status); switch (status) { case ImsFeature.STATE_READY: { startListeningForCalls(); break; } case ImsFeature.STATE_INITIALIZING: // fall through case ImsFeature.STATE_UNAVAILABLE: { stopListeningForCalls(); break; } default: { Log.w(LOG_TAG, "Unexpected State!"); } } } catch (ImsException e) { // Could not get the ImsService, retry! retryGetImsService(); } } @Override public void notifyUnavailable() { retryGetImsService(); } }; @VisibleForTesting public interface IRetryTimeout { int get(); } /** * Default implementation of interface that calculates the ImsService retry timeout. * Override-able for testing. */ @VisibleForTesting public IRetryTimeout mRetryTimeout = () -> { int timeout = (1 << mImsServiceRetryCount) * IMS_RETRY_STARTING_TIMEOUT_MS; if (mImsServiceRetryCount <= CEILING_SERVICE_RETRY_COUNT) { mImsServiceRetryCount++; } return timeout; }; private final ImsManager.Connector mImsManagerConnector; //***** Events Loading @@ -749,8 +688,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getDefaultPhone().registerForDataEnabledChanged( this, EVENT_DATA_ENABLED_CHANGED, null); mImsServiceRetryCount = 0; final TelecomManager telecomManager = (TelecomManager) mPhone.getContext().getSystemService(Context.TELECOM_SERVICE); mDefaultDialerUid.set( Loading @@ -760,9 +697,20 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mVtDataUsageSnapshot = new NetworkStats(currentTime, 1); mVtDataUsageUidSnapshot = new NetworkStats(currentTime, 1); // Send a message to connect to the Ims Service and open a connection through // getImsService(). sendEmptyMessage(EVENT_GET_IMS_SERVICE); mImsManagerConnector = new ImsManager.Connector(phone.getContext(), phone.getPhoneId(), new ImsManager.Connector.Listener() { @Override public void connectionReady(ImsManager manager) throws ImsException { mImsManager = manager; startListeningForCalls(); } @Override public void connectionUnavailable() { stopListeningForCalls(); } }); mImsManagerConnector.connect(); } /** Loading @@ -784,6 +732,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhoneNumberUtilsProxy = phoneNumberUtilsProxy; } /** * Test-only method used to set the ImsService retry timeout. */ @VisibleForTesting public void setRetryTimeout(ImsManager.Connector.RetryTimeout retryTimeout) { mImsManagerConnector.mRetryTimeout = retryTimeout; } private int getPackageUid(Context context, String pkg) { if (pkg == null) { return NetworkStats.UID_ALL; Loading @@ -800,19 +756,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return uid; } private void getImsService() throws ImsException { if (DBG) log("getImsService"); mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()); // Adding to set, will be safe adding multiple times. If the ImsService is not active yet, // this method will throw an ImsException. mImsManager.addNotifyStatusChangedCallbackIfAvailable(mNotifyStatusChangedCallback); // Wait for ImsService.STATE_READY to start listening for calls. // Call the callback right away for compatibility with older devices that do not use states. mNotifyStatusChangedCallback.notifyStateChanged(); } private void startListeningForCalls() throws ImsException { mImsServiceRetryCount = 0; log("startListeningForCalls"); mImsManager.open(mMmTelFeatureListener); mImsManager.addRegistrationCallback(mImsRegistrationCallback); mImsManager.addCapabilitiesCallback(mImsCapabilityCallback); Loading Loading @@ -852,6 +797,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } private void stopListeningForCalls() { log("stopListeningForCalls"); resetImsCapabilities(); // Only close on valid session. if (mImsManager != null) { Loading @@ -877,7 +823,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } mPhone.getContext().unregisterReceiver(mReceiver); mPhone.getDefaultPhone().unregisterForDataEnabledChanged(this); removeMessages(EVENT_GET_IMS_SERVICE); mImsManagerConnector.disconnect(); } @Override Loading Loading @@ -3089,14 +3035,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { onDataEnabledChanged(p.first, p.second); } break; case EVENT_GET_IMS_SERVICE: try { getImsService(); } catch (ImsException e) { loge("getImsService: " + e); retryGetImsService(); } break; case EVENT_CHECK_FOR_WIFI_HANDOVER: if (msg.obj instanceof ImsCall) { ImsCall imsCall = (ImsCall) msg.obj; Loading Loading @@ -3347,15 +3285,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (mImsManager.isServiceAvailable()) { return; } // remove callback so we do not receive updates from old ImsServiceProxy when switching // between ImsServices. mImsManager.removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback); //Leave mImsManager as null, then CallStateException will be thrown when dialing mImsManager = null; // Exponential backoff during retry, limited to 32 seconds. loge("getImsService: Retrying getting ImsService..."); removeMessages(EVENT_GET_IMS_SERVICE); sendEmptyMessageDelayed(EVENT_GET_IMS_SERVICE, mRetryTimeout.get()); mImsManagerConnector.connect(); } private void setVideoCallProvider(ImsPhoneConnection conn, ImsCall imsCall) Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +5 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; Loading Loading @@ -223,6 +224,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { doReturn(mImsConfig).when(mImsManager).getConfigInterface(); doNothing().when(mImsManager).addNotifyStatusChangedCallbackIfAvailable(any()); mImsCTHandlerThread = new ImsCTHandlerThread(this.getClass().getSimpleName()); mImsCTHandlerThread.start(); Loading Loading @@ -615,7 +618,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { public void testDialImsServiceUnavailable() throws ImsException { doThrow(new ImsException("Test Exception", ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN)).when( mImsManager).createCallProfile(anyInt(), anyInt()); mCTUT.mRetryTimeout = () -> 0; //ms mCTUT.setRetryTimeout(() -> 0); assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState()); assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); Loading Loading @@ -644,7 +647,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { mImsManager).setUiTTYMode(nullable(Context.class), anyInt(), nullable(Message.class)); // Remove retry timeout delay mCTUT.mRetryTimeout = () -> 0; //ms mCTUT.setRetryTimeout(() -> 0); //ms mCTUT.setUiTTYMode(0, new Message()); Loading