This matches the new AIDL definition in the API. Test: Manual Bug: 62489988 Change-Id: I97ad5b5359f19d533b5b8644fd37008c0c69bf9c
1434 lines
45 KiB
Java
1434 lines
45 KiB
Java
/*
|
|
* Copyright (c) 2013 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.ims.internal;
|
|
|
|
import android.os.Message;
|
|
import android.os.RemoteException;
|
|
|
|
import java.util.Objects;
|
|
|
|
import android.telephony.ims.stub.ImsCallSessionListenerImplBase;
|
|
import android.util.Log;
|
|
import com.android.ims.ImsCallProfile;
|
|
import com.android.ims.ImsConferenceState;
|
|
import com.android.ims.ImsReasonInfo;
|
|
import com.android.ims.ImsStreamMediaProfile;
|
|
import com.android.ims.ImsSuppServiceNotification;
|
|
|
|
/**
|
|
* Provides the call initiation/termination, and media exchange between two IMS endpoints.
|
|
* It directly communicates with IMS service which implements the IMS protocol behavior.
|
|
*
|
|
* @hide
|
|
*/
|
|
public class ImsCallSession {
|
|
private static final String TAG = "ImsCallSession";
|
|
|
|
/**
|
|
* Defines IMS call session state.
|
|
*/
|
|
public static class State {
|
|
public static final int IDLE = 0;
|
|
public static final int INITIATED = 1;
|
|
public static final int NEGOTIATING = 2;
|
|
public static final int ESTABLISHING = 3;
|
|
public static final int ESTABLISHED = 4;
|
|
|
|
public static final int RENEGOTIATING = 5;
|
|
public static final int REESTABLISHING = 6;
|
|
|
|
public static final int TERMINATING = 7;
|
|
public static final int TERMINATED = 8;
|
|
|
|
public static final int INVALID = (-1);
|
|
|
|
/**
|
|
* Converts the state to string.
|
|
*/
|
|
public static String toString(int state) {
|
|
switch (state) {
|
|
case IDLE:
|
|
return "IDLE";
|
|
case INITIATED:
|
|
return "INITIATED";
|
|
case NEGOTIATING:
|
|
return "NEGOTIATING";
|
|
case ESTABLISHING:
|
|
return "ESTABLISHING";
|
|
case ESTABLISHED:
|
|
return "ESTABLISHED";
|
|
case RENEGOTIATING:
|
|
return "RENEGOTIATING";
|
|
case REESTABLISHING:
|
|
return "REESTABLISHING";
|
|
case TERMINATING:
|
|
return "TERMINATING";
|
|
case TERMINATED:
|
|
return "TERMINATED";
|
|
default:
|
|
return "UNKNOWN";
|
|
}
|
|
}
|
|
|
|
private State() {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listener for events relating to an IMS session, such as when a session is being
|
|
* recieved ("on ringing") or a call is outgoing ("on calling").
|
|
* <p>Many of these events are also received by {@link ImsCall.Listener}.</p>
|
|
*/
|
|
public static class Listener {
|
|
/**
|
|
* Called when a request is sent out to initiate a new session
|
|
* and 1xx response is received from the network.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionProgressing(ImsCallSession session,
|
|
ImsStreamMediaProfile profile) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the session is established.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionStarted(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the session establishment is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the session establishment failure
|
|
*/
|
|
public void callSessionStartFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session is terminated.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the session termination
|
|
*/
|
|
public void callSessionTerminated(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session is in hold.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionHeld(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session hold is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the session hold failure
|
|
*/
|
|
public void callSessionHoldFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session hold is received from the remote user.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionHoldReceived(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session resume is done.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionResumed(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session resume is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the session resume failure
|
|
*/
|
|
public void callSessionResumeFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session resume is received from the remote user.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionResumeReceived(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session merge has been started. At this point, the {@code newSession}
|
|
* represents the session which has been initiated to the IMS conference server for the
|
|
* new merged conference.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param newSession the session object that is merged with an active & hold session
|
|
*/
|
|
public void callSessionMergeStarted(ImsCallSession session,
|
|
ImsCallSession newSession, ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session merge is successful and the merged session is active.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionMergeComplete(ImsCallSession session) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session merge has failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the call merge failure
|
|
*/
|
|
public void callSessionMergeFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session is updated (except for hold/unhold).
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionUpdated(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session update is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the session update failure
|
|
*/
|
|
public void callSessionUpdateFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the session update is received from the remote user.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionUpdateReceived(ImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the session is extended to the conference session.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param newSession the session object that is extended to the conference
|
|
* from the active session
|
|
*/
|
|
public void callSessionConferenceExtended(ImsCallSession session,
|
|
ImsCallSession newSession, ImsCallProfile profile) {
|
|
}
|
|
|
|
/**
|
|
* Called when the conference extension is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the conference extension failure
|
|
*/
|
|
public void callSessionConferenceExtendFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
}
|
|
|
|
/**
|
|
* Called when the conference extension is received from the remote user.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionConferenceExtendReceived(ImsCallSession session,
|
|
ImsCallSession newSession, ImsCallProfile profile) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the invitation request of the participants is delivered to the conference
|
|
* server.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the invitation request of the participants is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the conference invitation failure
|
|
*/
|
|
public void callSessionInviteParticipantsRequestFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the removal request of the participants is delivered to the conference
|
|
* server.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the removal request of the participants is failed.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
* @param reasonInfo detailed reason of the conference removal failure
|
|
*/
|
|
public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the conference state is updated.
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionConferenceStateUpdated(ImsCallSession session,
|
|
ImsConferenceState state) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the USSD message is received from the network.
|
|
*
|
|
* @param mode mode of the USSD message (REQUEST / NOTIFY)
|
|
* @param ussdMessage USSD message
|
|
*/
|
|
public void callSessionUssdMessageReceived(ImsCallSession session,
|
|
int mode, String ussdMessage) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when an {@link ImsCallSession} may handover from one radio technology to another.
|
|
* For example, the session may handover from WIFI to LTE if conditions are right.
|
|
* <p>
|
|
* If handover is attempted,
|
|
* {@link #callSessionHandover(ImsCallSession, int, int, ImsReasonInfo)} or
|
|
* {@link #callSessionHandoverFailed(ImsCallSession, int, int, ImsReasonInfo)} will be
|
|
* called to indicate the success or failure of the handover.
|
|
*
|
|
* @param session IMS session object
|
|
* @param srcAccessTech original access technology
|
|
* @param targetAccessTech new access technology
|
|
*/
|
|
public void callSessionMayHandover(ImsCallSession session, int srcAccessTech,
|
|
int targetAccessTech) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when session access technology changes
|
|
*
|
|
* @param session IMS session object
|
|
* @param srcAccessTech original access technology
|
|
* @param targetAccessTech new access technology
|
|
* @param reasonInfo
|
|
*/
|
|
public void callSessionHandover(ImsCallSession session,
|
|
int srcAccessTech, int targetAccessTech,
|
|
ImsReasonInfo reasonInfo) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when session access technology change fails
|
|
*
|
|
* @param session IMS session object
|
|
* @param srcAccessTech original access technology
|
|
* @param targetAccessTech new access technology
|
|
* @param reasonInfo handover failure reason
|
|
*/
|
|
public void callSessionHandoverFailed(ImsCallSession session,
|
|
int srcAccessTech, int targetAccessTech,
|
|
ImsReasonInfo reasonInfo) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when TTY mode of remote party changed
|
|
*
|
|
* @param session IMS session object
|
|
* @param mode TTY mode of remote party
|
|
*/
|
|
public void callSessionTtyModeReceived(ImsCallSession session,
|
|
int mode) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Notifies of a change to the multiparty state for this {@code ImsCallSession}.
|
|
*
|
|
* @param session The call session.
|
|
* @param isMultiParty {@code true} if the session became multiparty, {@code false}
|
|
* otherwise.
|
|
*/
|
|
public void callSessionMultipartyStateChanged(ImsCallSession session,
|
|
boolean isMultiParty) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Called when the session supplementary service is received
|
|
*
|
|
* @param session the session object that carries out the IMS session
|
|
*/
|
|
public void callSessionSuppServiceReceived(ImsCallSession session,
|
|
ImsSuppServiceNotification suppServiceInfo) {
|
|
}
|
|
|
|
/**
|
|
* Received RTT modify request from Remote Party
|
|
*/
|
|
public void callSessionRttModifyRequestReceived(ImsCallSession session,
|
|
ImsCallProfile callProfile) {
|
|
// no-op
|
|
}
|
|
|
|
/**
|
|
* Received response for RTT modify request
|
|
*/
|
|
public void callSessionRttModifyResponseReceived(int status) {
|
|
// no -op
|
|
}
|
|
|
|
/**
|
|
* Device received RTT message from Remote UE
|
|
*/
|
|
public void callSessionRttMessageReceived(String rttMessage) {
|
|
// no-op
|
|
}
|
|
}
|
|
|
|
private final IImsCallSession miSession;
|
|
private boolean mClosed = false;
|
|
private Listener mListener;
|
|
|
|
public ImsCallSession(IImsCallSession iSession) {
|
|
miSession = iSession;
|
|
|
|
if (iSession != null) {
|
|
try {
|
|
iSession.setListener(new IImsCallSessionListenerProxy());
|
|
} catch (RemoteException e) {
|
|
}
|
|
} else {
|
|
mClosed = true;
|
|
}
|
|
}
|
|
|
|
public ImsCallSession(IImsCallSession iSession, Listener listener) {
|
|
this(iSession);
|
|
setListener(listener);
|
|
}
|
|
|
|
/**
|
|
* Closes this object. This object is not usable after being closed.
|
|
*/
|
|
public synchronized void close() {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.close();
|
|
mClosed = true;
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the call ID of the session.
|
|
*
|
|
* @return the call ID
|
|
*/
|
|
public String getCallId() {
|
|
if (mClosed) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return miSession.getCallId();
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the call profile that this session is associated with
|
|
*
|
|
* @return the call profile that this session is associated with
|
|
*/
|
|
public ImsCallProfile getCallProfile() {
|
|
if (mClosed) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return miSession.getCallProfile();
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the local call profile that this session is associated with
|
|
*
|
|
* @return the local call profile that this session is associated with
|
|
*/
|
|
public ImsCallProfile getLocalCallProfile() {
|
|
if (mClosed) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return miSession.getLocalCallProfile();
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the remote call profile that this session is associated with
|
|
*
|
|
* @return the remote call profile that this session is associated with
|
|
*/
|
|
public ImsCallProfile getRemoteCallProfile() {
|
|
if (mClosed) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return miSession.getRemoteCallProfile();
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the video call provider for the session.
|
|
*
|
|
* @return The video call provider.
|
|
*/
|
|
public IImsVideoCallProvider getVideoCallProvider() {
|
|
if (mClosed) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return miSession.getVideoCallProvider();
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the value associated with the specified property of this session.
|
|
*
|
|
* @return the string value associated with the specified property
|
|
*/
|
|
public String getProperty(String name) {
|
|
if (mClosed) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return miSession.getProperty(name);
|
|
} catch (RemoteException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the session state.
|
|
* The value returned must be one of the states in {@link State}.
|
|
*
|
|
* @return the session state
|
|
*/
|
|
public int getState() {
|
|
if (mClosed) {
|
|
return State.INVALID;
|
|
}
|
|
|
|
try {
|
|
return miSession.getState();
|
|
} catch (RemoteException e) {
|
|
return State.INVALID;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determines if the {@link ImsCallSession} is currently alive (e.g. not in a terminated or
|
|
* closed state).
|
|
*
|
|
* @return {@code True} if the session is alive.
|
|
*/
|
|
public boolean isAlive() {
|
|
if (mClosed) {
|
|
return false;
|
|
}
|
|
|
|
int state = getState();
|
|
switch (state) {
|
|
case State.IDLE:
|
|
case State.INITIATED:
|
|
case State.NEGOTIATING:
|
|
case State.ESTABLISHING:
|
|
case State.ESTABLISHED:
|
|
case State.RENEGOTIATING:
|
|
case State.REESTABLISHING:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the native IMS call session.
|
|
* @hide
|
|
*/
|
|
public IImsCallSession getSession() {
|
|
return miSession;
|
|
}
|
|
|
|
/**
|
|
* Checks if the session is in call.
|
|
*
|
|
* @return true if the session is in call
|
|
*/
|
|
public boolean isInCall() {
|
|
if (mClosed) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
return miSession.isInCall();
|
|
} catch (RemoteException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the listener to listen to the session events. A {@link ImsCallSession}
|
|
* can only hold one listener at a time. Subsequent calls to this method
|
|
* override the previous listener.
|
|
*
|
|
* @param listener to listen to the session events of this object
|
|
*/
|
|
public void setListener(Listener listener) {
|
|
mListener = listener;
|
|
}
|
|
|
|
/**
|
|
* Mutes or unmutes the mic for the active call.
|
|
*
|
|
* @param muted true if the call is muted, false otherwise
|
|
*/
|
|
public void setMute(boolean muted) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.setMute(muted);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initiates an IMS call with the specified target and call profile.
|
|
* The session listener is called back upon defined session events.
|
|
* The method is only valid to call when the session state is in
|
|
* {@link ImsCallSession.State#IDLE}.
|
|
*
|
|
* @param callee dialed string to make the call to
|
|
* @param profile call profile to make the call with the specified service type,
|
|
* call type and media information
|
|
* @see Listener#callSessionStarted, Listener#callSessionStartFailed
|
|
*/
|
|
public void start(String callee, ImsCallProfile profile) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.start(callee, profile);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initiates an IMS conference call with the specified target and call profile.
|
|
* The session listener is called back upon defined session events.
|
|
* The method is only valid to call when the session state is in
|
|
* {@link ImsCallSession.State#IDLE}.
|
|
*
|
|
* @param participants participant list to initiate an IMS conference call
|
|
* @param profile call profile to make the call with the specified service type,
|
|
* call type and media information
|
|
* @see Listener#callSessionStarted, Listener#callSessionStartFailed
|
|
*/
|
|
public void start(String[] participants, ImsCallProfile profile) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.startConference(participants, profile);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Accepts an incoming call or session update.
|
|
*
|
|
* @param callType call type specified in {@link ImsCallProfile} to be answered
|
|
* @param profile stream media profile {@link ImsStreamMediaProfile} to be answered
|
|
* @see Listener#callSessionStarted
|
|
*/
|
|
public void accept(int callType, ImsStreamMediaProfile profile) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.accept(callType, profile);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rejects an incoming call or session update.
|
|
*
|
|
* @param reason reason code to reject an incoming call
|
|
* @see Listener#callSessionStartFailed
|
|
*/
|
|
public void reject(int reason) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.reject(reason);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Terminates a call.
|
|
*
|
|
* @see Listener#callSessionTerminated
|
|
*/
|
|
public void terminate(int reason) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.terminate(reason);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Puts a call on hold. When it succeeds, {@link Listener#callSessionHeld} is called.
|
|
*
|
|
* @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call
|
|
* @see Listener#callSessionHeld, Listener#callSessionHoldFailed
|
|
*/
|
|
public void hold(ImsStreamMediaProfile profile) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.hold(profile);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Continues a call that's on hold. When it succeeds,
|
|
* {@link Listener#callSessionResumed} is called.
|
|
*
|
|
* @param profile stream media profile {@link ImsStreamMediaProfile} to resume the call
|
|
* @see Listener#callSessionResumed, Listener#callSessionResumeFailed
|
|
*/
|
|
public void resume(ImsStreamMediaProfile profile) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.resume(profile);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Merges the active & hold call. When it succeeds,
|
|
* {@link Listener#callSessionMergeStarted} is called.
|
|
*
|
|
* @see Listener#callSessionMergeStarted , Listener#callSessionMergeFailed
|
|
*/
|
|
public void merge() {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.merge();
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the current call's properties (ex. call mode change: video upgrade / downgrade).
|
|
*
|
|
* @param callType call type specified in {@link ImsCallProfile} to be updated
|
|
* @param profile stream media profile {@link ImsStreamMediaProfile} to be updated
|
|
* @see Listener#callSessionUpdated, Listener#callSessionUpdateFailed
|
|
*/
|
|
public void update(int callType, ImsStreamMediaProfile profile) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.update(callType, profile);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extends this call to the conference call with the specified recipients.
|
|
*
|
|
* @param participants list to be invited to the conference call after extending the call
|
|
* @see Listener#callSessionConferenceExtended
|
|
* @see Listener#callSessionConferenceExtendFailed
|
|
*/
|
|
public void extendToConference(String[] participants) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.extendToConference(participants);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Requests the conference server to invite an additional participants to the conference.
|
|
*
|
|
* @param participants list to be invited to the conference call
|
|
* @see Listener#callSessionInviteParticipantsRequestDelivered
|
|
* @see Listener#callSessionInviteParticipantsRequestFailed
|
|
*/
|
|
public void inviteParticipants(String[] participants) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.inviteParticipants(participants);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Requests the conference server to remove the specified participants from the conference.
|
|
*
|
|
* @param participants participant list to be removed from the conference call
|
|
* @see Listener#callSessionRemoveParticipantsRequestDelivered
|
|
* @see Listener#callSessionRemoveParticipantsRequestFailed
|
|
*/
|
|
public void removeParticipants(String[] participants) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.removeParticipants(participants);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
|
|
* event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
|
|
* and event flash to 16. Currently, event flash is not supported.
|
|
*
|
|
* @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
|
|
*/
|
|
public void sendDtmf(char c, Message result) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.sendDtmf(c, result);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Starts a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
|
|
* event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
|
|
* and event flash to 16. Currently, event flash is not supported.
|
|
*
|
|
* @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
|
|
*/
|
|
public void startDtmf(char c) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.startDtmf(c);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stops a DTMF code.
|
|
*/
|
|
public void stopDtmf() {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.stopDtmf();
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends an USSD message.
|
|
*
|
|
* @param ussdMessage USSD message to send
|
|
*/
|
|
public void sendUssd(String ussdMessage) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.sendUssd(ussdMessage);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determines if the session is multiparty.
|
|
*
|
|
* @return {@code True} if the session is multiparty.
|
|
*/
|
|
public boolean isMultiparty() {
|
|
if (mClosed) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
return miSession.isMultiparty();
|
|
} catch (RemoteException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends Rtt Message
|
|
*
|
|
* @param rttMessage rtt text to be sent
|
|
* @throws ImsException if call is absent
|
|
*/
|
|
public void sendRttMessage(String rttMessage) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.sendRttMessage(rttMessage);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends RTT Upgrade request
|
|
*
|
|
* @param to : expected profile
|
|
* @throws CallStateException
|
|
*/
|
|
public void sendRttModifyRequest(ImsCallProfile to) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.sendRttModifyRequest(to);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends RTT Upgrade response
|
|
*
|
|
* @param response : response for upgrade
|
|
* @throws CallStateException
|
|
*/
|
|
public void sendRttModifyResponse(boolean response) {
|
|
if (mClosed) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
miSession.sendRttModifyResponse(response);
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A listener type for receiving notification on IMS call session events.
|
|
* When an event is generated for an {@link IImsCallSession},
|
|
* the application is notified by having one of the methods called on
|
|
* the {@link IImsCallSessionListener}.
|
|
*/
|
|
private class IImsCallSessionListenerProxy extends ImsCallSessionListenerImplBase {
|
|
/**
|
|
* Notifies the result of the basic session operation (setup / terminate).
|
|
*/
|
|
@Override
|
|
public void callSessionProgressing(IImsCallSession session,
|
|
ImsStreamMediaProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionProgressing(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionStarted(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionStarted(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionStartFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionTerminated(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionTerminated(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the result of the call hold/resume operation.
|
|
*/
|
|
@Override
|
|
public void callSessionHeld(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionHeld(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionHoldFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionHoldReceived(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionHoldReceived(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionResumed(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionResumed(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionResumeFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionResumeReceived(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionResumeReceived(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the start of a call merge operation.
|
|
*
|
|
* @param session The call session.
|
|
* @param newSession The merged call session.
|
|
* @param profile The call profile.
|
|
*/
|
|
@Override
|
|
public void callSessionMergeStarted(IImsCallSession session,
|
|
IImsCallSession newSession, ImsCallProfile profile) {
|
|
// This callback can be used for future use to add additional
|
|
// functionality that may be needed between conference start and complete
|
|
Log.d(TAG, "callSessionMergeStarted");
|
|
}
|
|
|
|
/**
|
|
* Notifies the successful completion of a call merge operation.
|
|
*
|
|
* @param newSession The call session.
|
|
*/
|
|
@Override
|
|
public void callSessionMergeComplete(IImsCallSession newSession) {
|
|
if (mListener != null) {
|
|
if (newSession != null) {
|
|
// Check if the active session is the same session that was
|
|
// active before the merge request was sent.
|
|
ImsCallSession validActiveSession = ImsCallSession.this;
|
|
try {
|
|
if (!Objects.equals(miSession.getCallId(), newSession.getCallId())) {
|
|
// New session created after conference
|
|
validActiveSession = new ImsCallSession(newSession);
|
|
}
|
|
} catch (RemoteException rex) {
|
|
Log.e(TAG, "callSessionMergeComplete: exception for getCallId!");
|
|
}
|
|
mListener.callSessionMergeComplete(validActiveSession);
|
|
} else {
|
|
// Session already exists. Hence no need to pass
|
|
mListener.callSessionMergeComplete(null);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies of a failure to perform a call merge operation.
|
|
*
|
|
* @param session The call session.
|
|
* @param reasonInfo The merge failure reason.
|
|
*/
|
|
@Override
|
|
public void callSessionMergeFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the result of call upgrade / downgrade or any other call updates.
|
|
*/
|
|
@Override
|
|
public void callSessionUpdated(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionUpdated(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionUpdateFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionUpdateReceived(IImsCallSession session,
|
|
ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionUpdateReceived(ImsCallSession.this, profile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the result of conference extension.
|
|
*/
|
|
@Override
|
|
public void callSessionConferenceExtended(IImsCallSession session,
|
|
IImsCallSession newSession, ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionConferenceExtended(ImsCallSession.this,
|
|
new ImsCallSession(newSession), profile);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionConferenceExtendFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionConferenceExtendReceived(IImsCallSession session,
|
|
IImsCallSession newSession, ImsCallProfile profile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionConferenceExtendReceived(ImsCallSession.this,
|
|
new ImsCallSession(newSession), profile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the result of the participant invitation / removal to/from
|
|
* the conference session.
|
|
*/
|
|
@Override
|
|
public void callSessionInviteParticipantsRequestDelivered(IImsCallSession session) {
|
|
if (mListener != null) {
|
|
mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionInviteParticipantsRequestFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this,
|
|
reasonInfo);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionRemoveParticipantsRequestDelivered(IImsCallSession session) {
|
|
if (mListener != null) {
|
|
mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionRemoveParticipantsRequestFailed(IImsCallSession session,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this,
|
|
reasonInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the changes of the conference info. in the conference session.
|
|
*/
|
|
@Override
|
|
public void callSessionConferenceStateUpdated(IImsCallSession session,
|
|
ImsConferenceState state) {
|
|
if (mListener != null) {
|
|
mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the incoming USSD message.
|
|
*/
|
|
@Override
|
|
public void callSessionUssdMessageReceived(IImsCallSession session,
|
|
int mode, String ussdMessage) {
|
|
if (mListener != null) {
|
|
mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies of a case where a {@link com.android.ims.internal.ImsCallSession} may
|
|
* potentially handover from one radio technology to another.
|
|
* @param session
|
|
* @param srcAccessTech The source radio access technology; one of the access technology
|
|
* constants defined in {@link android.telephony.ServiceState}. For
|
|
* example
|
|
* {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}.
|
|
* @param targetAccessTech The target radio access technology; one of the access technology
|
|
* constants defined in {@link android.telephony.ServiceState}. For
|
|
* example
|
|
* {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}.
|
|
*/
|
|
@Override
|
|
public void callSessionMayHandover(IImsCallSession session,
|
|
int srcAccessTech, int targetAccessTech) {
|
|
if (mListener != null) {
|
|
mListener.callSessionMayHandover(ImsCallSession.this, srcAccessTech,
|
|
targetAccessTech);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies of handover information for this call
|
|
*/
|
|
@Override
|
|
public void callSessionHandover(IImsCallSession session,
|
|
int srcAccessTech, int targetAccessTech,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionHandover(ImsCallSession.this, srcAccessTech,
|
|
targetAccessTech, reasonInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies of handover failure info for this call
|
|
*/
|
|
@Override
|
|
public void callSessionHandoverFailed(IImsCallSession session,
|
|
int srcAccessTech, int targetAccessTech,
|
|
ImsReasonInfo reasonInfo) {
|
|
if (mListener != null) {
|
|
mListener.callSessionHandoverFailed(ImsCallSession.this, srcAccessTech,
|
|
targetAccessTech, reasonInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies the TTY mode received from remote party.
|
|
*/
|
|
@Override
|
|
public void callSessionTtyModeReceived(IImsCallSession session,
|
|
int mode) {
|
|
if (mListener != null) {
|
|
mListener.callSessionTtyModeReceived(ImsCallSession.this, mode);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notifies of a change to the multiparty state for this {@code ImsCallSession}.
|
|
*
|
|
* @param session The call session.
|
|
* @param isMultiParty {@code true} if the session became multiparty, {@code false}
|
|
* otherwise.
|
|
*/
|
|
public void callSessionMultipartyStateChanged(IImsCallSession session,
|
|
boolean isMultiParty) {
|
|
|
|
if (mListener != null) {
|
|
mListener.callSessionMultipartyStateChanged(ImsCallSession.this, isMultiParty);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void callSessionSuppServiceReceived(IImsCallSession session,
|
|
ImsSuppServiceNotification suppServiceInfo ) {
|
|
if (mListener != null) {
|
|
mListener.callSessionSuppServiceReceived(ImsCallSession.this, suppServiceInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Received RTT modify request from remote party
|
|
*/
|
|
@Override
|
|
public void callSessionRttModifyRequestReceived(IImsCallSession session,
|
|
ImsCallProfile callProfile) {
|
|
if (mListener != null) {
|
|
mListener.callSessionRttModifyRequestReceived(ImsCallSession.this, callProfile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Received response for RTT modify request
|
|
*/
|
|
@Override
|
|
public void callSessionRttModifyResponseReceived(int status) {
|
|
if (mListener != null) {
|
|
mListener.callSessionRttModifyResponseReceived(status);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* RTT Message received
|
|
*/
|
|
@Override
|
|
public void callSessionRttMessageReceived(String rttMessage) {
|
|
if (mListener != null) {
|
|
mListener.callSessionRttMessageReceived(rttMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Provides a string representation of the {@link ImsCallSession}. Primarily intended for
|
|
* use in log statements.
|
|
*
|
|
* @return String representation of session.
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("[ImsCallSession objId:");
|
|
sb.append(System.identityHashCode(this));
|
|
sb.append(" state:");
|
|
sb.append(State.toString(getState()));
|
|
sb.append(" callId:");
|
|
sb.append(getCallId());
|
|
sb.append("]");
|
|
return sb.toString();
|
|
}
|
|
}
|