Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java +3 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Call; import com.android.internal.telephony.Connection; import com.android.internal.telephony.IccCard; Loading Loading @@ -104,7 +105,8 @@ abstract class ImsPhoneBase extends Phone { * * @param cn The connection. */ protected void startOnHoldTone(Connection cn) { @VisibleForTesting public void startOnHoldTone(Connection cn) { Pair<Connection, Boolean> result = new Pair<Connection, Boolean>(cn, Boolean.TRUE); mOnHoldRegistrants.notifyRegistrants(new AsyncResult(null, result, null)); } Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java +2 −2 Original line number Diff line number Diff line Loading @@ -237,8 +237,8 @@ public class ImsPhoneCall extends Call { } } /*package*/ ImsPhoneConnection getFirstConnection() { @VisibleForTesting public ImsPhoneConnection getFirstConnection() { if (mConnections.size() == 0) return null; return (ImsPhoneConnection) mConnections.get(0); Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +46 −32 Original line number Diff line number Diff line Loading @@ -311,6 +311,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private boolean mAllowEmergencyVideoCalls = false; private boolean mIgnoreDataEnabledChangedForVideoCalls = false; private boolean mIsViLteDataMetered = false; private boolean mAlwaysPlayRemoteHoldTone = false; /** * Listeners to changes in the phone state. Intended for use by other interested IMS components Loading Loading @@ -1029,6 +1030,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_VILTE_DATA_IS_METERED_BOOL); mSupportPauseVideo = carrierConfig.getBoolean( CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL); mAlwaysPlayRemoteHoldTone = carrierConfig.getBoolean( CarrierConfigManager.KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL); String[] mappings = carrierConfig .getStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY); Loading Loading @@ -2442,38 +2445,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { @Override public void onCallHoldReceived(ImsCall imsCall) { if (DBG) log("onCallHoldReceived"); ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { if (!mOnHoldToneStarted && ImsPhoneCall.isLocalTone(imsCall) && conn.getState() == ImsPhoneCall.State.ACTIVE) { mPhone.startOnHoldTone(conn); mOnHoldToneStarted = true; mOnHoldToneId = System.identityHashCode(conn); } conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null); boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean( com.android.internal.R.bool.config_useVideoPauseWorkaround); if (useVideoPauseWorkaround && mSupportPauseVideo && VideoProfile.isVideo(conn.getVideoState())) { // If we are using the video pause workaround, the vendor IMS code has issues // with video pause signalling. In this case, when a call is remotely // held, the modem does not reliably change the video state of the call to be // paused. // As a workaround, we will turn on that bit now. conn.changeToPausedState(); } } SuppServiceNotification supp = new SuppServiceNotification(); // Type of notification: 0 = MO; 1 = MT // Refer SuppServiceNotification class documentation. supp.notificationType = 1; supp.code = SuppServiceNotification.MT_CODE_CALL_ON_HOLD; mPhone.notifySuppSvcNotification(supp); mMetrics.writeOnImsCallHoldReceived(mPhone.getPhoneId(), imsCall.getCallSession()); ImsPhoneCallTracker.this.onCallHoldReceived(imsCall); } @Override Loading Loading @@ -3701,4 +3673,46 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getPhoneId(), mImsFeatureEnabled); } } @VisibleForTesting public void onCallHoldReceived(ImsCall imsCall) { if (DBG) log("onCallHoldReceived"); ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { if (!mOnHoldToneStarted && (ImsPhoneCall.isLocalTone(imsCall) || mAlwaysPlayRemoteHoldTone) && conn.getState() == ImsPhoneCall.State.ACTIVE) { mPhone.startOnHoldTone(conn); mOnHoldToneStarted = true; mOnHoldToneId = System.identityHashCode(conn); } conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null); boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean( com.android.internal.R.bool.config_useVideoPauseWorkaround); if (useVideoPauseWorkaround && mSupportPauseVideo && VideoProfile.isVideo(conn.getVideoState())) { // If we are using the video pause workaround, the vendor IMS code has issues // with video pause signalling. In this case, when a call is remotely // held, the modem does not reliably change the video state of the call to be // paused. // As a workaround, we will turn on that bit now. conn.changeToPausedState(); } } SuppServiceNotification supp = new SuppServiceNotification(); // Type of notification: 0 = MO; 1 = MT // Refer SuppServiceNotification class documentation. supp.notificationType = 1; supp.code = SuppServiceNotification.MT_CODE_CALL_ON_HOLD; mPhone.notifySuppSvcNotification(supp); mMetrics.writeOnImsCallHoldReceived(mPhone.getPhoneId(), imsCall.getCallSession()); } @VisibleForTesting public void setAlwaysPlayRemoteHoldTone(boolean shouldPlayRemoteHoldTone) { mAlwaysPlayRemoteHoldTone = shouldPlayRemoteHoldTone; } } tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +78 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import com.android.ims.ImsException; import com.android.ims.ImsManager; import com.android.ims.ImsReasonInfo; import com.android.ims.ImsServiceClass; import com.android.ims.ImsStreamMediaProfile; import com.android.ims.internal.ImsCallSession; import com.android.internal.telephony.Call; import com.android.internal.telephony.CallStateException; Loading Loading @@ -587,4 +588,81 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(DisconnectCause.DIAL_LOW_BATTERY, mCTUT.getDisconnectCauseFromReasonInfo( new ImsReasonInfo(ImsReasonInfo.CODE_LOW_BATTERY, 0), Call.State.DIALING)); } /** * Tests that no hold tone is played if the call is remotely held and the media direction is * send/receive (i.e. there is an audio stream present). */ @Test @SmallTest public void testNoRemoteHoldtone() { //establish a MT call testImsMTCallAccept(); ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); ImsCall call = connection.getImsCall(); // Set the media direction to send/receive. ImsCallProfile callProfile = new ImsCallProfile(); callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE; call.setCallProfile(callProfile); try { mCTUT.onCallHoldReceived(call); } catch (Exception ex) { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } verify(mImsPhone, never()).startOnHoldTone(nullable(Connection.class)); } /** * Verifies that a remote hold tone is played when the call is remotely held and the media * direction is inactive (i.e. the audio stream is not playing, so we should play the tone). */ @Test @SmallTest public void testRemoteToneInactive() { //establish a MT call testImsMTCallAccept(); ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); ImsCall call = connection.getImsCall(); // Set the media direction to inactive to trigger a hold tone. ImsCallProfile callProfile = new ImsCallProfile(); callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_INACTIVE; call.setCallProfile(callProfile); try { mCTUT.onCallHoldReceived(call); } catch (Exception ex) { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } verify(mImsPhone, times(1)).startOnHoldTone(nullable(Connection.class)); } @Test @SmallTest public void testRemoteHoldtone() { // Set carrier config to always play remote hold tone. mCTUT.setAlwaysPlayRemoteHoldTone(true); //establish a MT call testImsMTCallAccept(); ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); ImsCall call = connection.getImsCall(); // Set the media direction to send/receive; normally we don't play a hold tone but the // carrier config option is set to ensure we will do it in this case. ImsCallProfile callProfile = new ImsCallProfile(); callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE; call.setCallProfile(callProfile); try { mCTUT.onCallHoldReceived(call); } catch (Exception ex) { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } verify(mImsPhone, times(1)).startOnHoldTone(nullable(Connection.class)); } } Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java +3 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Call; import com.android.internal.telephony.Connection; import com.android.internal.telephony.IccCard; Loading Loading @@ -104,7 +105,8 @@ abstract class ImsPhoneBase extends Phone { * * @param cn The connection. */ protected void startOnHoldTone(Connection cn) { @VisibleForTesting public void startOnHoldTone(Connection cn) { Pair<Connection, Boolean> result = new Pair<Connection, Boolean>(cn, Boolean.TRUE); mOnHoldRegistrants.notifyRegistrants(new AsyncResult(null, result, null)); } Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java +2 −2 Original line number Diff line number Diff line Loading @@ -237,8 +237,8 @@ public class ImsPhoneCall extends Call { } } /*package*/ ImsPhoneConnection getFirstConnection() { @VisibleForTesting public ImsPhoneConnection getFirstConnection() { if (mConnections.size() == 0) return null; return (ImsPhoneConnection) mConnections.get(0); Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +46 −32 Original line number Diff line number Diff line Loading @@ -311,6 +311,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private boolean mAllowEmergencyVideoCalls = false; private boolean mIgnoreDataEnabledChangedForVideoCalls = false; private boolean mIsViLteDataMetered = false; private boolean mAlwaysPlayRemoteHoldTone = false; /** * Listeners to changes in the phone state. Intended for use by other interested IMS components Loading Loading @@ -1029,6 +1030,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_VILTE_DATA_IS_METERED_BOOL); mSupportPauseVideo = carrierConfig.getBoolean( CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL); mAlwaysPlayRemoteHoldTone = carrierConfig.getBoolean( CarrierConfigManager.KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL); String[] mappings = carrierConfig .getStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY); Loading Loading @@ -2442,38 +2445,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { @Override public void onCallHoldReceived(ImsCall imsCall) { if (DBG) log("onCallHoldReceived"); ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { if (!mOnHoldToneStarted && ImsPhoneCall.isLocalTone(imsCall) && conn.getState() == ImsPhoneCall.State.ACTIVE) { mPhone.startOnHoldTone(conn); mOnHoldToneStarted = true; mOnHoldToneId = System.identityHashCode(conn); } conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null); boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean( com.android.internal.R.bool.config_useVideoPauseWorkaround); if (useVideoPauseWorkaround && mSupportPauseVideo && VideoProfile.isVideo(conn.getVideoState())) { // If we are using the video pause workaround, the vendor IMS code has issues // with video pause signalling. In this case, when a call is remotely // held, the modem does not reliably change the video state of the call to be // paused. // As a workaround, we will turn on that bit now. conn.changeToPausedState(); } } SuppServiceNotification supp = new SuppServiceNotification(); // Type of notification: 0 = MO; 1 = MT // Refer SuppServiceNotification class documentation. supp.notificationType = 1; supp.code = SuppServiceNotification.MT_CODE_CALL_ON_HOLD; mPhone.notifySuppSvcNotification(supp); mMetrics.writeOnImsCallHoldReceived(mPhone.getPhoneId(), imsCall.getCallSession()); ImsPhoneCallTracker.this.onCallHoldReceived(imsCall); } @Override Loading Loading @@ -3701,4 +3673,46 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getPhoneId(), mImsFeatureEnabled); } } @VisibleForTesting public void onCallHoldReceived(ImsCall imsCall) { if (DBG) log("onCallHoldReceived"); ImsPhoneConnection conn = findConnection(imsCall); if (conn != null) { if (!mOnHoldToneStarted && (ImsPhoneCall.isLocalTone(imsCall) || mAlwaysPlayRemoteHoldTone) && conn.getState() == ImsPhoneCall.State.ACTIVE) { mPhone.startOnHoldTone(conn); mOnHoldToneStarted = true; mOnHoldToneId = System.identityHashCode(conn); } conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null); boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean( com.android.internal.R.bool.config_useVideoPauseWorkaround); if (useVideoPauseWorkaround && mSupportPauseVideo && VideoProfile.isVideo(conn.getVideoState())) { // If we are using the video pause workaround, the vendor IMS code has issues // with video pause signalling. In this case, when a call is remotely // held, the modem does not reliably change the video state of the call to be // paused. // As a workaround, we will turn on that bit now. conn.changeToPausedState(); } } SuppServiceNotification supp = new SuppServiceNotification(); // Type of notification: 0 = MO; 1 = MT // Refer SuppServiceNotification class documentation. supp.notificationType = 1; supp.code = SuppServiceNotification.MT_CODE_CALL_ON_HOLD; mPhone.notifySuppSvcNotification(supp); mMetrics.writeOnImsCallHoldReceived(mPhone.getPhoneId(), imsCall.getCallSession()); } @VisibleForTesting public void setAlwaysPlayRemoteHoldTone(boolean shouldPlayRemoteHoldTone) { mAlwaysPlayRemoteHoldTone = shouldPlayRemoteHoldTone; } }
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +78 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import com.android.ims.ImsException; import com.android.ims.ImsManager; import com.android.ims.ImsReasonInfo; import com.android.ims.ImsServiceClass; import com.android.ims.ImsStreamMediaProfile; import com.android.ims.internal.ImsCallSession; import com.android.internal.telephony.Call; import com.android.internal.telephony.CallStateException; Loading Loading @@ -587,4 +588,81 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { assertEquals(DisconnectCause.DIAL_LOW_BATTERY, mCTUT.getDisconnectCauseFromReasonInfo( new ImsReasonInfo(ImsReasonInfo.CODE_LOW_BATTERY, 0), Call.State.DIALING)); } /** * Tests that no hold tone is played if the call is remotely held and the media direction is * send/receive (i.e. there is an audio stream present). */ @Test @SmallTest public void testNoRemoteHoldtone() { //establish a MT call testImsMTCallAccept(); ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); ImsCall call = connection.getImsCall(); // Set the media direction to send/receive. ImsCallProfile callProfile = new ImsCallProfile(); callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE; call.setCallProfile(callProfile); try { mCTUT.onCallHoldReceived(call); } catch (Exception ex) { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } verify(mImsPhone, never()).startOnHoldTone(nullable(Connection.class)); } /** * Verifies that a remote hold tone is played when the call is remotely held and the media * direction is inactive (i.e. the audio stream is not playing, so we should play the tone). */ @Test @SmallTest public void testRemoteToneInactive() { //establish a MT call testImsMTCallAccept(); ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); ImsCall call = connection.getImsCall(); // Set the media direction to inactive to trigger a hold tone. ImsCallProfile callProfile = new ImsCallProfile(); callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_INACTIVE; call.setCallProfile(callProfile); try { mCTUT.onCallHoldReceived(call); } catch (Exception ex) { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } verify(mImsPhone, times(1)).startOnHoldTone(nullable(Connection.class)); } @Test @SmallTest public void testRemoteHoldtone() { // Set carrier config to always play remote hold tone. mCTUT.setAlwaysPlayRemoteHoldTone(true); //establish a MT call testImsMTCallAccept(); ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); ImsCall call = connection.getImsCall(); // Set the media direction to send/receive; normally we don't play a hold tone but the // carrier config option is set to ensure we will do it in this case. ImsCallProfile callProfile = new ImsCallProfile(); callProfile.mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE; call.setCallProfile(callProfile); try { mCTUT.onCallHoldReceived(call); } catch (Exception ex) { ex.printStackTrace(); Assert.fail("unexpected exception thrown" + ex.getMessage()); } verify(mImsPhone, times(1)).startOnHoldTone(nullable(Connection.class)); } }