FileDocCategorySizeDatePackage
Call.javaAPI DocAndroid 5.1 API36792Thu Mar 12 22:22:42 GMT 2015android.telecom

Call

public final class Call extends Object
Represents an ongoing phone call that the in-call app should present to the user. {@hide}

Fields Summary
public static final int
STATE_NEW
The state of a {@code Call} when newly created.
public static final int
STATE_DIALING
The state of an outgoing {@code Call} when dialing the remote number, but not yet connected.
public static final int
STATE_RINGING
The state of an incoming {@code Call} when ringing locally, but not yet connected.
public static final int
STATE_HOLDING
The state of a {@code Call} when in a holding state.
public static final int
STATE_ACTIVE
The state of a {@code Call} when actively supporting conversation.
public static final int
STATE_DISCONNECTED
The state of a {@code Call} when no further voice or other communication is being transmitted, the remote side has been or will inevitably be informed that the {@code Call} is no longer active, and the local data transport has or inevitably will release resources associated with this {@code Call}.
public static final int
STATE_PRE_DIAL_WAIT
The state of an outgoing {@code Call}, but waiting for user input before proceeding.
public static final int
STATE_CONNECTING
The initial state of an outgoing {@code Call}. Common transitions are to {@link #STATE_DIALING} state for a successful call or {@link #STATE_DISCONNECTED} if it failed.
public static final int
STATE_DISCONNECTING
The state of a {@code Call} when the user has initiated a disconnection of the call, but the call has not yet been disconnected by the underlying {@code ConnectionService}. The next state of the call is (potentially) {@link #STATE_DISCONNECTED}.
public static final String
AVAILABLE_PHONE_ACCOUNTS
The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call extras. Used to pass the phone accounts to display on the front end to the user in order to select phone accounts to (for example) place a call.
private final Phone
mPhone
private final String
mTelecomCallId
private final InCallAdapter
mInCallAdapter
private final List
mChildrenIds
private final List
mChildren
private final List
mUnmodifiableChildren
private final List
mListeners
private final List
mConferenceableCalls
private final List
mUnmodifiableConferenceableCalls
private boolean
mChildrenCached
private String
mParentId
private int
mState
private List
mCannedTextResponses
private String
mRemainingPostDialSequence
private InCallService.VideoCall
mVideoCall
private Details
mDetails
Constructors Summary
Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter)
{@hide}

        mPhone = phone;
        mTelecomCallId = telecomCallId;
        mInCallAdapter = inCallAdapter;
        mState = STATE_NEW;
    
Methods Summary
public voidaddListener(android.telecom.Call$Listener listener)
Adds a listener to this {@code Call}.

param
listener A {@code Listener}.

        mListeners.add(listener);
    
public voidanswer(int videoState)
Instructs this {@link #STATE_RINGING} {@code Call} to answer.

param
videoState The video state in which to answer the call.

        mInCallAdapter.answerCall(mTelecomCallId, videoState);
    
public voidconference(android.telecom.Call callToConferenceWith)
Instructs this {@code Call} to enter a conference.

param
callToConferenceWith The other call with which to conference.

        if (callToConferenceWith != null) {
            mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId);
        }
    
public voiddisconnect()
Instructs this {@code Call} to disconnect.

        mInCallAdapter.disconnectCall(mTelecomCallId);
    
private voidfireCallDestroyed()

        for (Listener listener : mListeners) {
            listener.onCallDestroyed(this);
        }
    
private voidfireCannedTextResponsesLoaded(java.util.List cannedTextResponses)

        for (Listener listener : mListeners) {
            listener.onCannedTextResponsesLoaded(this, cannedTextResponses);
        }
    
private voidfireChildrenChanged(java.util.List children)

        for (Listener listener : mListeners) {
            listener.onChildrenChanged(this, children);
        }
    
private voidfireConferenceableCallsChanged()

        for (Listener listener : mListeners) {
            listener.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
        }
    
private voidfireDetailsChanged(android.telecom.Call$Details details)

        for (Listener listener : mListeners) {
            listener.onDetailsChanged(this, details);
        }
    
private voidfireParentChanged(android.telecom.Call newParent)

        for (Listener listener : mListeners) {
            listener.onParentChanged(this, newParent);
        }
    
private voidfirePostDialWait(java.lang.String remainingPostDialSequence)

        for (Listener listener : mListeners) {
            listener.onPostDialWait(this, remainingPostDialSequence);
        }
    
private voidfireStateChanged(int newState)

        for (Listener listener : mListeners) {
            listener.onStateChanged(this, newState);
        }
    
private voidfireVideoCallChanged(InCallService.VideoCall videoCall)

        for (Listener listener : mListeners) {
            listener.onVideoCallChanged(this, videoCall);
        }
    
public java.util.ListgetCannedTextResponses()
Obtains a list of canned, pre-configured message responses to present to the user as ways of rejecting this {@code Call} using via a text message.

see
#reject(boolean, String)
return
A list of canned text message responses.

        return mCannedTextResponses;
    
public java.util.ListgetChildren()
Obtains the children of this conference {@code Call}, if any.

return
The children of this {@code Call} if this {@code Call} is a conference, or an empty {@code List} otherwise.

        if (!mChildrenCached) {
            mChildrenCached = true;
            mChildren.clear();

            for(String id : mChildrenIds) {
                Call call = mPhone.internalGetCallByTelecomId(id);
                if (call == null) {
                    // At least one child was still not found, so do not save true for "cached"
                    mChildrenCached = false;
                } else {
                    mChildren.add(call);
                }
            }
        }

        return mUnmodifiableChildren;
    
public java.util.ListgetConferenceableCalls()
Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.

return
The list of conferenceable {@code Call}s.

        return mUnmodifiableConferenceableCalls;
    
public android.telecom.Call$DetailsgetDetails()
Obtains an object containing call details.

return
A {@link Details} object. Depending on the state of the {@code Call}, the result may be {@code null}.

        return mDetails;
    
public android.telecom.CallgetParent()
Obtains the parent of this {@code Call} in a conference, if any.

return
The parent {@code Call}, or {@code null} if this {@code Call} is not a child of any conference {@code Call}s.

        if (mParentId != null) {
            return mPhone.internalGetCallByTelecomId(mParentId);
        }
        return null;
    
public java.lang.StringgetRemainingPostDialSequence()
Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.

return
The remaining post-dial sequence, or {@code null} if there is no post-dial sequence remaining or this {@code Call} is not in a post-dial state.


                                                
       
        return mRemainingPostDialSequence;
    
public intgetState()
Obtains the state of this {@code Call}.

return
A state value, chosen from the {@code STATE_*} constants.

        return mState;
    
public InCallService.VideoCallgetVideoCall()
Obtains an object that can be used to display video from this {@code Call}.

return
An {@code Call.VideoCall}.
hide

        return mVideoCall;
    
public voidhold()
Instructs this {@code Call} to go on hold.

        mInCallAdapter.holdCall(mTelecomCallId);
    
final java.lang.StringinternalGetCallId()
{@hide}

        return mTelecomCallId;
    
final voidinternalSetDisconnected()
{@hide}

        if (mState != Call.STATE_DISCONNECTED) {
            mState = Call.STATE_DISCONNECTED;
            fireStateChanged(mState);
            fireCallDestroyed();
            mPhone.internalRemoveCall(this);
        }
    
final voidinternalSetPostDialWait(java.lang.String remaining)
{@hide}

        mRemainingPostDialSequence = remaining;
        firePostDialWait(mRemainingPostDialSequence);
    
final voidinternalUpdate(ParcelableCall parcelableCall, java.util.Map callIdMap)
{@hide}

        // First, we update the internal state as far as possible before firing any updates.
        Details details = new Details(
                parcelableCall.getHandle(),
                parcelableCall.getHandlePresentation(),
                parcelableCall.getCallerDisplayName(),
                parcelableCall.getCallerDisplayNamePresentation(),
                parcelableCall.getAccountHandle(),
                parcelableCall.getCapabilities(),
                parcelableCall.getProperties(),
                parcelableCall.getDisconnectCause(),
                parcelableCall.getConnectTimeMillis(),
                parcelableCall.getGatewayInfo(),
                parcelableCall.getVideoState(),
                parcelableCall.getStatusHints(),
                parcelableCall.getExtras());
        boolean detailsChanged = !Objects.equals(mDetails, details);
        if (detailsChanged) {
            mDetails = details;
        }

        boolean cannedTextResponsesChanged = false;
        if (mCannedTextResponses == null && parcelableCall.getCannedSmsResponses() != null
                && !parcelableCall.getCannedSmsResponses().isEmpty()) {
            mCannedTextResponses =
                    Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
        }

        boolean videoCallChanged = !Objects.equals(mVideoCall, parcelableCall.getVideoCall());
        if (videoCallChanged) {
            mVideoCall = parcelableCall.getVideoCall();
        }

        int state = stateFromParcelableCallState(parcelableCall.getState());
        boolean stateChanged = mState != state;
        if (stateChanged) {
            mState = state;
        }

        String parentId = parcelableCall.getParentCallId();
        boolean parentChanged = !Objects.equals(mParentId, parentId);
        if (parentChanged) {
            mParentId = parentId;
        }

        List<String> childCallIds = parcelableCall.getChildCallIds();
        boolean childrenChanged = !Objects.equals(childCallIds, mChildrenIds);
        if (childrenChanged) {
            mChildrenIds.clear();
            mChildrenIds.addAll(parcelableCall.getChildCallIds());
            mChildrenCached = false;
        }

        List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
        List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
        for (String otherId : conferenceableCallIds) {
            if (callIdMap.containsKey(otherId)) {
                conferenceableCalls.add(callIdMap.get(otherId));
            }
        }

        if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
            mConferenceableCalls.clear();
            mConferenceableCalls.addAll(conferenceableCalls);
            fireConferenceableCallsChanged();
        }

        // Now we fire updates, ensuring that any client who listens to any of these notifications
        // gets the most up-to-date state.

        if (stateChanged) {
            fireStateChanged(mState);
        }
        if (detailsChanged) {
            fireDetailsChanged(mDetails);
        }
        if (cannedTextResponsesChanged) {
            fireCannedTextResponsesLoaded(mCannedTextResponses);
        }
        if (videoCallChanged) {
            fireVideoCallChanged(mVideoCall);
        }
        if (parentChanged) {
            fireParentChanged(getParent());
        }
        if (childrenChanged) {
            fireChildrenChanged(getChildren());
        }

        // If we have transitioned to DISCONNECTED, that means we need to notify clients and
        // remove ourselves from the Phone. Note that we do this after completing all state updates
        // so a client can cleanly transition all their UI to the state appropriate for a
        // DISCONNECTED Call while still relying on the existence of that Call in the Phone's list.
        if (mState == STATE_DISCONNECTED) {
            fireCallDestroyed();
            mPhone.internalRemoveCall(this);
        }
    
