Loading src/java/com/android/internal/telephony/Call.java +12 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.telephony.Rlog; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * {@hide} Loading Loading @@ -121,6 +122,17 @@ public abstract class Call { } } /** * @return returns a summary of the connections held in this call. */ public String getConnectionSummary() { synchronized (mLock) { return mConnections.stream() .map(c -> c.getTelecomCallId() + "/objId:" + System.identityHashCode(c)) .collect(Collectors.joining(", ")); } } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract Phone getPhone(); @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +52 −5 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Queue; import java.util.Set; Loading Loading @@ -205,7 +206,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private void processIncomingCall(IImsCallSession c, Bundle extras) { if (DBG) log("processIncomingCall: incoming call intent"); mOperationLocalLog.log("onIncomingCall Received"); if (extras == null) extras = new Bundle(); if (mImsManager == null) return; Loading Loading @@ -275,6 +275,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } } mOperationLocalLog.log("onIncomingCall: isUnknown=" + isUnknown + ", connId=" + System.identityHashCode(conn)); addConnection(conn); setVideoCallProvider(conn, imsCall); Loading @@ -284,6 +287,13 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getVoiceCallSessionStats().onImsCallReceived(conn); if (isUnknown) { // Check for condition where an unknown connection replaces a pending // MO call. This will cause problems later in all likelihood. if (mPendingMO != null && Objects.equals(mPendingMO.getAddress(), conn.getAddress())) { mOperationLocalLog.log("onIncomingCall: unknown call " + conn + " replaces " + mPendingMO); } mPhone.notifyUnknownConnection(conn); } else { if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE) Loading Loading @@ -2248,6 +2258,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return !isImsAudioCallActiveOrHolding || !VideoProfile.isVideo(videoState); } /** * Determines if there are issues which would preclude dialing an outgoing call. Throws a * {@link CallStateException} if there is an issue. Loading Loading @@ -2315,9 +2326,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (DBG) { log("updatePhoneState pendingMo = " + (mPendingMO == null ? "null" : mPendingMO.getState()) + ", fg= " + mForegroundCall.getState() + "(" + mForegroundCall.getConnectionsCount() + "), bg= " + mBackgroundCall .getState() + "(" + mBackgroundCall.getConnectionsCount() + ")"); : mPendingMO.getState() + "(" + mPendingMO.getTelecomCallId() + "/objId:" + System.identityHashCode(mPendingMO) + ")") + ", rng= " + mRingingCall.getState() + "(" + mRingingCall.getConnectionSummary() + "), fg= " + mForegroundCall.getState() + "(" + mForegroundCall.getConnectionSummary() + "), bg= " + mBackgroundCall.getState() + "(" + mBackgroundCall.getConnectionSummary() + ")"); log("updatePhoneState oldState=" + oldState + ", newState=" + mState); } Loading Loading @@ -2608,9 +2624,35 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return null; } /** * Given a connection, detach it from any {@link ImsPhoneCall} it is associated with, remove it * from the connections lists, and ensure if it was the pending MO connection it gets removed * from there as well. * @param conn The connection to cleanup and remove. */ public synchronized void cleanupAndRemoveConnection(ImsPhoneConnection conn) { mOperationLocalLog.log("cleanupAndRemoveConnection: " + conn); // If the connection is attached to a call, detach it. if (conn.getCall() != null) { conn.getCall().detach(conn); } // Remove it from the connection list. removeConnection(conn); // Finally, if it was the pending MO, then ensure that connection gets cleaned up as well. if (conn == mPendingMO) { mPendingMO.finalize(); mPendingMO = null; } // Ensure aggregate state for this tracker is also updated to reflect the new state. updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private synchronized void removeConnection(ImsPhoneConnection conn) { public synchronized void removeConnection(ImsPhoneConnection conn) { mConnections.remove(conn); // If not emergency call is remaining, notify emergency call registrants if (mIsInEmergencyCall) { boolean isEmergencyCallInList = false; Loading Loading @@ -5311,6 +5353,11 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return mConnections; } @VisibleForTesting public ImsPhoneConnection getPendingMO() { return mPendingMO; } /** * Set up static configuration from package/services/Telephony's config.xml. * @param config the config. Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +29 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static junit.framework.Assert.assertNotNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyString; Loading Loading @@ -1560,6 +1561,23 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { verify(mImsManager, never()).setOfferedRtpHeaderExtensionTypes(any()); } @Test @SmallTest public void testCleanupAndRemoveConnection() throws Exception { ImsPhoneConnection conn = placeCall(); assertEquals(1, mCTUT.getConnections().size()); assertNotNull(mCTUT.getPendingMO()); assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState()); assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); mCTUT.cleanupAndRemoveConnection(conn); assertEquals(0, mCTUT.getConnections().size()); assertNull(mCTUT.getPendingMO()); assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState()); assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); } private void sendCarrierConfigChanged() { Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId()); Loading Loading @@ -1595,6 +1613,16 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { } private ImsPhoneConnection placeCallAndMakeActive() { ImsPhoneConnection connection = placeCall(); ImsCall imsCall = connection.getImsCall(); imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(), new ImsStreamMediaProfile()); imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(), new ImsCallProfile()); return connection; } private ImsPhoneConnection placeCall() { try { doAnswer(new Answer<ImsCall>() { @Override Loading @@ -1606,6 +1634,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { imsCallMocking(imsCall); return imsCall; } }).when(mImsManager).makeCall(eq(mImsCallProfile), (String[]) any(), (ImsCall.Listener) any()); } catch (ImsException ie) { Loading @@ -1622,11 +1651,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { if (connection == null) { Assert.fail("connection is null"); } ImsCall imsCall = connection.getImsCall(); imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(), new ImsStreamMediaProfile()); imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(), new ImsCallProfile()); return connection; } } Loading Loading
src/java/com/android/internal/telephony/Call.java +12 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.telephony.Rlog; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * {@hide} Loading Loading @@ -121,6 +122,17 @@ public abstract class Call { } } /** * @return returns a summary of the connections held in this call. */ public String getConnectionSummary() { synchronized (mLock) { return mConnections.stream() .map(c -> c.getTelecomCallId() + "/objId:" + System.identityHashCode(c)) .collect(Collectors.joining(", ")); } } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract Phone getPhone(); @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +52 −5 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Queue; import java.util.Set; Loading Loading @@ -205,7 +206,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private void processIncomingCall(IImsCallSession c, Bundle extras) { if (DBG) log("processIncomingCall: incoming call intent"); mOperationLocalLog.log("onIncomingCall Received"); if (extras == null) extras = new Bundle(); if (mImsManager == null) return; Loading Loading @@ -275,6 +275,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } } mOperationLocalLog.log("onIncomingCall: isUnknown=" + isUnknown + ", connId=" + System.identityHashCode(conn)); addConnection(conn); setVideoCallProvider(conn, imsCall); Loading @@ -284,6 +287,13 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getVoiceCallSessionStats().onImsCallReceived(conn); if (isUnknown) { // Check for condition where an unknown connection replaces a pending // MO call. This will cause problems later in all likelihood. if (mPendingMO != null && Objects.equals(mPendingMO.getAddress(), conn.getAddress())) { mOperationLocalLog.log("onIncomingCall: unknown call " + conn + " replaces " + mPendingMO); } mPhone.notifyUnknownConnection(conn); } else { if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE) Loading Loading @@ -2248,6 +2258,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return !isImsAudioCallActiveOrHolding || !VideoProfile.isVideo(videoState); } /** * Determines if there are issues which would preclude dialing an outgoing call. Throws a * {@link CallStateException} if there is an issue. Loading Loading @@ -2315,9 +2326,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (DBG) { log("updatePhoneState pendingMo = " + (mPendingMO == null ? "null" : mPendingMO.getState()) + ", fg= " + mForegroundCall.getState() + "(" + mForegroundCall.getConnectionsCount() + "), bg= " + mBackgroundCall .getState() + "(" + mBackgroundCall.getConnectionsCount() + ")"); : mPendingMO.getState() + "(" + mPendingMO.getTelecomCallId() + "/objId:" + System.identityHashCode(mPendingMO) + ")") + ", rng= " + mRingingCall.getState() + "(" + mRingingCall.getConnectionSummary() + "), fg= " + mForegroundCall.getState() + "(" + mForegroundCall.getConnectionSummary() + "), bg= " + mBackgroundCall.getState() + "(" + mBackgroundCall.getConnectionSummary() + ")"); log("updatePhoneState oldState=" + oldState + ", newState=" + mState); } Loading Loading @@ -2608,9 +2624,35 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return null; } /** * Given a connection, detach it from any {@link ImsPhoneCall} it is associated with, remove it * from the connections lists, and ensure if it was the pending MO connection it gets removed * from there as well. * @param conn The connection to cleanup and remove. */ public synchronized void cleanupAndRemoveConnection(ImsPhoneConnection conn) { mOperationLocalLog.log("cleanupAndRemoveConnection: " + conn); // If the connection is attached to a call, detach it. if (conn.getCall() != null) { conn.getCall().detach(conn); } // Remove it from the connection list. removeConnection(conn); // Finally, if it was the pending MO, then ensure that connection gets cleaned up as well. if (conn == mPendingMO) { mPendingMO.finalize(); mPendingMO = null; } // Ensure aggregate state for this tracker is also updated to reflect the new state. updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private synchronized void removeConnection(ImsPhoneConnection conn) { public synchronized void removeConnection(ImsPhoneConnection conn) { mConnections.remove(conn); // If not emergency call is remaining, notify emergency call registrants if (mIsInEmergencyCall) { boolean isEmergencyCallInList = false; Loading Loading @@ -5311,6 +5353,11 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { return mConnections; } @VisibleForTesting public ImsPhoneConnection getPendingMO() { return mPendingMO; } /** * Set up static configuration from package/services/Telephony's config.xml. * @param config the config. Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +29 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static junit.framework.Assert.assertNotNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyString; Loading Loading @@ -1560,6 +1561,23 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { verify(mImsManager, never()).setOfferedRtpHeaderExtensionTypes(any()); } @Test @SmallTest public void testCleanupAndRemoveConnection() throws Exception { ImsPhoneConnection conn = placeCall(); assertEquals(1, mCTUT.getConnections().size()); assertNotNull(mCTUT.getPendingMO()); assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState()); assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); mCTUT.cleanupAndRemoveConnection(conn); assertEquals(0, mCTUT.getConnections().size()); assertNull(mCTUT.getPendingMO()); assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState()); assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); } private void sendCarrierConfigChanged() { Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId()); Loading Loading @@ -1595,6 +1613,16 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { } private ImsPhoneConnection placeCallAndMakeActive() { ImsPhoneConnection connection = placeCall(); ImsCall imsCall = connection.getImsCall(); imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(), new ImsStreamMediaProfile()); imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(), new ImsCallProfile()); return connection; } private ImsPhoneConnection placeCall() { try { doAnswer(new Answer<ImsCall>() { @Override Loading @@ -1606,6 +1634,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { imsCallMocking(imsCall); return imsCall; } }).when(mImsManager).makeCall(eq(mImsCallProfile), (String[]) any(), (ImsCall.Listener) any()); } catch (ImsException ie) { Loading @@ -1622,11 +1651,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { if (connection == null) { Assert.fail("connection is null"); } ImsCall imsCall = connection.getImsCall(); imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(), new ImsStreamMediaProfile()); imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(), new ImsCallProfile()); return connection; } } Loading