diff options
Diffstat (limited to 'telecomm/java/android/telecom/Call.java')
-rw-r--r-- | telecomm/java/android/telecom/Call.java | 842 |
1 files changed, 842 insertions, 0 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java new file mode 100644 index 0000000..1d33b3b --- /dev/null +++ b/telecomm/java/android/telecom/Call.java @@ -0,0 +1,842 @@ +/* + * Copyright (C) 2014 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 android.telecom; + +import android.annotation.SystemApi; +import android.net.Uri; +import android.os.Bundle; +import android.telephony.DisconnectCause; + +import java.lang.String; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Represents an ongoing phone call that the in-call app should present to the user. + * + * {@hide} + */ +@SystemApi +public final class Call { + /** + * The state of a {@code Call} when newly created. + */ + public static final int STATE_NEW = 0; + + /** + * The state of an outgoing {@code Call} when dialing the remote number, but not yet connected. + */ + public static final int STATE_DIALING = 1; + + /** + * The state of an incoming {@code Call} when ringing locally, but not yet connected. + */ + public static final int STATE_RINGING = 2; + + /** + * The state of a {@code Call} when in a holding state. + */ + public static final int STATE_HOLDING = 3; + + /** + * The state of a {@code Call} when actively supporting conversation. + */ + public static final int STATE_ACTIVE = 4; + + /** + * 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_DISCONNECTED = 7; + + /** + * The state of an outgoing {@code Call}, but waiting for user input before proceeding. + */ + public static final int STATE_PRE_DIAL_WAIT = 8; + + /** + * 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_CONNECTING = 9; + + public static class Details { + private final Uri mHandle; + private final int mHandlePresentation; + private final String mCallerDisplayName; + private final int mCallerDisplayNamePresentation; + private final PhoneAccountHandle mAccountHandle; + private final int mCallCapabilities; + private final int mCallProperties; + private final int mDisconnectCauseCode; + private final String mDisconnectCauseMessage; + private final long mConnectTimeMillis; + private final GatewayInfo mGatewayInfo; + private final int mVideoState; + private final StatusHints mStatusHints; + private final Bundle mExtras; + + /** + * @return The handle (e.g., phone number) to which the {@code Call} is currently + * connected. + */ + public Uri getHandle() { + return mHandle; + } + + /** + * @return The presentation requirements for the handle. See + * {@link TelecomManager} for valid values. + */ + public int getHandlePresentation() { + return mHandlePresentation; + } + + /** + * @return The display name for the caller. + */ + public String getCallerDisplayName() { + return mCallerDisplayName; + } + + /** + * @return The presentation requirements for the caller display name. See + * {@link TelecomManager} for valid values. + */ + public int getCallerDisplayNamePresentation() { + return mCallerDisplayNamePresentation; + } + + /** + * @return The {@code PhoneAccountHandle} whereby the {@code Call} is currently being + * routed. + */ + public PhoneAccountHandle getAccountHandle() { + return mAccountHandle; + } + + /** + * @return A bitmask of the capabilities of the {@code Call}, as defined in + * {@link PhoneCapabilities}. + */ + public int getCallCapabilities() { + return mCallCapabilities; + } + + /** + * @return A bitmask of the properties of the {@code Call}, as defined in + * {@link CallProperties}. + */ + public int getCallProperties() { + return mCallProperties; + } + + /** + * @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed + * as a code chosen from among those declared in {@link DisconnectCause}. + */ + public int getDisconnectCauseCode() { + return mDisconnectCauseCode; + } + + /** + * @return For a {@link #STATE_DISCONNECTED} {@code Call}, an optional reason for + * disconnection expressed as a free text message. + */ + public String getDisconnectCauseMessage() { + return mDisconnectCauseMessage; + } + + /** + * @return The time the {@code Call} has been connected. This information is updated + * periodically, but user interfaces should not rely on this to display any "call time + * clock". + */ + public long getConnectTimeMillis() { + return mConnectTimeMillis; + } + + /** + * @return Information about any calling gateway the {@code Call} may be using. + */ + public GatewayInfo getGatewayInfo() { + return mGatewayInfo; + } + + /** + * @return The video state of the {@code Call}. + */ + public int getVideoState() { + return mVideoState; + } + + /** + * @return The current {@link android.telecom.StatusHints}, or {@code null} if none + * have been set. + */ + public StatusHints getStatusHints() { + return mStatusHints; + } + + /** + * @return A bundle extras to pass with the call + */ + public Bundle getExtras() { + return mExtras; + } + + @Override + public boolean equals(Object o) { + if (o instanceof Details) { + Details d = (Details) o; + return + Objects.equals(mHandle, d.mHandle) && + Objects.equals(mHandlePresentation, d.mHandlePresentation) && + Objects.equals(mCallerDisplayName, d.mCallerDisplayName) && + Objects.equals(mCallerDisplayNamePresentation, + d.mCallerDisplayNamePresentation) && + Objects.equals(mAccountHandle, d.mAccountHandle) && + Objects.equals(mCallCapabilities, d.mCallCapabilities) && + Objects.equals(mCallProperties, d.mCallProperties) && + Objects.equals(mDisconnectCauseCode, d.mDisconnectCauseCode) && + Objects.equals(mDisconnectCauseMessage, d.mDisconnectCauseMessage) && + Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) && + Objects.equals(mGatewayInfo, d.mGatewayInfo) && + Objects.equals(mVideoState, d.mVideoState) && + Objects.equals(mStatusHints, d.mStatusHints) && + Objects.equals(mExtras, d.mExtras); + } + return false; + } + + @Override + public int hashCode() { + return + Objects.hashCode(mHandle) + + Objects.hashCode(mHandlePresentation) + + Objects.hashCode(mCallerDisplayName) + + Objects.hashCode(mCallerDisplayNamePresentation) + + Objects.hashCode(mAccountHandle) + + Objects.hashCode(mCallCapabilities) + + Objects.hashCode(mCallProperties) + + Objects.hashCode(mDisconnectCauseCode) + + Objects.hashCode(mDisconnectCauseMessage) + + Objects.hashCode(mConnectTimeMillis) + + Objects.hashCode(mGatewayInfo) + + Objects.hashCode(mVideoState) + + Objects.hashCode(mStatusHints) + + Objects.hashCode(mExtras); + } + + /** {@hide} */ + public Details( + Uri handle, + int handlePresentation, + String callerDisplayName, + int callerDisplayNamePresentation, + PhoneAccountHandle accountHandle, + int capabilities, + int properties, + int disconnectCauseCode, + String disconnectCauseMessage, + long connectTimeMillis, + GatewayInfo gatewayInfo, + int videoState, + StatusHints statusHints, + Bundle extras) { + mHandle = handle; + mHandlePresentation = handlePresentation; + mCallerDisplayName = callerDisplayName; + mCallerDisplayNamePresentation = callerDisplayNamePresentation; + mAccountHandle = accountHandle; + mCallCapabilities = capabilities; + mCallProperties = properties; + mDisconnectCauseCode = disconnectCauseCode; + mDisconnectCauseMessage = disconnectCauseMessage; + mConnectTimeMillis = connectTimeMillis; + mGatewayInfo = gatewayInfo; + mVideoState = videoState; + mStatusHints = statusHints; + mExtras = extras; + } + } + + public static abstract class Listener { + /** + * Invoked when the state of this {@code Call} has changed. See {@link #getState()}. + * + * @param call The {@code Call} invoking this method. + * @param state The new state of the {@code Call}. + */ + public void onStateChanged(Call call, int state) {} + + /** + * Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}. + * + * @param call The {@code Call} invoking this method. + * @param parent The new parent of the {@code Call}. + */ + public void onParentChanged(Call call, Call parent) {} + + /** + * Invoked when the children of this {@code Call} have changed. See {@link #getChildren()}. + * + * @param call The {@code Call} invoking this method. + * @param children The new children of the {@code Call}. + */ + public void onChildrenChanged(Call call, List<Call> children) {} + + /** + * Invoked when the details of this {@code Call} have changed. See {@link #getDetails()}. + * + * @param call The {@code Call} invoking this method. + * @param details A {@code Details} object describing the {@code Call}. + */ + public void onDetailsChanged(Call call, Details details) {} + + /** + * Invoked when the text messages that can be used as responses to the incoming + * {@code Call} are loaded from the relevant database. + * See {@link #getCannedTextResponses()}. + * + * @param call The {@code Call} invoking this method. + * @param cannedTextResponses The text messages useable as responses. + */ + public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {} + + /** + * Invoked when the post-dial sequence in the outgoing {@code Call} has reached a pause + * character. This causes the post-dial signals to stop pending user confirmation. An + * implementation should present this choice to the user and invoke + * {@link #postDialContinue(boolean)} when the user makes the choice. + * + * @param call The {@code Call} invoking this method. + * @param remainingPostDialSequence The post-dial characters that remain to be sent. + */ + public void onPostDialWait(Call call, String remainingPostDialSequence) {} + + /** + * Invoked when the {@code Call.VideoCall} of the {@code Call} has changed. + * + * @param call The {@code Call} invoking this method. + * @param videoCall The {@code Call.VideoCall} associated with the {@code Call}. + * @hide + */ + public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {} + + /** + * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning + * up their UI for the {@code Call} in response to state transitions. Specifically, + * clients should not assume that a {@link #onStateChanged(Call, int)} with a state of + * {@link #STATE_DISCONNECTED} is the final notification the {@code Call} will send. Rather, + * clients should wait for this method to be invoked. + * + * @param call The {@code Call} being destroyed. + */ + public void onCallDestroyed(Call call) {} + + /** + * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be + * conferenced. + * + * @param call The {@code Call} being updated. + * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be + * conferenced. + */ + public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {} + } + + private final Phone mPhone; + private final String mTelecomCallId; + private final InCallAdapter mInCallAdapter; + private final List<String> mChildrenIds = new ArrayList<>(); + private final List<Call> mChildren = new ArrayList<>(); + private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren); + private final List<Listener> mListeners = new CopyOnWriteArrayList<>(); + private final List<Call> mConferenceableCalls = new ArrayList<>(); + private final List<Call> mUnmodifiableConferenceableCalls = + Collections.unmodifiableList(mConferenceableCalls); + + private boolean mChildrenCached; + private String mParentId = null; + private int mState; + private List<String> mCannedTextResponses = null; + private String mRemainingPostDialSequence; + private InCallService.VideoCall mVideoCall; + private Details mDetails; + + /** + * 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. + */ + public String getRemainingPostDialSequence() { + return mRemainingPostDialSequence; + } + + /** + * Instructs this {@link #STATE_RINGING} {@code Call} to answer. + * @param videoState The video state in which to answer the call. + */ + public void answer(int videoState) { + mInCallAdapter.answerCall(mTelecomCallId, videoState); + } + + /** + * 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. + */ + public void reject(boolean rejectWithMessage, String textMessage) { + mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage); + } + + /** + * Instructs this {@code Call} to disconnect. + */ + public void disconnect() { + mInCallAdapter.disconnectCall(mTelecomCallId); + } + + /** + * Instructs this {@code Call} to go on hold. + */ + public void hold() { + mInCallAdapter.holdCall(mTelecomCallId); + } + + /** + * Instructs this {@link #STATE_HOLDING} call to release from hold. + */ + public void unhold() { + mInCallAdapter.unholdCall(mTelecomCallId); + } + + /** + * 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 '#'}. + */ + public void playDtmfTone(char digit) { + mInCallAdapter.playDtmfTone(mTelecomCallId, digit); + } + + /** + * 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. + */ + public void stopDtmfTone() { + mInCallAdapter.stopDtmfTone(mTelecomCallId); + } + + /** + * 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. + */ + public void postDialContinue(boolean proceed) { + mInCallAdapter.postDialContinue(mTelecomCallId, proceed); + } + + /** + * Notifies this {@code Call} that an account has been selected and to proceed with placing + * an outgoing call. + */ + public void phoneAccountSelected(PhoneAccountHandle accountHandle) { + mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle); + + } + + /** + * Instructs this {@code Call} to enter a conference. + * + * @param callToConferenceWith The other call with which to conference. + */ + public void conference(Call callToConferenceWith) { + if (callToConferenceWith != null) { + mInCallAdapter.conference(mTelecomCallId, callToConferenceWith.mTelecomCallId); + } + } + + /** + * Instructs this {@code Call} to split from any conference call with which it may be + * connected. + */ + public void splitFromConference() { + mInCallAdapter.splitFromConference(mTelecomCallId); + } + + /** + * Merges the calls within this conference. See {@link PhoneCapabilities#MERGE_CONFERENCE}. + */ + public void mergeConference() { + mInCallAdapter.mergeConference(mTelecomCallId); + } + + /** + * Swaps the calls within this conference. See {@link PhoneCapabilities#SWAP_CONFERENCE}. + */ + public void swapConference() { + mInCallAdapter.swapConference(mTelecomCallId); + } + + /** + * 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. + */ + public Call getParent() { + if (mParentId != null) { + return mPhone.internalGetCallByTelecomId(mParentId); + } + return null; + } + + /** + * 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. + */ + public List<Call> getChildren() { + 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; + } + + /** + * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference. + * + * @return The list of conferenceable {@code Call}s. + */ + public List<Call> getConferenceableCalls() { + return mUnmodifiableConferenceableCalls; + } + + /** + * Obtains the state of this {@code Call}. + * + * @return A state value, chosen from the {@code STATE_*} constants. + */ + public int getState() { + return mState; + } + + /** + * 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. + */ + public List<String> getCannedTextResponses() { + return mCannedTextResponses; + } + + /** + * Obtains an object that can be used to display video from this {@code Call}. + * + * @return An {@code Call.VideoCall}. + * @hide + */ + public InCallService.VideoCall getVideoCall() { + return mVideoCall; + } + + /** + * 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}. + */ + public Details getDetails() { + return mDetails; + } + + /** + * Adds a listener to this {@code Call}. + * + * @param listener A {@code Listener}. + */ + public void addListener(Listener listener) { + mListeners.add(listener); + } + + /** + * Removes a listener from this {@code Call}. + * + * @param listener A {@code Listener}. + */ + public void removeListener(Listener listener) { + if (listener != null) { + mListeners.remove(listener); + } + } + + /** {@hide} */ + Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) { + mPhone = phone; + mTelecomCallId = telecomCallId; + mInCallAdapter = inCallAdapter; + mState = STATE_NEW; + } + + /** {@hide} */ + final String internalGetCallId() { + return mTelecomCallId; + } + + /** {@hide} */ + final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) { + // 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.getDisconnectCauseCode(), + parcelableCall.getDisconnectCauseMsg(), + 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); + } + } + + /** {@hide} */ + final void internalSetPostDialWait(String remaining) { + mRemainingPostDialSequence = remaining; + firePostDialWait(mRemainingPostDialSequence); + } + + /** {@hide} */ + final void internalSetDisconnected() { + if (mState != Call.STATE_DISCONNECTED) { + mState = Call.STATE_DISCONNECTED; + fireStateChanged(mState); + fireCallDestroyed(); + mPhone.internalRemoveCall(this); + } + } + + private void fireStateChanged(int newState) { + for (Listener listener : mListeners) { + listener.onStateChanged(this, newState); + } + } + + private void fireParentChanged(Call newParent) { + for (Listener listener : mListeners) { + listener.onParentChanged(this, newParent); + } + } + + private void fireChildrenChanged(List<Call> children) { + for (Listener listener : mListeners) { + listener.onChildrenChanged(this, children); + } + } + + private void fireDetailsChanged(Details details) { + for (Listener listener : mListeners) { + listener.onDetailsChanged(this, details); + } + } + + private void fireCannedTextResponsesLoaded(List<String> cannedTextResponses) { + for (Listener listener : mListeners) { + listener.onCannedTextResponsesLoaded(this, cannedTextResponses); + } + } + + private void fireVideoCallChanged(InCallService.VideoCall videoCall) { + for (Listener listener : mListeners) { + listener.onVideoCallChanged(this, videoCall); + } + } + + private void firePostDialWait(String remainingPostDialSequence) { + for (Listener listener : mListeners) { + listener.onPostDialWait(this, remainingPostDialSequence); + } + } + + private void fireCallDestroyed() { + for (Listener listener : mListeners) { + listener.onCallDestroyed(this); + } + } + + private void fireConferenceableCallsChanged() { + for (Listener listener : mListeners) { + listener.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls); + } + } + + private int stateFromParcelableCallState(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; + default: + Log.wtf(this, "Unrecognized CallState %s", parcelableCallState); + return STATE_NEW; + } + } +} |