public voidmergeConference()
Merges the calls within this conference. See {@link Details#CAPABILITY_MERGE_CONFERENCE}.

        mInCallAdapter.mergeConference(mTelecomCallId);
    
public voidphoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault)
Notifies this {@code Call} that an account has been selected and to proceed with placing an outgoing call. Optionally sets this account as the default account.

        mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault);

    
public voidplayDtmfTone(char digit)
Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone. Any other currently playing DTMF tone in the specified call is immediately stopped.

param
digit A character representing the DTMF digit for which to play the tone. This value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.

        mInCallAdapter.playDtmfTone(mTelecomCallId, digit);
    
public voidpostDialContinue(boolean proceed)
Instructs this {@code Call} to continue playing a post-dial DTMF string. A post-dial DTMF string is a string of digits entered after a phone number, when dialed, that are immediately sent as DTMF tones to the recipient as soon as the connection is made. If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, this {@code Call} will temporarily pause playing the tones for a pre-defined period of time. If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this {@code Call} will pause playing the tones and notify listeners via {@link Listener#onPostDialWait(Call, String)}. At this point, the in-call app should display to the user an indication of this state and an affordance to continue the postdial sequence. When the user decides to continue the postdial sequence, the in-call app should invoke the {@link #postDialContinue(boolean)} method.

param
proceed Whether or not to continue with the post-dial sequence.

        mInCallAdapter.postDialContinue(mTelecomCallId, proceed);
    
public voidreject(boolean rejectWithMessage, java.lang.String textMessage)
Instructs this {@link #STATE_RINGING} {@code Call} to reject.

param
rejectWithMessage Whether to reject with a text message.
param
textMessage An optional text message with which to respond.

        mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
    
public voidremoveListener(android.telecom.Call$Listener listener)
Removes a listener from this {@code Call}.

param
listener A {@code Listener}.

        if (listener != null) {
            mListeners.remove(listener);
        }
    
public voidsplitFromConference()
Instructs this {@code Call} to split from any conference call with which it may be connected.

        mInCallAdapter.splitFromConference(mTelecomCallId);
    
private intstateFromParcelableCallState(int parcelableCallState)

        switch (parcelableCallState) {
            case CallState.NEW:
                return STATE_NEW;
            case CallState.CONNECTING:
                return STATE_CONNECTING;
            case CallState.PRE_DIAL_WAIT:
                return STATE_PRE_DIAL_WAIT;
            case CallState.DIALING:
                return STATE_DIALING;
            case CallState.RINGING:
                return STATE_RINGING;
            case CallState.ACTIVE:
                return STATE_ACTIVE;
            case CallState.ON_HOLD:
                return STATE_HOLDING;
            case CallState.DISCONNECTED:
                return STATE_DISCONNECTED;
            case CallState.ABORTED:
                return STATE_DISCONNECTED;
            case CallState.DISCONNECTING:
                return STATE_DISCONNECTING;
            default:
                Log.wtf(this, "Unrecognized CallState %s", parcelableCallState);
                return STATE_NEW;
        }
    
public voidstopDtmfTone()
Instructs this {@code Call} to stop any dual-tone multi-frequency signaling (DTMF) tone currently playing. DTMF tones are played by calling {@link #playDtmfTone(char)}. If no DTMF tone is currently playing, this method will do nothing.

        mInCallAdapter.stopDtmfTone(mTelecomCallId);
    
public voidswapConference()
Swaps the calls within this conference. See {@link Details#CAPABILITY_SWAP_CONFERENCE}.

        mInCallAdapter.swapConference(mTelecomCallId);
    
public voidunhold()
Instructs this {@link #STATE_HOLDING} call to release from hold.

        mInCallAdapter.unholdCall(mTelecomCallId);