Merge changes from topic "IMS Threading Refactoring"

* changes:
  Fix for crash while merging 2 audio calls for initiating conference call
  (IMS Threading refactoring) Telephony IMS classes to schedule IMS callback on the main thread
This commit is contained in:
Parvathy Shanmugam 2022-02-04 10:52:40 +00:00 committed by Gerrit Code Review
commit a28bba3ebe
2 changed files with 254 additions and 140 deletions

View File

@ -107,6 +107,25 @@ public final class TelephonyUtils {
} }
} }
/**
* Convenience method for running the provided action in the provided
* executor enclosed in
* {@link Binder#clearCallingIdentity}/{@link Binder#restoreCallingIdentity}
*
* Any exception thrown by the given action will need to be handled by caller.
*
*/
public static void runWithCleanCallingIdentity(
@NonNull Runnable action, @NonNull Executor executor) {
if (action != null) {
if (executor != null) {
executor.execute(() -> runWithCleanCallingIdentity(action));
} else {
runWithCleanCallingIdentity(action);
}
}
}
/** /**
* Convenience method for running the provided action enclosed in * Convenience method for running the provided action enclosed in

View File

@ -27,10 +27,12 @@ import android.util.Log;
import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsVideoCallProvider; import com.android.ims.internal.IImsVideoCallProvider;
import com.android.internal.telephony.util.TelephonyUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executor;
/** /**
* Provides the call initiation/termination, and media exchange between two IMS endpoints. * Provides the call initiation/termination, and media exchange between two IMS endpoints.
@ -522,6 +524,7 @@ public class ImsCallSession {
private final IImsCallSession miSession; private final IImsCallSession miSession;
private boolean mClosed = false; private boolean mClosed = false;
private Listener mListener; private Listener mListener;
private Executor mListenerExecutor = Runnable::run;
/** @hide */ /** @hide */
public ImsCallSession(IImsCallSession iSession) { public ImsCallSession(IImsCallSession iSession) {
@ -538,9 +541,9 @@ public class ImsCallSession {
} }
/** @hide */ /** @hide */
public ImsCallSession(IImsCallSession iSession, Listener listener) { public ImsCallSession(IImsCallSession iSession, Listener listener, Executor executor) {
this(iSession); this(iSession);
setListener(listener); setListener(listener, executor);
} }
/** /**
@ -738,10 +741,14 @@ public class ImsCallSession {
* override the previous listener. * override the previous listener.
* *
* @param listener to listen to the session events of this object * @param listener to listen to the session events of this object
* @param executor an Executor that will execute callbacks
* @hide * @hide
*/ */
public void setListener(Listener listener) { public void setListener(Listener listener, Executor executor) {
mListener = listener; mListener = listener;
if (executor != null) {
mListenerExecutor = executor;
}
} }
/** /**
@ -1205,44 +1212,56 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionInitiating(ImsCallProfile profile) { public void callSessionInitiating(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionInitiating(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionInitiating(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionProgressing(ImsStreamMediaProfile profile) { public void callSessionProgressing(ImsStreamMediaProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionProgressing(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionProgressing(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionInitiated(ImsCallProfile profile) { public void callSessionInitiated(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionStarted(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionStarted(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionInitiatingFailed(ImsReasonInfo reasonInfo) { public void callSessionInitiatingFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) { public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionTerminated(ImsReasonInfo reasonInfo) { public void callSessionTerminated(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionTerminated(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionTerminated(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1250,44 +1269,56 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionHeld(ImsCallProfile profile) { public void callSessionHeld(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionHeld(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionHeld(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionHoldFailed(ImsReasonInfo reasonInfo) { public void callSessionHoldFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionHoldReceived(ImsCallProfile profile) { public void callSessionHoldReceived(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionHoldReceived(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionHoldReceived(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionResumed(ImsCallProfile profile) { public void callSessionResumed(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionResumed(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionResumed(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionResumeFailed(ImsReasonInfo reasonInfo) { public void callSessionResumeFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionResumeReceived(ImsCallProfile profile) { public void callSessionResumeReceived(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionResumeReceived(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionResumeReceived(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
/** /**
@ -1310,15 +1341,17 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionMergeComplete(IImsCallSession newSession) { public void callSessionMergeComplete(IImsCallSession newSession) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
if (newSession != null) { if (mListener != null) {
// New session created after conference if (newSession != null) {
mListener.callSessionMergeComplete(new ImsCallSession(newSession)); // New session created after conference
} else { mListener.callSessionMergeComplete(new ImsCallSession(newSession));
// Session already exists. Hence no need to pass } else {
mListener.callSessionMergeComplete(null); // Session already exists. Hence no need to pass
} mListener.callSessionMergeComplete(null);
} }
}
}, mListenerExecutor);
} }
/** /**
@ -1328,9 +1361,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionMergeFailed(ImsReasonInfo reasonInfo) { public void callSessionMergeFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1338,23 +1373,29 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionUpdated(ImsCallProfile profile) { public void callSessionUpdated(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionUpdated(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionUpdated(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) { public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionUpdateReceived(ImsCallProfile profile) { public void callSessionUpdateReceived(ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionUpdateReceived(ImsCallSession.this, profile); if (mListener != null) {
} mListener.callSessionUpdateReceived(ImsCallSession.this, profile);
}
}, mListenerExecutor);
} }
/** /**
@ -1363,26 +1404,33 @@ public class ImsCallSession {
@Override @Override
public void callSessionConferenceExtended(IImsCallSession newSession, public void callSessionConferenceExtended(IImsCallSession newSession,
ImsCallProfile profile) { ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionConferenceExtended(ImsCallSession.this, if (mListener != null) {
new ImsCallSession(newSession), profile); mListener.callSessionConferenceExtended(ImsCallSession.this,
} new ImsCallSession(newSession), profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) { public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionConferenceExtendFailed(
ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionConferenceExtendReceived(IImsCallSession newSession, public void callSessionConferenceExtendReceived(IImsCallSession newSession,
ImsCallProfile profile) { ImsCallProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionConferenceExtendReceived(ImsCallSession.this, if (mListener != null) {
new ImsCallSession(newSession), profile); mListener.callSessionConferenceExtendReceived(ImsCallSession.this,
} new ImsCallSession(newSession), profile);
}
}, mListenerExecutor);
} }
/** /**
@ -1391,32 +1439,41 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionInviteParticipantsRequestDelivered() { public void callSessionInviteParticipantsRequestDelivered() {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this); if (mListener != null) {
} mListener.callSessionInviteParticipantsRequestDelivered(
ImsCallSession.this);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) { public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this, if (mListener != null) {
reasonInfo); mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this,
} reasonInfo);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionRemoveParticipantsRequestDelivered() { public void callSessionRemoveParticipantsRequestDelivered() {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this); if (mListener != null) {
} mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) { public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this, if (mListener != null) {
reasonInfo); mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this,
} reasonInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1424,9 +1481,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionConferenceStateUpdated(ImsConferenceState state) { public void callSessionConferenceStateUpdated(ImsConferenceState state) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state); if (mListener != null) {
} mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state);
}
}, mListenerExecutor);
} }
/** /**
@ -1434,9 +1493,12 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionUssdMessageReceived(int mode, String ussdMessage) { public void callSessionUssdMessageReceived(int mode, String ussdMessage) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage); if (mListener != null) {
} mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode,
ussdMessage);
}
}, mListenerExecutor);
} }
/** /**
@ -1452,10 +1514,12 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionMayHandover(int srcNetworkType, int targetNetworkType) { public void callSessionMayHandover(int srcNetworkType, int targetNetworkType) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionMayHandover(ImsCallSession.this, srcNetworkType, if (mListener != null) {
targetNetworkType); mListener.callSessionMayHandover(ImsCallSession.this, srcNetworkType,
} targetNetworkType);
}
}, mListenerExecutor);
} }
/** /**
@ -1464,10 +1528,12 @@ public class ImsCallSession {
@Override @Override
public void callSessionHandover(int srcNetworkType, int targetNetworkType, public void callSessionHandover(int srcNetworkType, int targetNetworkType,
ImsReasonInfo reasonInfo) { ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionHandover(ImsCallSession.this, srcNetworkType, if (mListener != null) {
targetNetworkType, reasonInfo); mListener.callSessionHandover(ImsCallSession.this, srcNetworkType,
} targetNetworkType, reasonInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1476,10 +1542,12 @@ public class ImsCallSession {
@Override @Override
public void callSessionHandoverFailed(int srcNetworkType, int targetNetworkType, public void callSessionHandoverFailed(int srcNetworkType, int targetNetworkType,
ImsReasonInfo reasonInfo) { ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionHandoverFailed(ImsCallSession.this, srcNetworkType, if (mListener != null) {
targetNetworkType, reasonInfo); mListener.callSessionHandoverFailed(ImsCallSession.this, srcNetworkType,
} targetNetworkType, reasonInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1487,9 +1555,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionTtyModeReceived(int mode) { public void callSessionTtyModeReceived(int mode) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionTtyModeReceived(ImsCallSession.this, mode); if (mListener != null) {
} mListener.callSessionTtyModeReceived(ImsCallSession.this, mode);
}
}, mListenerExecutor);
} }
/** /**
@ -1499,16 +1569,22 @@ public class ImsCallSession {
* otherwise. * otherwise.
*/ */
public void callSessionMultipartyStateChanged(boolean isMultiParty) { public void callSessionMultipartyStateChanged(boolean isMultiParty) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionMultipartyStateChanged(ImsCallSession.this, isMultiParty); if (mListener != null) {
} mListener.callSessionMultipartyStateChanged(ImsCallSession.this,
isMultiParty);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppServiceInfo ) { public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppServiceInfo ) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionSuppServiceReceived(ImsCallSession.this, suppServiceInfo); if (mListener != null) {
} mListener.callSessionSuppServiceReceived(ImsCallSession.this,
suppServiceInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1516,9 +1592,12 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) { public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRttModifyRequestReceived(ImsCallSession.this, callProfile); if (mListener != null) {
} mListener.callSessionRttModifyRequestReceived(ImsCallSession.this,
callProfile);
}
}, mListenerExecutor);
} }
/** /**
@ -1526,9 +1605,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionRttModifyResponseReceived(int status) { public void callSessionRttModifyResponseReceived(int status) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRttModifyResponseReceived(status); if (mListener != null) {
} mListener.callSessionRttModifyResponseReceived(status);
}
}, mListenerExecutor);
} }
/** /**
@ -1536,9 +1617,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionRttMessageReceived(String rttMessage) { public void callSessionRttMessageReceived(String rttMessage) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRttMessageReceived(rttMessage); if (mListener != null) {
} mListener.callSessionRttMessageReceived(rttMessage);
}
}, mListenerExecutor);
} }
/** /**
@ -1546,23 +1629,29 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) { public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRttAudioIndicatorChanged(profile); if (mListener != null) {
} mListener.callSessionRttAudioIndicatorChanged(profile);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionTransferred() { public void callSessionTransferred() {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionTransferred(ImsCallSession.this); if (mListener != null) {
} mListener.callSessionTransferred(ImsCallSession.this);
}
}, mListenerExecutor);
} }
@Override @Override
public void callSessionTransferFailed(@Nullable ImsReasonInfo reasonInfo) { public void callSessionTransferFailed(@Nullable ImsReasonInfo reasonInfo) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionTransferFailed(ImsCallSession.this, reasonInfo); if (mListener != null) {
} mListener.callSessionTransferFailed(ImsCallSession.this, reasonInfo);
}
}, mListenerExecutor);
} }
/** /**
@ -1571,9 +1660,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callSessionDtmfReceived(char dtmf) { public void callSessionDtmfReceived(char dtmf) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionDtmfReceived(dtmf); if (mListener != null) {
} mListener.callSessionDtmfReceived(dtmf);
}
}, mListenerExecutor);
} }
/** /**
@ -1581,9 +1672,11 @@ public class ImsCallSession {
*/ */
@Override @Override
public void callQualityChanged(CallQuality callQuality) { public void callQualityChanged(CallQuality callQuality) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callQualityChanged(callQuality); if (mListener != null) {
} mListener.callQualityChanged(callQuality);
}
}, mListenerExecutor);
} }
/** /**
@ -1593,10 +1686,12 @@ public class ImsCallSession {
@Override @Override
public void callSessionRtpHeaderExtensionsReceived( public void callSessionRtpHeaderExtensionsReceived(
@NonNull List<RtpHeaderExtension> extensions) { @NonNull List<RtpHeaderExtension> extensions) {
if (mListener != null) { TelephonyUtils.runWithCleanCallingIdentity(()-> {
mListener.callSessionRtpHeaderExtensionsReceived( if (mListener != null) {
new ArraySet<RtpHeaderExtension>(extensions)); mListener.callSessionRtpHeaderExtensionsReceived(
} new ArraySet<RtpHeaderExtension>(extensions));
}
}, mListenerExecutor);
} }
} }