Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +42 −12 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.telephony.ims.ProvisioningManager; import android.telephony.ims.RtpHeaderExtension; import android.telephony.ims.RtpHeaderExtensionType; import android.telephony.ims.SrvccCall; import android.telephony.ims.aidl.IImsCallSessionListener; import android.telephony.ims.aidl.ISrvccStartedCallback; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; Loading Loading @@ -168,10 +169,12 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; Loading Loading @@ -234,16 +237,18 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener(); private class MmTelFeatureListener extends MmTelFeature.Listener { private void processIncomingCall(IImsCallSession c, Bundle extras) { private IImsCallSessionListener processIncomingCall(@NonNull IImsCallSession c, @Nullable String callId, @Nullable Bundle extras) { if (DBG) log("processIncomingCall: incoming call intent"); if (extras == null) extras = new Bundle(); if (mImsManager == null) return; if (mImsManager == null) return null; try { IImsCallSessionListener iimsCallSessionListener; // Network initiated USSD will be treated by mImsUssdListener boolean isUssd = extras.getBoolean(MmTelFeature.EXTRA_IS_USSD, false); // For compatibility purposes with older vendor implmentations. // For compatibility purposes with older vendor implementations. isUssd |= extras.getBoolean(ImsManager.EXTRA_USSD, false); if (isUssd) { if (DBG) log("processIncomingCall: USSD"); Loading @@ -252,11 +257,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (mUssdSession != null) { mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE); } return; if (callId != null) mUssdSession.getCallSession().setCallId(callId); iimsCallSessionListener = (IImsCallSessionListener) mUssdSession .getCallSession().getIImsCallSessionListenerProxy(); return iimsCallSessionListener; } boolean isUnknown = extras.getBoolean(MmTelFeature.EXTRA_IS_UNKNOWN_CALL, false); // For compatibility purposes with older vendor implmentations. // For compatibility purposes with older vendor implementations. isUnknown |= extras.getBoolean(ImsManager.EXTRA_IS_UNKNOWN_CALL, false); if (DBG) { log("processIncomingCall: isUnknown = " + isUnknown Loading @@ -266,6 +274,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { // Normal MT/Unknown call ImsCall imsCall = mImsManager.takeCall(c, mImsCallListener); if (callId != null) imsCall.getCallSession().setCallId(callId); iimsCallSessionListener = (IImsCallSessionListener) imsCall .getCallSession().getIImsCallSessionListenerProxy(); ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall, ImsPhoneCallTracker.this, (isUnknown ? mForegroundCall : mRingingCall), isUnknown); Loading Loading @@ -340,18 +351,19 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); mImsCallInfoTracker.addImsCallStatus(conn); return iimsCallSessionListener; } catch (ImsException | RemoteException e) { loge("processIncomingCall: exception " + e); mOperationLocalLog.log("onIncomingCall: exception processing: " + e); return null; } } @Override public void onIncomingCall(IImsCallSession c, Bundle extras) { // we want to ensure we block this binder thread until incoming call setup completes // as to avoid race conditions where the ImsService tries to update the state of the // call before the listeners have been attached. executeAndWait(()-> processIncomingCall(c, extras)); @Nullable public IImsCallSessionListener onIncomingCall( @NonNull IImsCallSession c, @Nullable String callId, @Nullable Bundle extras) { return executeAndWaitForReturn(()-> processIncomingCall(c, callId, extras)); } @Override Loading Loading @@ -413,6 +425,24 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { logw("Binder - exception: " + e.getMessage()); } } /** * Schedule the given Runnable on mExecutor and block this thread until it finishes. * @param r The Runnable to run. */ private <T> T executeAndWaitForReturn(Supplier<T> r) { CompletableFuture<T> future = CompletableFuture.supplyAsync( () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor); try { return future.get(); } catch (ExecutionException | InterruptedException e) { Log.w(LOG_TAG, "ImsPhoneCallTracker : executeAndWaitForReturn exception: " + e.getMessage()); return null; } } } /** Loading tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java +16 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading Loading @@ -151,11 +152,25 @@ public class MmTelFeatureTests extends ImsTestBase { mFeature.incomingCall(session); ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class); verify(mListener).onIncomingCall(captor.capture(), any()); verify(mListener).onIncomingCall(captor.capture(), eq(null), any()); assertEquals(sessionBinder, captor.getValue()); } @SmallTest @Test public void testNewIncomingCallReturnListener() throws Exception { IImsCallSession sessionBinder = Mockito.mock(IImsCallSession.class); ImsCallSessionImplBase session = new ImsCallSessionImplBase(); session.setServiceImpl(sessionBinder); String callId = "callID"; Bundle extra = new Bundle(); mFeature.incomingCall(session, callId, extra); ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class); verify(mListener).onIncomingCall(captor.capture(), eq(callId), eq(extra)); assertEquals(sessionBinder, captor.getValue()); } @SmallTest @Test public void testSetTtyMessageMessenger() throws Exception { Loading tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java +5 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,11 @@ public class TestMmTelFeature extends MmTelFeature { notifyIncomingCall(c, new Bundle()); } public ImsCallSessionListener incomingCall( ImsCallSessionImplBase c, String callId, Bundle extra) { return notifyIncomingCall(c, callId, extra); } @Override public ImsCallProfile createCallProfile(int callSessionType, int callType) { return super.createCallProfile(callSessionType, callType); Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -556,7 +556,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); assertFalse(mCTUT.mRingingCall.isRinging()); // mock a MT call mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(1)).notifyIncomingRing(); assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); Loading Loading @@ -708,7 +708,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(2)).notifyIncomingRing(); Loading Loading @@ -746,7 +746,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(2)).notifyIncomingRing(); Loading Loading @@ -938,7 +938,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { try { doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class), any(ImsCall.Listener.class)); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE); } catch (Exception ex) { ex.printStackTrace(); Loading Loading @@ -1756,7 +1756,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); assertFalse(mCTUT.mRingingCall.isRinging()); // mock a MT call mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(1)).notifyIncomingRing(); assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); Loading Loading @@ -1794,7 +1794,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); assertFalse(mCTUT.mRingingCall.isRinging()); // mock a MT call mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(1)).notifyIncomingRing(); assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); Loading Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +42 −12 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.telephony.ims.ProvisioningManager; import android.telephony.ims.RtpHeaderExtension; import android.telephony.ims.RtpHeaderExtensionType; import android.telephony.ims.SrvccCall; import android.telephony.ims.aidl.IImsCallSessionListener; import android.telephony.ims.aidl.ISrvccStartedCallback; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; Loading Loading @@ -168,10 +169,12 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; Loading Loading @@ -234,16 +237,18 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener(); private class MmTelFeatureListener extends MmTelFeature.Listener { private void processIncomingCall(IImsCallSession c, Bundle extras) { private IImsCallSessionListener processIncomingCall(@NonNull IImsCallSession c, @Nullable String callId, @Nullable Bundle extras) { if (DBG) log("processIncomingCall: incoming call intent"); if (extras == null) extras = new Bundle(); if (mImsManager == null) return; if (mImsManager == null) return null; try { IImsCallSessionListener iimsCallSessionListener; // Network initiated USSD will be treated by mImsUssdListener boolean isUssd = extras.getBoolean(MmTelFeature.EXTRA_IS_USSD, false); // For compatibility purposes with older vendor implmentations. // For compatibility purposes with older vendor implementations. isUssd |= extras.getBoolean(ImsManager.EXTRA_USSD, false); if (isUssd) { if (DBG) log("processIncomingCall: USSD"); Loading @@ -252,11 +257,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (mUssdSession != null) { mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE); } return; if (callId != null) mUssdSession.getCallSession().setCallId(callId); iimsCallSessionListener = (IImsCallSessionListener) mUssdSession .getCallSession().getIImsCallSessionListenerProxy(); return iimsCallSessionListener; } boolean isUnknown = extras.getBoolean(MmTelFeature.EXTRA_IS_UNKNOWN_CALL, false); // For compatibility purposes with older vendor implmentations. // For compatibility purposes with older vendor implementations. isUnknown |= extras.getBoolean(ImsManager.EXTRA_IS_UNKNOWN_CALL, false); if (DBG) { log("processIncomingCall: isUnknown = " + isUnknown Loading @@ -266,6 +274,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { // Normal MT/Unknown call ImsCall imsCall = mImsManager.takeCall(c, mImsCallListener); if (callId != null) imsCall.getCallSession().setCallId(callId); iimsCallSessionListener = (IImsCallSessionListener) imsCall .getCallSession().getIImsCallSessionListenerProxy(); ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall, ImsPhoneCallTracker.this, (isUnknown ? mForegroundCall : mRingingCall), isUnknown); Loading Loading @@ -340,18 +351,19 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); mImsCallInfoTracker.addImsCallStatus(conn); return iimsCallSessionListener; } catch (ImsException | RemoteException e) { loge("processIncomingCall: exception " + e); mOperationLocalLog.log("onIncomingCall: exception processing: " + e); return null; } } @Override public void onIncomingCall(IImsCallSession c, Bundle extras) { // we want to ensure we block this binder thread until incoming call setup completes // as to avoid race conditions where the ImsService tries to update the state of the // call before the listeners have been attached. executeAndWait(()-> processIncomingCall(c, extras)); @Nullable public IImsCallSessionListener onIncomingCall( @NonNull IImsCallSession c, @Nullable String callId, @Nullable Bundle extras) { return executeAndWaitForReturn(()-> processIncomingCall(c, callId, extras)); } @Override Loading Loading @@ -413,6 +425,24 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { logw("Binder - exception: " + e.getMessage()); } } /** * Schedule the given Runnable on mExecutor and block this thread until it finishes. * @param r The Runnable to run. */ private <T> T executeAndWaitForReturn(Supplier<T> r) { CompletableFuture<T> future = CompletableFuture.supplyAsync( () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor); try { return future.get(); } catch (ExecutionException | InterruptedException e) { Log.w(LOG_TAG, "ImsPhoneCallTracker : executeAndWaitForReturn exception: " + e.getMessage()); return null; } } } /** Loading
tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java +16 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading Loading @@ -151,11 +152,25 @@ public class MmTelFeatureTests extends ImsTestBase { mFeature.incomingCall(session); ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class); verify(mListener).onIncomingCall(captor.capture(), any()); verify(mListener).onIncomingCall(captor.capture(), eq(null), any()); assertEquals(sessionBinder, captor.getValue()); } @SmallTest @Test public void testNewIncomingCallReturnListener() throws Exception { IImsCallSession sessionBinder = Mockito.mock(IImsCallSession.class); ImsCallSessionImplBase session = new ImsCallSessionImplBase(); session.setServiceImpl(sessionBinder); String callId = "callID"; Bundle extra = new Bundle(); mFeature.incomingCall(session, callId, extra); ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class); verify(mListener).onIncomingCall(captor.capture(), eq(callId), eq(extra)); assertEquals(sessionBinder, captor.getValue()); } @SmallTest @Test public void testSetTtyMessageMessenger() throws Exception { Loading
tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java +5 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,11 @@ public class TestMmTelFeature extends MmTelFeature { notifyIncomingCall(c, new Bundle()); } public ImsCallSessionListener incomingCall( ImsCallSessionImplBase c, String callId, Bundle extra) { return notifyIncomingCall(c, callId, extra); } @Override public ImsCallProfile createCallProfile(int callSessionType, int callType) { return super.createCallProfile(callSessionType, callType); Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -556,7 +556,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); assertFalse(mCTUT.mRingingCall.isRinging()); // mock a MT call mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(1)).notifyIncomingRing(); assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); Loading Loading @@ -708,7 +708,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(2)).notifyIncomingRing(); Loading Loading @@ -746,7 +746,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(2)).notifyIncomingRing(); Loading Loading @@ -938,7 +938,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { try { doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class), any(ImsCall.Listener.class)); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE); } catch (Exception ex) { ex.printStackTrace(); Loading Loading @@ -1756,7 +1756,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); assertFalse(mCTUT.mRingingCall.isRinging()); // mock a MT call mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(1)).notifyIncomingRing(); assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); Loading Loading @@ -1794,7 +1794,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); assertFalse(mCTUT.mRingingCall.isRinging()); // mock a MT call mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY); mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY); verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any()); verify(mImsPhone, times(1)).notifyIncomingRing(); assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); Loading