diff options
Diffstat (limited to 'telecomm/java')
23 files changed, 612 insertions, 497 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 33a7fe1..2a30384 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Bundle; @@ -65,9 +66,18 @@ public final class Call { public static final int STATE_DISCONNECTED = 7; /** - * The state of an outgoing {@code Call}, but waiting for user input before proceeding. + * The state of an outgoing {@code Call} when waiting on user to select a + * {@link PhoneAccount} through which to place the call. */ - public static final int STATE_PRE_DIAL_WAIT = 8; + public static final int STATE_SELECT_PHONE_ACCOUNT = 8; + + /** + * @hide + * @deprecated use STATE_SELECT_PHONE_ACCOUNT. + */ + @Deprecated + @SystemApi + public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT; /** * The initial state of an outgoing {@code Call}. @@ -212,7 +222,6 @@ public final class Call { /** * For video calls, indicates whether the outgoing video for the call can be paused using * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState. - * @hide */ public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000; @@ -233,7 +242,6 @@ public final class Call { private final int mVideoState; private final StatusHints mStatusHints; private final Bundle mExtras; - private final int mCallSubstate; /** * Whether the supplied capabilities supports the specified capability. @@ -430,14 +438,6 @@ public final class Call { return mExtras; } - /** - * @return The substate of the {@code Call}. - * @hide - */ - public int getCallSubstate() { - return mCallSubstate; - } - @Override public boolean equals(Object o) { if (o instanceof Details) { @@ -456,8 +456,7 @@ public final class Call { Objects.equals(mGatewayInfo, d.mGatewayInfo) && Objects.equals(mVideoState, d.mVideoState) && Objects.equals(mStatusHints, d.mStatusHints) && - Objects.equals(mExtras, d.mExtras) && - Objects.equals(mCallSubstate, d.mCallSubstate); + Objects.equals(mExtras, d.mExtras); } return false; } @@ -477,8 +476,7 @@ public final class Call { Objects.hashCode(mGatewayInfo) + Objects.hashCode(mVideoState) + Objects.hashCode(mStatusHints) + - Objects.hashCode(mExtras) + - Objects.hashCode(mCallSubstate); + Objects.hashCode(mExtras); } /** {@hide} */ @@ -495,8 +493,7 @@ public final class Call { GatewayInfo gatewayInfo, int videoState, StatusHints statusHints, - Bundle extras, - int callSubstate) { + Bundle extras) { mHandle = handle; mHandlePresentation = handlePresentation; mCallerDisplayName = callerDisplayName; @@ -510,11 +507,10 @@ public final class Call { mVideoState = videoState; mStatusHints = statusHints; mExtras = extras; - mCallSubstate = callSubstate; } } - public static abstract class Listener { + public static abstract class Callback { /** * Invoked when the state of this {@code Call} has changed. See {@link #getState()}. * @@ -598,13 +594,21 @@ public final class Call { public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {} } + /** + * @deprecated Use {@code Call.Callback} instead. + * @hide + */ + @Deprecated + @SystemApi + public static abstract class Listener extends Callback { } + 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<Callback> mCallbacks = new CopyOnWriteArrayList<>(); private final List<Call> mConferenceableCalls = new ArrayList<>(); private final List<Call> mUnmodifiableConferenceableCalls = Collections.unmodifiableList(mConferenceableCalls); @@ -699,8 +703,8 @@ public final class Call { * {@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 + * {@code Call} will pause playing the tones and notify callbacks via + * {@link Callback#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. @@ -841,25 +845,52 @@ public final class Call { } /** + * Registers a callback to this {@code Call}. + * + * @param callback A {@code Callback}. + */ + public void registerCallback(Callback callback) { + mCallbacks.add(callback); + } + + /** + * Unregisters a callback from this {@code Call}. + * + * @param callback A {@code Callback}. + */ + public void unregisterCallback(Callback callback) { + if (callback != null) { + mCallbacks.remove(callback); + } + } + + /** * Adds a listener to this {@code Call}. * * @param listener A {@code Listener}. + * @deprecated Use {@link #registerCallback} instead. + * @hide */ + @Deprecated + @SystemApi public void addListener(Listener listener) { - mListeners.add(listener); + registerCallback(listener); } /** * Removes a listener from this {@code Call}. * * @param listener A {@code Listener}. + * @deprecated Use {@link #unregisterCallback} instead. + * @hide */ + @Deprecated + @SystemApi public void removeListener(Listener listener) { - if (listener != null) { - mListeners.remove(listener); - } + unregisterCallback(listener); } + /** {@hide} */ Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) { mPhone = phone; @@ -889,8 +920,7 @@ public final class Call { parcelableCall.getGatewayInfo(), parcelableCall.getVideoState(), parcelableCall.getStatusHints(), - parcelableCall.getExtras(), - parcelableCall.getCallSubstate()); + parcelableCall.getExtras()); boolean detailsChanged = !Objects.equals(mDetails, details); if (detailsChanged) { mDetails = details; @@ -908,7 +938,7 @@ public final class Call { mVideoCall = parcelableCall.getVideoCall(); } - int state = stateFromParcelableCallState(parcelableCall.getState()); + int state = parcelableCall.getState(); boolean stateChanged = mState != state; if (stateChanged) { mState = state; @@ -991,84 +1021,56 @@ public final class Call { } private void fireStateChanged(int newState) { - for (Listener listener : mListeners) { - listener.onStateChanged(this, newState); + for (Callback callback : mCallbacks) { + callback.onStateChanged(this, newState); } } private void fireParentChanged(Call newParent) { - for (Listener listener : mListeners) { - listener.onParentChanged(this, newParent); + for (Callback callback : mCallbacks) { + callback.onParentChanged(this, newParent); } } private void fireChildrenChanged(List<Call> children) { - for (Listener listener : mListeners) { - listener.onChildrenChanged(this, children); + for (Callback callback : mCallbacks) { + callback.onChildrenChanged(this, children); } } private void fireDetailsChanged(Details details) { - for (Listener listener : mListeners) { - listener.onDetailsChanged(this, details); + for (Callback callback : mCallbacks) { + callback.onDetailsChanged(this, details); } } private void fireCannedTextResponsesLoaded(List<String> cannedTextResponses) { - for (Listener listener : mListeners) { - listener.onCannedTextResponsesLoaded(this, cannedTextResponses); + for (Callback callback : mCallbacks) { + callback.onCannedTextResponsesLoaded(this, cannedTextResponses); } } private void fireVideoCallChanged(InCallService.VideoCall videoCall) { - for (Listener listener : mListeners) { - listener.onVideoCallChanged(this, videoCall); + for (Callback callback : mCallbacks) { + callback.onVideoCallChanged(this, videoCall); } } private void firePostDialWait(String remainingPostDialSequence) { - for (Listener listener : mListeners) { - listener.onPostDialWait(this, remainingPostDialSequence); + for (Callback callback : mCallbacks) { + callback.onPostDialWait(this, remainingPostDialSequence); } } private void fireCallDestroyed() { - for (Listener listener : mListeners) { - listener.onCallDestroyed(this); + for (Callback callback : mCallbacks) { + callback.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; - case CallState.DISCONNECTING: - return STATE_DISCONNECTING; - default: - Log.wtf(this, "Unrecognized CallState %s", parcelableCallState); - return STATE_NEW; + for (Callback callback : mCallbacks) { + callback.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls); } } } diff --git a/telecomm/java/android/telecom/CallState.java b/telecomm/java/android/telecom/CallState.java deleted file mode 100644 index 5584226..0000000 --- a/telecomm/java/android/telecom/CallState.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 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; - -/** - * Defines call-state constants of the different states in which a call can exist. Although states - * have the notion of normal transitions, due to the volatile nature of telephony systems, code - * that uses these states should be resilient to unexpected state changes outside of what is - * considered traditional. - */ -public final class CallState { - - private CallState() {} - - /** - * Indicates that a call is new and not connected. This is used as the default state internally - * within Telecom and should not be used between Telecom and call services. Call services are - * not expected to ever interact with NEW calls, but {@link InCallService}s will see calls in - * this state. - */ - public static final int NEW = 0; - - /** - * The initial state of an outgoing {@code Call}. - * Common transitions are to {@link #DIALING} state for a successful call or - * {@link #DISCONNECTED} if it failed. - */ - public static final int CONNECTING = 1; - - /** - * Indicates that the call is about to go into the outgoing and dialing state but is waiting for - * user input before it proceeds. For example, where no default {@link PhoneAccount} is set, - * this is the state where the InCallUI is waiting for the user to select a - * {@link PhoneAccount} to call from. - */ - public static final int PRE_DIAL_WAIT = 2; - - /** - * Indicates that a call is outgoing and in the dialing state. A call transitions to this state - * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this - * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED} - * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user). - */ - public static final int DIALING = 3; - - /** - * Indicates that a call is incoming and the user still has the option of answering, rejecting, - * or doing nothing with the call. This state is usually associated with some type of audible - * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED} - * otherwise. - */ - public static final int RINGING = 4; - - /** - * Indicates that a call is currently connected to another party and a communication channel is - * open between them. The normal transition to this state is by the user answering a - * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party. - */ - public static final int ACTIVE = 5; - - /** - * Indicates that the call is currently on hold. In this state, the call is not terminated - * but no communication is allowed until the call is no longer on hold. The typical transition - * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing - * an action, such as clicking the hold button. - */ - public static final int ON_HOLD = 6; - - /** - * Indicates that a call is currently disconnected. All states can transition to this state - * by the call service giving notice that the connection has been severed. When the user - * explicitly ends a call, it will not transition to this state until the call service confirms - * the disconnection or communication was lost to the call service currently responsible for - * this call (e.g., call service crashes). - */ - public static final int DISCONNECTED = 7; - - /** - * Indicates that the call was attempted (mostly in the context of outgoing, at least at the - * time of writing) but cancelled before it was successfully connected. - */ - public static final int ABORTED = 8; - - /** - * Indicates that the call is in the process of being disconnected and will transition next - * to a {@link #DISCONNECTED} state. - * <p> - * This state is not expected to be communicated from the Telephony layer, but will be reported - * to the InCall UI for calls where disconnection has been initiated by the user but the - * ConnectionService has confirmed the call as disconnected. - */ - public static final int DISCONNECTING = 9; - - public static String toString(int callState) { - switch (callState) { - case NEW: - return "NEW"; - case CONNECTING: - return "CONNECTING"; - case PRE_DIAL_WAIT: - return "PRE_DIAL_WAIT"; - case DIALING: - return "DIALING"; - case RINGING: - return "RINGING"; - case ACTIVE: - return "ACTIVE"; - case ON_HOLD: - return "ON_HOLD"; - case DISCONNECTED: - return "DISCONNECTED"; - case ABORTED: - return "ABORTED"; - case DISCONNECTING: - return "DISCONNECTING"; - default: - return "UNKNOWN"; - } - } -} diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 15a1da1..bab60fe 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -29,7 +29,7 @@ import java.util.concurrent.CopyOnWriteArraySet; /** * Represents a conference call which can contain any number of {@link Connection} objects. */ -public abstract class Conference implements IConferenceable { +public abstract class Conference implements Conferenceable { /** * Used to indicate that the conference connection time is not specified. If not specified, diff --git a/telecomm/java/android/telecom/Conferenceable.java b/telecomm/java/android/telecom/Conferenceable.java new file mode 100644 index 0000000..5c4cbc5 --- /dev/null +++ b/telecomm/java/android/telecom/Conferenceable.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 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; + +/** + * Interface used to identify entities with which another entity can participate in a conference + * call with. The {@link ConnectionService} implementation will only recognize + * {@link Conferenceable}s which are {@link Connection}s or {@link Conference}s. + */ +public interface Conferenceable { + +} diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index d4274b9..e79584f 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -44,7 +44,7 @@ import java.util.concurrent.ConcurrentHashMap; * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no * longer used and associated resources may be recovered. */ -public abstract class Connection implements IConferenceable { +public abstract class Connection implements Conferenceable { public static final int STATE_INITIALIZING = 0; @@ -180,7 +180,7 @@ public abstract class Connection implements IConferenceable { /** * Speed up audio setup for MT call. * @hide - */ + */ public static final int CAPABILITY_SPEED_UP_MT_AUDIO = 0x00040000; /** @@ -200,48 +200,6 @@ public abstract class Connection implements IConferenceable { // Next CAPABILITY value: 0x00200000 //********************************************************************************************** - /** - * Call substate bitmask values - */ - - /* Default case */ - /** - * @hide - */ - public static final int SUBSTATE_NONE = 0; - - /* Indicates that the call is connected but audio attribute is suspended */ - /** - * @hide - */ - public static final int SUBSTATE_AUDIO_CONNECTED_SUSPENDED = 0x1; - - /* Indicates that the call is connected but video attribute is suspended */ - /** - * @hide - */ - public static final int SUBSTATE_VIDEO_CONNECTED_SUSPENDED = 0x2; - - /* Indicates that the call is established but media retry is needed */ - /** - * @hide - */ - public static final int SUBSTATE_AVP_RETRY = 0x4; - - /* Indicates that the call is multitasking */ - /** - * @hide - */ - public static final int SUBSTATE_MEDIA_PAUSED = 0x8; - - /* Mask containing all the call substate bits set */ - /** - * @hide - */ - public static final int SUBSTATE_ALL = SUBSTATE_AUDIO_CONNECTED_SUSPENDED | - SUBSTATE_VIDEO_CONNECTED_SUSPENDED | SUBSTATE_AVP_RETRY | - SUBSTATE_MEDIA_PAUSED; - // Flag controlling whether PII is emitted into the logs private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG); @@ -374,13 +332,12 @@ public abstract class Connection implements IConferenceable { public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} public void onConferenceablesChanged( - Connection c, List<IConferenceable> conferenceables) {} + Connection c, List<Conferenceable> conferenceables) {} public void onConferenceChanged(Connection c, Conference conference) {} /** @hide */ public void onConferenceParticipantsChanged(Connection c, List<ConferenceParticipant> participants) {} public void onConferenceStarted() {} - public void onCallSubstateChanged(Connection c, int substate) {} } public static abstract class VideoProvider { @@ -788,8 +745,8 @@ public abstract class Connection implements IConferenceable { */ private final Set<Listener> mListeners = Collections.newSetFromMap( new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); - private final List<IConferenceable> mConferenceables = new ArrayList<>(); - private final List<IConferenceable> mUnmodifiableConferenceables = + private final List<Conferenceable> mConferenceables = new ArrayList<>(); + private final List<Conferenceable> mUnmodifiableConferenceables = Collections.unmodifiableList(mConferenceables); private int mState = STATE_NEW; @@ -807,7 +764,6 @@ public abstract class Connection implements IConferenceable { private DisconnectCause mDisconnectCause; private Conference mConference; private ConnectionService mConnectionService; - private int mCallSubstate; /** * Create a new Connection. @@ -866,21 +822,6 @@ public abstract class Connection implements IConferenceable { } /** - * Returns the call substate of the call. - * Valid values: {@link Connection#SUBSTATE_NONE}, - * {@link Connection#SUBSTATE_AUDIO_CONNECTED_SUSPENDED}, - * {@link Connection#SUBSTATE_VIDEO_CONNECTED_SUSPENDED}, - * {@link Connection#SUBSTATE_AVP_RETRY}, - * {@link Connection#SUBSTATE_MEDIA_PAUSED}. - * - * @param callSubstate The new call substate. - * @hide - */ - public final int getCallSubstate() { - return mCallSubstate; - } - - /** * @return The audio state of the connection, describing how its audio is currently * being routed by the system. This is {@code null} if this Connection * does not directly know about its audio state. @@ -1054,25 +995,6 @@ public abstract class Connection implements IConferenceable { } /** - * Set the call substate for the connection. - * Valid values: {@link Connection#SUBSTATE_NONE}, - * {@link Connection#SUBSTATE_AUDIO_CONNECTED_SUSPENDED}, - * {@link Connection#SUBSTATE_VIDEO_CONNECTED_SUSPENDED}, - * {@link Connection#SUBSTATE_AVP_RETRY}, - * {@link Connection#SUBSTATE_MEDIA_PAUSED}. - * - * @param callSubstate The new call substate. - * @hide - */ - public final void setCallSubstate(int callSubstate) { - Log.d(this, "setCallSubstate %d", callSubstate); - mCallSubstate = callSubstate; - for (Listener l : mListeners) { - l.onCallSubstateChanged(this, mCallSubstate); - } - } - - /** * Sets state to active (e.g., an ongoing connection where two or more parties can actively * communicate). */ @@ -1175,14 +1097,11 @@ public abstract class Connection implements IConferenceable { /** * Informs listeners that this {@code Connection} has processed a character in the post-dial * started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence; - * (b) it has encountered a "wait" character; and (c) it wishes to signal Telecom to play - * the corresponding DTMF tone locally. + * and (b) it wishes to signal Telecom to play the corresponding DTMF tone locally. * * @param nextChar The DTMF character that was just processed by the {@code Connection}. - * - * @hide */ - public final void setNextPostDialWaitChar(char nextChar) { + public final void setNextPostDialChar(char nextChar) { checkImmutable(); for (Listener l : mListeners) { l.onPostDialChar(this, nextChar); @@ -1280,9 +1199,9 @@ public abstract class Connection implements IConferenceable { * * @param conferenceables The conferenceables. */ - public final void setConferenceables(List<IConferenceable> conferenceables) { + public final void setConferenceables(List<Conferenceable> conferenceables) { clearConferenceableList(); - for (IConferenceable c : conferenceables) { + for (Conferenceable c : conferenceables) { // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a // small amount of items here. if (!mConferenceables.contains(c)) { @@ -1302,7 +1221,7 @@ public abstract class Connection implements IConferenceable { /** * Returns the connections or conferences with which this connection can be conferenced. */ - public final List<IConferenceable> getConferenceables() { + public final List<Conferenceable> getConferenceables() { return mUnmodifiableConferenceables; } @@ -1567,7 +1486,7 @@ public abstract class Connection implements IConferenceable { } private final void clearConferenceableList() { - for (IConferenceable c : mConferenceables) { + for (Conferenceable c : mConferenceables) { if (c instanceof Connection) { Connection connection = (Connection) c; connection.removeConnectionListener(mConnectionDeathListener); diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index e36d32b..9812815 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -539,7 +539,7 @@ public abstract class ConnectionService extends Service { @Override public void onConferenceablesChanged( - Connection connection, List<IConferenceable> conferenceables) { + Connection connection, List<Conferenceable> conferenceables) { mAdapter.setConferenceableConnections( mIdByConnection.get(connection), createIdList(conferenceables)); @@ -556,13 +556,6 @@ public abstract class ConnectionService extends Service { mAdapter.setIsConferenced(id, conferenceId); } } - - @Override - public void onCallSubstateChanged(Connection c, int callSubstate) { - String id = mIdByConnection.get(c); - Log.d(this, "Adapter set call substate %d", callSubstate); - mAdapter.setCallSubstate(id, callSubstate); - } }; /** {@inheritDoc} */ @@ -632,8 +625,7 @@ public abstract class ConnectionService extends Service { connection.getAudioModeIsVoip(), connection.getStatusHints(), connection.getDisconnectCause(), - createIdList(connection.getConferenceables()), - connection.getCallSubstate())); + createIdList(connection.getConferenceables()))); } private void abort(String callId) { @@ -956,7 +948,7 @@ public abstract class ConnectionService extends Service { connection.getAudioModeIsVoip(), connection.getStatusHints(), connection.getDisconnectCause(), - emptyList, connection.getCallSubstate()); + emptyList); mAdapter.addExistingConnection(id, parcelableConnection); } } @@ -1176,14 +1168,14 @@ public abstract class ConnectionService extends Service { /** * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of - * {@link IConferenceable}s passed in. + * {@link Conferenceable}s passed in. * - * @param conferenceables The {@link IConferenceable} connections and conferences. + * @param conferenceables The {@link Conferenceable} connections and conferences. * @return List of string conference and call Ids. */ - private List<String> createIdList(List<IConferenceable> conferenceables) { + private List<String> createIdList(List<Conferenceable> conferenceables) { List<String> ids = new ArrayList<>(); - for (IConferenceable c : conferenceables) { + for (Conferenceable c : conferenceables) { // Only allow Connection and Conference conferenceables. if (c instanceof Connection) { Connection connection = (Connection) c; diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java index a410976..d026a28 100644 --- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java +++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java @@ -369,26 +369,4 @@ final class ConnectionServiceAdapter implements DeathRecipient { } } } - - /** - * Set the call substate for the connection. - * Valid values: {@link Connection#CALL_SUBSTATE_NONE}, - * {@link Connection#CALL_SUBSTATE_AUDIO_CONNECTED_SUSPENDED}, - * {@link Connection#CALL_SUBSTATE_VIDEO_CONNECTED_SUSPENDED}, - * {@link Connection#CALL_SUBSTATE_AVP_RETRY}, - * {@link Connection#CALL_SUBSTATE_MEDIA_PAUSED}. - * - * @param callId The unique ID of the call to set the substate for. - * @param callSubstate The new call substate. - * @hide - */ - public final void setCallSubstate(String callId, int callSubstate) { - Log.v(this, "setCallSubstate: %d", callSubstate); - for (IConnectionServiceAdapter adapter : mAdapters) { - try { - adapter.setCallSubstate(callId, callSubstate); - } catch (RemoteException ignored) { - } - } - } } diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java index 5f93789..429f296 100644 --- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java +++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java @@ -59,7 +59,6 @@ final class ConnectionServiceAdapterServant { private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20; private static final int MSG_ADD_EXISTING_CONNECTION = 21; private static final int MSG_ON_POST_DIAL_CHAR = 22; - private static final int MSG_SET_CALL_SUBSTATE = 23; private final IConnectionServiceAdapter mDelegate; @@ -221,10 +220,6 @@ final class ConnectionServiceAdapterServant { } break; } - case MSG_SET_CALL_SUBSTATE: { - mDelegate.setCallSubstate((String) msg.obj, msg.arg1); - break; - } } } }; @@ -389,12 +384,6 @@ final class ConnectionServiceAdapterServant { args.arg2 = connection; mHandler.obtainMessage(MSG_ADD_EXISTING_CONNECTION, args).sendToTarget(); } - - @Override - public void setCallSubstate(String connectionId, int callSubstate) { - mHandler.obtainMessage(MSG_SET_CALL_SUBSTATE, callSubstate, 0, - connectionId).sendToTarget(); - } }; public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) { diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java new file mode 100644 index 0000000..eef72fb --- /dev/null +++ b/telecomm/java/android/telecom/DefaultDialerManager.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2015 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.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.provider.Settings; +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class for managing the default dialer application that will receive incoming calls, and be + * allowed to make emergency outgoing calls. + * + * @hide + */ +public class DefaultDialerManager { + private static final String TAG = "DefaultDialerManager"; + + /** + * Sets the specified package name as the default dialer application. The caller of this method + * needs to have permission to write to secure settings. + * + * @hide + * */ + public static void setDefaultPhoneApplication(Context context, String packageName) { + // Get old package name + String oldPackageName = Settings.Secure.getString(context.getContentResolver(), + Settings.Secure.DIALER_DEFAULT_APPLICATION); + + if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) { + // No change + return; + } + + // Only make the change if the new package belongs to a valid phone application + List<ComponentName> componentNames = getInstalledDialerApplications(context); + final ComponentName foundComponent = getComponentName(componentNames, packageName); + + if (foundComponent != null) { + // Update the secure setting. + Settings.Secure.putString(context.getContentResolver(), + Settings.Secure.DIALER_DEFAULT_APPLICATION, foundComponent.getPackageName()); + } + } + + /** + * Returns the installed dialer application that will be used to receive incoming calls, and is + * allowed to make emergency calls. + * + * The application will be returned in order of preference: + * 1) User selected phone application (if still installed) + * 2) Pre-installed system dialer (if not disabled) + * 3) Null + * + * @hide + * */ + public static ComponentName getDefaultDialerApplication(Context context) { + String defaultPackageName = Settings.Secure.getString(context.getContentResolver(), + Settings.Secure.DIALER_DEFAULT_APPLICATION); + + final List<ComponentName> componentNames = getInstalledDialerApplications(context); + if (!TextUtils.isEmpty(defaultPackageName)) { + final ComponentName defaultDialer = + getComponentName(componentNames, defaultPackageName); + if (defaultDialer != null) { + return defaultDialer; + } + } + + // No user-set dialer found, fallback to system dialer + ComponentName systemDialer = getTelecomManager(context).getDefaultPhoneApp(); + + if (systemDialer == null) { + // No system dialer configured at build time + return null; + } + + // Verify that the system dialer has not been disabled. + return getComponentName(componentNames, systemDialer.getPackageName()); + } + + /** + * Returns a list of installed and available dialer applications. + * + * In order to appear in the list, a dialer application must implement an intent-filter with + * the DIAL intent for the following schemes: + * + * 1) Empty scheme + * 2) tel Uri scheme + * + * @hide + **/ + public static List<ComponentName> getInstalledDialerApplications(Context context) { + PackageManager packageManager = context.getPackageManager(); + + // Get the list of apps registered for the DIAL intent with empty scheme + Intent intent = new Intent(Intent.ACTION_DIAL); + List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0); + + List<ComponentName> componentNames = new ArrayList<ComponentName> (); + + for (ResolveInfo resolveInfo : resolveInfoList) { + final ActivityInfo activityInfo = resolveInfo.activityInfo; + if (activityInfo == null) { + continue; + } + final ComponentName componentName = + new ComponentName(activityInfo.packageName, activityInfo.name); + componentNames.add(componentName); + } + + // TODO: Filter for apps that don't handle DIAL intent with tel scheme + return componentNames; + } + + /** + * Returns the {@link ComponentName} for the installed dialer application for a given package + * name. + * + * @param context A valid context. + * @param packageName to retrieve the {@link ComponentName} for. + * + * @return The {@link ComponentName} for the installed dialer application corresponding to the + * package name, or null if none is found. + * + * @hide + */ + public static ComponentName getDialerApplicationForPackageName(Context context, + String packageName) { + return getComponentName(getInstalledDialerApplications(context), packageName); + } + + /** + * Returns the component from a list of application components that corresponds to the package + * name. + * + * @param componentNames A list of component names + * @param packageName The package name to look for + * @return The {@link ComponentName} that matches the provided packageName, or null if not + * found. + */ + private static ComponentName getComponentName(List<ComponentName> componentNames, + String packageName) { + for (ComponentName componentName : componentNames) { + if (TextUtils.equals(packageName, componentName.getPackageName())) { + return componentName; + } + } + return null; + } + + private static TelecomManager getTelecomManager(Context context) { + return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); + } +} diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java index 73bcd0c..3a7faf6 100644 --- a/telecomm/java/android/telecom/DisconnectCause.java +++ b/telecomm/java/android/telecom/DisconnectCause.java @@ -130,8 +130,10 @@ public final class DisconnectCause implements Parcelable { /** * Returns a short label which explains the reason for the disconnect cause and is for display - * in the user interface. The {@link ConnectionService } is responsible for providing and - * localizing this label. If there is no string provided, returns null. + * in the user interface. If not null, it is expected that the In-Call UI should display this + * text where it would normally display the call state ("Dialing", "Disconnected") and is + * therefore expected to be relatively small. The {@link ConnectionService } is responsible for + * providing and localizing this label. If there is no string provided, returns null. * * @return The disconnect label. */ @@ -141,8 +143,11 @@ public final class DisconnectCause implements Parcelable { /** * Returns a description which explains the reason for the disconnect cause and is for display - * in the user interface. The {@link ConnectionService } is responsible for providing and - * localizing this message. If there is no string provided, returns null. + * in the user interface. This optional text is generally a longer and more descriptive version + * of {@link #getLabel}, however it can exist even if {@link #getLabel} is empty. The In-Call UI + * should display this relatively prominently; the traditional implementation displays this as + * an alert dialog. The {@link ConnectionService} is responsible for providing and localizing + * this message. If there is no string provided, returns null. * * @return The disconnect description. */ diff --git a/telecomm/java/android/telecom/IConferenceable.java b/telecomm/java/android/telecom/IConferenceable.java index a9be20b..a664baa 100644 --- a/telecomm/java/android/telecom/IConferenceable.java +++ b/telecomm/java/android/telecom/IConferenceable.java @@ -19,8 +19,10 @@ package android.telecom; /** * Interface used to identify entities with which another entity can participate in a conference * call with. The {@link ConnectionService} implementation will only recognize - * {@link IConferenceable}s which are {@link Connection}s or {@link Conference}s. + * {@link Conferenceable}s which are {@link Connection}s or {@link Conference}s. + * <p> + * @deprecated use {@link Conferenceable} instead. + * @hide */ -public interface IConferenceable { - +public interface IConferenceable extends Conferenceable { } diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index 66072da..7cbc0fc 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -17,6 +17,7 @@ package android.telecom; import android.annotation.SdkConstant; +import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; import android.os.Handler; @@ -30,6 +31,8 @@ import com.android.internal.telecom.IInCallAdapter; import com.android.internal.telecom.IInCallService; import java.lang.String; +import java.util.Collections; +import java.util.List; /** * This service is implemented by any app that wishes to provide the user-interface for managing @@ -63,6 +66,7 @@ public abstract class InCallService extends Service { switch (msg.what) { case MSG_SET_IN_CALL_ADAPTER: mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj)); + mPhone.addListener(mPhoneListener); onPhoneCreated(mPhone); break; case MSG_ADD_CALL: @@ -144,6 +148,39 @@ public abstract class InCallService extends Service { } } + private Phone.Listener mPhoneListener = new Phone.Listener() { + /** ${inheritDoc} */ + @Override + public void onAudioStateChanged(Phone phone, AudioState audioState) { + InCallService.this.onAudioStateChanged(audioState); + } + + /** ${inheritDoc} */ + @Override + public void onBringToForeground(Phone phone, boolean showDialpad) { + InCallService.this.onBringToForeground(showDialpad); + } + + /** ${inheritDoc} */ + @Override + public void onCallAdded(Phone phone, Call call) { + InCallService.this.onCallAdded(call); + } + + /** ${inheritDoc} */ + @Override + public void onCallRemoved(Phone phone, Call call) { + InCallService.this.onCallRemoved(call); + } + + /** ${inheritDoc} */ + @Override + public void onCanAddCallChanged(Phone phone, boolean canAddCall) { + InCallService.this.onCanAddCallChanged(canAddCall); + } + + }; + private Phone mPhone; public InCallService() { @@ -161,8 +198,14 @@ public abstract class InCallService extends Service { mPhone = null; oldPhone.destroy(); + // destroy sets all the calls to disconnected if any live ones still exist. Therefore, + // it is important to remove the Listener *after* the call to destroy so that + // InCallService.on* callbacks are appropriately called. + oldPhone.removeListener(mPhoneListener); + onPhoneDestroyed(oldPhone); } + return false; } @@ -172,19 +215,79 @@ public abstract class InCallService extends Service { * @return The {@code Phone} object associated with this {@code InCallService}, or {@code null} * if the {@code InCallService} is not in a state where it has an associated * {@code Phone}. + * @hide + * @deprecated Use direct methods on InCallService instead of {@link Phone}. */ - public final Phone getPhone() { + @SystemApi + @Deprecated + public Phone getPhone() { return mPhone; } /** + * Obtains the current list of {@code Call}s to be displayed by this in-call experience. + * + * @return A list of the relevant {@code Call}s. + */ + public final List<Call> getCalls() { + return mPhone == null ? Collections.<Call>emptyList() : mPhone.getCalls(); + } + + /** + * Returns if the device can support additional calls. + * + * @return Whether the phone supports adding more calls. + */ + public final boolean canAddCall() { + return mPhone == null ? false : mPhone.canAddCall(); + } + + /** + * Obtains the current phone call audio state. + * + * @return An object encapsulating the audio state. Returns null if the service is not + * fully initialized. + */ + public final AudioState getAudioState() { + return mPhone == null ? null : mPhone.getAudioState(); + } + + /** + * Sets the microphone mute state. When this request is honored, there will be change to + * the {@link #getAudioState()}. + * + * @param state {@code true} if the microphone should be muted; {@code false} otherwise. + */ + public final void setMuted(boolean state) { + if (mPhone != null) { + mPhone.setMuted(state); + } + } + + /** + * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will + * be change to the {@link #getAudioState()}. + * + * @param route The audio route to use. + */ + public final void setAudioRoute(int route) { + if (mPhone != null) { + mPhone.setAudioRoute(route); + } + } + + /** * Invoked when the {@code Phone} has been created. This is a signal to the in-call experience * to start displaying in-call information to the user. Each instance of {@code InCallService} * will have only one {@code Phone}, and this method will be called exactly once in the lifetime * of the {@code InCallService}. * * @param phone The {@code Phone} object associated with this {@code InCallService}. + * @hide + * @deprecated Use direct methods on InCallService instead of {@link Phone}. */ + @SystemApi + @Deprecated public void onPhoneCreated(Phone phone) { } @@ -195,22 +298,76 @@ public abstract class InCallService extends Service { * call to {@link #onPhoneCreated(Phone)}. * * @param phone The {@code Phone} object associated with this {@code InCallService}. + * @hide + * @deprecated Use direct methods on InCallService instead of {@link Phone}. */ + @SystemApi + @Deprecated public void onPhoneDestroyed(Phone phone) { } /** + * Called when the audio state changes. + * + * @param audioState The new {@link AudioState}. + */ + public void onAudioStateChanged(AudioState audioState) { + } + + /** + * Called to bring the in-call screen to the foreground. The in-call experience should + * respond immediately by coming to the foreground to inform the user of the state of + * ongoing {@code Call}s. + * + * @param showDialpad If true, put up the dialpad when the screen is shown. + */ + public void onBringToForeground(boolean showDialpad) { + } + + /** + * Called when a {@code Call} has been added to this in-call session. The in-call user + * experience should add necessary state listeners to the specified {@code Call} and + * immediately start to show the user information about the existence + * and nature of this {@code Call}. Subsequent invocations of {@link #getCalls()} will + * include this {@code Call}. + * + * @param call A newly added {@code Call}. + */ + public void onCallAdded(Call call) { + } + + /** + * Called when a {@code Call} has been removed from this in-call session. The in-call user + * experience should remove any state listeners from the specified {@code Call} and + * immediately stop displaying any information about this {@code Call}. + * Subsequent invocations of {@link #getCalls()} will no longer include this {@code Call}. + * + * @param call A newly removed {@code Call}. + */ + public void onCallRemoved(Call call) { + } + + /** + * Called when the ability to add more calls changes. If the phone cannot + * support more calls then {@code canAddCall} is set to {@code false}. If it can, then it + * is set to {@code true}. This can be used to control the visibility of UI to add more calls. + * + * @param canAddCall Indicates whether an additional call can be added. + */ + public void onCanAddCallChanged(boolean canAddCall) { + } + + /** * Class to invoke functionality related to video calls. */ public static abstract class VideoCall { /** - * Sets a listener to invoke callback methods in the InCallUI after performing video - * telephony actions. + * Registers a callback to receive commands and state changes for video calls. * - * @param videoCallListener The call video client. + * @param callback The video call callback. */ - public abstract void setVideoCallListener(VideoCall.Listener videoCallListener); + public abstract void registerCallback(VideoCall.Callback callback); /** * Sets the camera to be used for video recording in a video call. @@ -253,7 +410,7 @@ public abstract class InCallService extends Service { /** * Issues a request to modify the properties of the current session. The request is sent to * the remote device where it it handled by - * {@link VideoCall.Listener#onSessionModifyRequestReceived}. + * {@link VideoCall.Callback#onSessionModifyRequestReceived}. * Some examples of session modification requests: upgrade call from audio to video, * downgrade call from video to audio, pause video. * @@ -265,9 +422,9 @@ public abstract class InCallService extends Service { * Provides a response to a request to change the current call session video * properties. * This is in response to a request the InCall UI has received via - * {@link VideoCall.Listener#onSessionModifyRequestReceived}. + * {@link VideoCall.Callback#onSessionModifyRequestReceived}. * The response is handled on the remove device by - * {@link VideoCall.Listener#onSessionModifyResponseReceived}. + * {@link VideoCall.Callback#onSessionModifyResponseReceived}. * * @param responseProfile The response call video properties. */ @@ -276,14 +433,14 @@ public abstract class InCallService extends Service { /** * Issues a request to the video provider to retrieve the camera capabilities. * Camera capabilities are reported back to the caller via - * {@link VideoCall.Listener#onCameraCapabilitiesChanged(CameraCapabilities)}. + * {@link VideoCall.Callback#onCameraCapabilitiesChanged(CameraCapabilities)}. */ public abstract void requestCameraCapabilities(); /** * Issues a request to the video telephony framework to retrieve the cumulative data usage for * the current call. Data usage is reported back to the caller via - * {@link VideoCall.Listener#onCallDataUsageChanged}. + * {@link VideoCall.Callback#onCallDataUsageChanged}. */ public abstract void requestCallDataUsage(); @@ -296,9 +453,9 @@ public abstract class InCallService extends Service { public abstract void setPauseImage(String uri); /** - * Listener class which invokes callbacks after video call actions occur. + * Callback class which invokes callbacks after video call actions occur. */ - public static abstract class Listener { + public static abstract class Callback { /** * Called when a session modification request is received from the remote device. * The remote request is sent via @@ -373,8 +530,7 @@ public abstract class InCallService extends Service { * * @param cameraCapabilities The changed camera capabilities. */ - public abstract void onCameraCapabilitiesChanged( - CameraCapabilities cameraCapabilities); + public abstract void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities); } } } diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java index adc648f..c5c3d11 100644 --- a/telecomm/java/android/telecom/ParcelableCall.java +++ b/telecomm/java/android/telecom/ParcelableCall.java @@ -54,7 +54,6 @@ public final class ParcelableCall implements Parcelable { private final int mVideoState; private final List<String> mConferenceableCallIds; private final Bundle mExtras; - private int mCallSubstate; public ParcelableCall( String id, @@ -76,8 +75,7 @@ public final class ParcelableCall implements Parcelable { StatusHints statusHints, int videoState, List<String> conferenceableCallIds, - Bundle extras, - int callSubstate) { + Bundle extras) { mId = id; mState = state; mDisconnectCause = disconnectCause; @@ -98,7 +96,6 @@ public final class ParcelableCall implements Parcelable { mVideoState = videoState; mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds); mExtras = extras; - mCallSubstate = callSubstate; } /** The unique ID of the call. */ @@ -235,14 +232,6 @@ public final class ParcelableCall implements Parcelable { return mExtras; } - /** - * The call substate. - * @return The substate of the call. - */ - public int getCallSubstate() { - return mCallSubstate; - } - /** Responsible for creating ParcelableCall objects for deserialized Parcels. */ public static final Parcelable.Creator<ParcelableCall> CREATOR = new Parcelable.Creator<ParcelableCall> () { @@ -273,7 +262,6 @@ public final class ParcelableCall implements Parcelable { List<String> conferenceableCallIds = new ArrayList<>(); source.readList(conferenceableCallIds, classLoader); Bundle extras = source.readParcelable(classLoader); - int callSubstate = source.readInt(); return new ParcelableCall( id, state, @@ -294,8 +282,7 @@ public final class ParcelableCall implements Parcelable { statusHints, videoState, conferenceableCallIds, - extras, - callSubstate); + extras); } @Override @@ -334,7 +321,6 @@ public final class ParcelableCall implements Parcelable { destination.writeInt(mVideoState); destination.writeList(mConferenceableCallIds); destination.writeParcelable(mExtras, 0); - destination.writeInt(mCallSubstate); } @Override diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java index b60b99d..552e250 100644 --- a/telecomm/java/android/telecom/ParcelableConnection.java +++ b/telecomm/java/android/telecom/ParcelableConnection.java @@ -46,7 +46,6 @@ public final class ParcelableConnection implements Parcelable { private final StatusHints mStatusHints; private final DisconnectCause mDisconnectCause; private final List<String> mConferenceableConnectionIds; - private final int mCallSubstate; /** @hide */ public ParcelableConnection( @@ -63,8 +62,7 @@ public final class ParcelableConnection implements Parcelable { boolean isVoipAudioMode, StatusHints statusHints, DisconnectCause disconnectCause, - List<String> conferenceableConnectionIds, - int callSubstate) { + List<String> conferenceableConnectionIds) { mPhoneAccount = phoneAccount; mState = state; mConnectionCapabilities = capabilities; @@ -79,7 +77,6 @@ public final class ParcelableConnection implements Parcelable { mStatusHints = statusHints; mDisconnectCause = disconnectCause; this.mConferenceableConnectionIds = conferenceableConnectionIds; - mCallSubstate = callSubstate; } public PhoneAccountHandle getPhoneAccount() { @@ -139,10 +136,6 @@ public final class ParcelableConnection implements Parcelable { return mConferenceableConnectionIds; } - public int getCallSubstate() { - return mCallSubstate; - } - @Override public String toString() { return new StringBuilder() @@ -177,7 +170,6 @@ public final class ParcelableConnection implements Parcelable { DisconnectCause disconnectCause = source.readParcelable(classLoader); List<String> conferenceableConnectionIds = new ArrayList<>(); source.readStringList(conferenceableConnectionIds); - int callSubstate = source.readInt(); return new ParcelableConnection( phoneAccount, @@ -193,8 +185,7 @@ public final class ParcelableConnection implements Parcelable { audioModeIsVoip, statusHints, disconnectCause, - conferenceableConnectionIds, - callSubstate); + conferenceableConnectionIds); } @Override @@ -227,6 +218,5 @@ public final class ParcelableConnection implements Parcelable { destination.writeParcelable(mStatusHints, 0); destination.writeParcelable(mDisconnectCause, 0); destination.writeStringList(mConferenceableConnectionIds); - destination.writeInt(mCallSubstate); } } diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java index d9a9cdf..c1c1129 100644 --- a/telecomm/java/android/telecom/Phone.java +++ b/telecomm/java/android/telecom/Phone.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.SystemApi; import android.util.ArrayMap; import java.util.Collections; @@ -26,7 +27,12 @@ import java.util.concurrent.CopyOnWriteArrayList; /** * A unified virtual device providing a means of voice (and other) communication on a device. + * + * @hide + * @deprecated Use {@link InCallService} directly instead of using this class. */ +@SystemApi +@Deprecated public final class Phone { public abstract static class Listener { @@ -100,12 +106,10 @@ public final class Phone { private boolean mCanAddCall = true; - /** {@hide} */ Phone(InCallAdapter adapter) { mInCallAdapter = adapter; } - /** {@hide} */ final void internalAddCall(ParcelableCall parcelableCall) { Call call = new Call(this, parcelableCall.getId(), mInCallAdapter); mCallByTelecomCallId.put(parcelableCall.getId(), call); @@ -115,14 +119,12 @@ public final class Phone { fireCallAdded(call); } - /** {@hide} */ final void internalRemoveCall(Call call) { mCallByTelecomCallId.remove(call.internalGetCallId()); mCalls.remove(call); fireCallRemoved(call); } - /** {@hide} */ final void internalUpdateCall(ParcelableCall parcelableCall) { Call call = mCallByTelecomCallId.get(parcelableCall.getId()); if (call != null) { @@ -131,7 +133,6 @@ public final class Phone { } } - /** {@hide} */ final void internalSetPostDialWait(String telecomId, String remaining) { Call call = mCallByTelecomCallId.get(telecomId); if (call != null) { @@ -139,7 +140,6 @@ public final class Phone { } } - /** {@hide} */ final void internalAudioStateChanged(AudioState audioState) { if (!Objects.equals(mAudioState, audioState)) { mAudioState = audioState; @@ -147,17 +147,14 @@ public final class Phone { } } - /** {@hide} */ final Call internalGetCallByTelecomId(String telecomId) { return mCallByTelecomCallId.get(telecomId); } - /** {@hide} */ final void internalBringToForeground(boolean showDialpad) { fireBringToForeground(showDialpad); } - /** {@hide} */ final void internalSetCanAddCall(boolean canAddCall) { if (mCanAddCall != canAddCall) { mCanAddCall = canAddCall; @@ -167,7 +164,6 @@ public final class Phone { /** * Called to destroy the phone and cleanup any lingering calls. - * @hide */ final void destroy() { for (Call call : mCalls) { diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 00d170f..bab460d 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -89,9 +89,7 @@ public class PhoneAccount implements Parcelable { * Flag indicating that this {@code PhoneAccount} is capable of placing video calls. * <p> * See {@link #getCapabilities} - * @hide */ - @SystemApi public static final int CAPABILITY_VIDEO_CALLING = 0x8; /** diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java index 009ec5b..4c423f2 100644 --- a/telecomm/java/android/telecom/RemoteConnection.java +++ b/telecomm/java/android/telecom/RemoteConnection.java @@ -153,16 +153,6 @@ public final class RemoteConnection { public void onVideoStateChanged(RemoteConnection connection, int videoState) {} /** - * Indicates that the call substate of this {@code RemoteConnection} has changed. - * See {@link #getCallSubstate()}. - * - * @param connection The {@code RemoteConnection} invoking this method. - * @param callSubstate The new call substate of the {@code RemoteConnection}. - * @hide - */ - public void onCallSubstateChanged(RemoteConnection connection, int callSubstate) {} - - /** * Indicates that this {@code RemoteConnection} has been destroyed. No further requests * should be made to the {@code RemoteConnection}, and references to it should be cleared. * @@ -414,7 +404,6 @@ public final class RemoteConnection { private boolean mConnected; private int mConnectionCapabilities; private int mVideoState; - private int mCallSubstate; private VideoProvider mVideoProvider; private boolean mIsVoipAudioMode; private StatusHints mStatusHints; @@ -595,15 +584,6 @@ public final class RemoteConnection { } /** - * - * @return The call substate of the {@code RemoteConnection}. See - * @hide - */ - public int getCallSubstate() { - return mCallSubstate; - } - - /** * Obtains the video provider of this {@code RemoteConnection}. * @return The video provider associated with this {@code RemoteConnection}. * @hide @@ -916,16 +896,6 @@ public final class RemoteConnection { /** * @hide */ - void setCallSubstate(int callSubstate) { - mCallSubstate = callSubstate; - for (Callback c : mCallbacks) { - c.onCallSubstateChanged(this, callSubstate); - } - } - - /** - * @hide - */ void setVideoProvider(VideoProvider videoProvider) { mVideoProvider = videoProvider; for (Callback c : mCallbacks) { diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java index 179db55..a9b725b 100644 --- a/telecomm/java/android/telecom/RemoteConnectionService.java +++ b/telecomm/java/android/telecom/RemoteConnectionService.java @@ -60,11 +60,16 @@ final class RemoteConnectionService { mPendingConnections.remove(connection); // Unconditionally initialize the connection ... connection.setConnectionCapabilities(parcel.getConnectionCapabilities()); - connection.setAddress( - parcel.getHandle(), parcel.getHandlePresentation()); - connection.setCallerDisplayName( - parcel.getCallerDisplayName(), - parcel.getCallerDisplayNamePresentation()); + if (parcel.getHandle() != null + || parcel.getState() != Connection.STATE_DISCONNECTED) { + connection.setAddress(parcel.getHandle(), parcel.getHandlePresentation()); + } + if (parcel.getCallerDisplayName() != null + || parcel.getState() != Connection.STATE_DISCONNECTED) { + connection.setCallerDisplayName( + parcel.getCallerDisplayName(), + parcel.getCallerDisplayNamePresentation()); + } // Set state after handle so that the client can identify the connection. if (parcel.getState() == Connection.STATE_DISCONNECTED) { connection.setDisconnected(parcel.getDisconnectCause()); @@ -79,7 +84,6 @@ final class RemoteConnectionService { } connection.setConferenceableConnections(conferenceable); connection.setVideoState(parcel.getVideoState()); - connection.setCallSubstate(parcel.getCallSubstate()); if (connection.getState() == Connection.STATE_DISCONNECTED) { // ... then, if it was created in a disconnected state, that indicates // failure on the providing end, so immediately mark it destroyed @@ -307,12 +311,6 @@ final class RemoteConnectionService { mOurConnectionServiceImpl.addRemoteExistingConnection(remoteConnction); } - - @Override - public void setCallSubstate(String callId, int callSubstate) { - findConnectionForAction(callId, "callSubstate") - .setCallSubstate(callSubstate); - } }; private final ConnectionServiceAdapterServant mServant = diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index c73f6c2..fd95327 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -17,6 +17,7 @@ package android.telecom; import android.annotation.SystemApi; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; @@ -75,12 +76,24 @@ public class TelecomManager { "android.telecom.action.CONNECTION_SERVICE_CONFIGURE"; /** + * The {@link android.content.Intent} action used to show the call accessibility settings page. + */ + public static final String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = + "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS"; + + /** * The {@link android.content.Intent} action used to show the call settings page. */ public static final String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS"; /** + * The {@link android.content.Intent} action used to show the respond via SMS settings page. + */ + public static final String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = + "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"; + + /** * The {@link android.content.Intent} action used to show the settings page used to configure * {@link PhoneAccount} preferences. */ @@ -347,7 +360,8 @@ public class TelecomManager { public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) { try { if (isServiceConnected()) { - return getTelecomService().getDefaultOutgoingPhoneAccount(uriScheme); + return getTelecomService().getDefaultOutgoingPhoneAccount(uriScheme, + mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getDefaultOutgoingPhoneAccount", e); @@ -431,7 +445,7 @@ public class TelecomManager { public List<PhoneAccountHandle> getSimCallManagers() { try { if (isServiceConnected()) { - return getTelecomService().getSimCallManagers(); + return getTelecomService().getSimCallManagers(mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getSimCallManagers"); @@ -479,7 +493,8 @@ public class TelecomManager { public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) { try { if (isServiceConnected()) { - return getTelecomService().getPhoneAccountsSupportingScheme(uriScheme); + return getTelecomService().getPhoneAccountsSupportingScheme(uriScheme, + mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e); @@ -494,11 +509,12 @@ public class TelecomManager { * * @see #EXTRA_PHONE_ACCOUNT_HANDLE * @return A list of {@code PhoneAccountHandle} objects. + * */ public List<PhoneAccountHandle> getCallCapablePhoneAccounts() { try { if (isServiceConnected()) { - return getTelecomService().getCallCapablePhoneAccounts(); + return getTelecomService().getCallCapablePhoneAccounts(mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts", e); @@ -698,7 +714,8 @@ public class TelecomManager { public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) { try { if (isServiceConnected()) { - return getTelecomService().isVoiceMailNumber(accountHandle, number); + return getTelecomService().isVoiceMailNumber(accountHandle, number, + mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling ITelecomService#isVoiceMailNumber.", e); @@ -707,20 +724,22 @@ public class TelecomManager { } /** - * Return whether a given phone account has a voicemail number configured. + * Return the voicemail number for a given phone account. * - * @param accountHandle The handle for the account to check for a voicemail number. - * @return {@code true} If the given phone account has a voicemail number. + * @param accountHandle The handle for the phone account. + * @return The voicemail number for the phone account, and {@code null} if one has not been + * configured. */ - public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) { + public String getVoiceMailNumber(PhoneAccountHandle accountHandle) { try { if (isServiceConnected()) { - return getTelecomService().hasVoiceMailNumber(accountHandle); + return getTelecomService().getVoiceMailNumber(accountHandle, + mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling ITelecomService#hasVoiceMailNumber.", e); } - return false; + return null; } /** @@ -732,7 +751,8 @@ public class TelecomManager { public String getLine1Number(PhoneAccountHandle accountHandle) { try { if (isServiceConnected()) { - return getTelecomService().getLine1Number(accountHandle); + return getTelecomService().getLine1Number(accountHandle, + mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling ITelecomService#getLine1Number.", e); @@ -750,7 +770,7 @@ public class TelecomManager { public boolean isInCall() { try { if (isServiceConnected()) { - return getTelecomService().isInCall(); + return getTelecomService().isInCall(mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling isInCall().", e); @@ -792,7 +812,7 @@ public class TelecomManager { public boolean isRinging() { try { if (isServiceConnected()) { - return getTelecomService().isRinging(); + return getTelecomService().isRinging(mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException attempting to get ringing state of phone app.", e); @@ -858,7 +878,7 @@ public class TelecomManager { public boolean isTtySupported() { try { if (isServiceConnected()) { - return getTelecomService().isTtySupported(); + return getTelecomService().isTtySupported(mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException attempting to get TTY supported state.", e); @@ -879,7 +899,7 @@ public class TelecomManager { public int getCurrentTtyMode() { try { if (isServiceConnected()) { - return getTelecomService().getCurrentTtyMode(); + return getTelecomService().getCurrentTtyMode(mContext.getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException attempting to get the current TTY mode.", e); @@ -1031,13 +1051,46 @@ public class TelecomManager { ITelecomService service = getTelecomService(); if (service != null) { try { - service.showInCallScreen(showDialpad); + service.showInCallScreen(showDialpad, mContext.getOpPackageName()); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#showCallScreen", e); } } } + /** + * Places a new outgoing call to the provided address using the system telecom service with + * the specified extras. + * + * This method is equivalent to placing an outgoing call using {@link Intent#ACTION_CALL}, + * except that the outgoing call will always be sent via the system telecom service. If + * method-caller is either the user selected default dialer app or preloaded system dialer + * app, then emergency calls will also be allowed. + * + * Requires permission: {@link android.Manifest.permission#CALL_PHONE} + * + * Usage example: + * <pre> + * Uri uri = Uri.fromParts("tel", "12345", null); + * Bundle extras = new Bundle(); + * extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true); + * telecomManager.placeCall(uri, extras); + * </pre> + * + * @param address The address to make the call to. + * @param extras Bundle of extras to use with the call. + */ + public void placeCall(Uri address, Bundle extras) { + ITelecomService service = getTelecomService(); + if (service != null) { + try { + service.placeCall(address, extras, mContext.getOpPackageName()); + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelecomService#placeCall", e); + } + } + } + private ITelecomService getTelecomService() { return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE)); } diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java index 0445448..7bef688 100644 --- a/telecomm/java/android/telecom/VideoCallImpl.java +++ b/telecomm/java/android/telecom/VideoCallImpl.java @@ -46,7 +46,7 @@ public class VideoCallImpl extends VideoCall { private final IVideoProvider mVideoProvider; private final VideoCallListenerBinder mBinder; - private VideoCall.Listener mVideoCallListener; + private VideoCall.Callback mCallback; private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { @Override @@ -109,14 +109,14 @@ public class VideoCallImpl extends VideoCall { private final Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { - if (mVideoCallListener == null) { + if (mCallback == null) { return; } SomeArgs args; switch (msg.what) { case MSG_RECEIVE_SESSION_MODIFY_REQUEST: - mVideoCallListener.onSessionModifyRequestReceived((VideoProfile) msg.obj); + mCallback.onSessionModifyRequestReceived((VideoProfile) msg.obj); break; case MSG_RECEIVE_SESSION_MODIFY_RESPONSE: args = (SomeArgs) msg.obj; @@ -125,34 +125,34 @@ public class VideoCallImpl extends VideoCall { VideoProfile requestProfile = (VideoProfile) args.arg2; VideoProfile responseProfile = (VideoProfile) args.arg3; - mVideoCallListener.onSessionModifyResponseReceived( + mCallback.onSessionModifyResponseReceived( status, requestProfile, responseProfile); } finally { args.recycle(); } break; case MSG_HANDLE_CALL_SESSION_EVENT: - mVideoCallListener.onCallSessionEvent((int) msg.obj); + mCallback.onCallSessionEvent((int) msg.obj); break; case MSG_CHANGE_PEER_DIMENSIONS: args = (SomeArgs) msg.obj; try { int width = (int) args.arg1; int height = (int) args.arg2; - mVideoCallListener.onPeerDimensionsChanged(width, height); + mCallback.onPeerDimensionsChanged(width, height); } finally { args.recycle(); } break; case MSG_CHANGE_CALL_DATA_USAGE: - mVideoCallListener.onCallDataUsageChanged((long) msg.obj); + mCallback.onCallDataUsageChanged((long) msg.obj); break; case MSG_CHANGE_CAMERA_CAPABILITIES: - mVideoCallListener.onCameraCapabilitiesChanged( + mCallback.onCameraCapabilitiesChanged( (CameraCapabilities) msg.obj); break; case MSG_CHANGE_VIDEO_QUALITY: - mVideoCallListener.onVideoQualityChanged(msg.arg1); + mCallback.onVideoQualityChanged(msg.arg1); break; default: break; @@ -170,8 +170,8 @@ public class VideoCallImpl extends VideoCall { } /** {@inheritDoc} */ - public void setVideoCallListener(VideoCall.Listener videoCallListener) { - mVideoCallListener = videoCallListener; + public void registerCallback(VideoCall.Callback callback) { + mCallback = callback; } /** {@inheritDoc} */ diff --git a/telecomm/java/android/telecom/Voicemail.java b/telecomm/java/android/telecom/Voicemail.java index dbec2ad..f5b8052 100644 --- a/telecomm/java/android/telecom/Voicemail.java +++ b/telecomm/java/android/telecom/Voicemail.java @@ -59,6 +59,16 @@ public class Voicemail implements Parcelable { } /** + * Create a {@link Builder} for a {@link Voicemail} to be updated (or deleted). + * <p> + * The id and source data fields are mandatory for update - id is necessary for updating the + * database and source data is necessary for updating the server. + */ + public static Builder createForUpdate(long id, String sourceData) { + return new Builder().setId(id).setSourceData(sourceData); + } + + /** * Builder pattern for creating a {@link Voicemail}. The builder must be created with the * {@link #createForInsertion(long, String)} method. * <p> diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl index e6c28f3..7e7e9cc 100644 --- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl @@ -81,6 +81,4 @@ oneway interface IConnectionServiceAdapter { void setConferenceableConnections(String callId, in List<String> conferenceableCallIds); void addExistingConnection(String callId, in ParcelableConnection connection); - - void setCallSubstate(String callId, int callSubstate); } diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index d2030f2..45b2482 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -33,12 +33,12 @@ interface ITelecomService { * * @param showDialpad if true, make the dialpad visible initially. */ - void showInCallScreen(boolean showDialpad); + void showInCallScreen(boolean showDialpad, String callingPackage); /** * @see TelecomServiceImpl#getDefaultOutgoingPhoneAccount */ - PhoneAccountHandle getDefaultOutgoingPhoneAccount(in String uriScheme); + PhoneAccountHandle getDefaultOutgoingPhoneAccount(in String uriScheme, String callingPackage); /** * @see TelecomServiceImpl#getUserSelectedOutgoingPhoneAccount @@ -53,12 +53,13 @@ interface ITelecomService { /** * @see TelecomServiceImpl#getCallCapablePhoneAccounts */ - List<PhoneAccountHandle> getCallCapablePhoneAccounts(); + List<PhoneAccountHandle> getCallCapablePhoneAccounts(String callingPackage); /** * @see TelecomManager#getPhoneAccountsSupportingScheme */ - List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme); + List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme, + String callingPackage); /** * @see TelecomManager#getPhoneAccountsForPackage @@ -98,7 +99,7 @@ interface ITelecomService { /** * @see TelecomServiceImpl#getSimCallManagers */ - List<PhoneAccountHandle> getSimCallManagers(); + List<PhoneAccountHandle> getSimCallManagers(String callingPackage); /** * @see TelecomServiceImpl#registerPhoneAccount @@ -118,17 +119,18 @@ interface ITelecomService { /** * @see TelecomServiceImpl#isVoiceMailNumber */ - boolean isVoiceMailNumber(in PhoneAccountHandle accountHandle, String number); + boolean isVoiceMailNumber(in PhoneAccountHandle accountHandle, String number, + String callingPackage); /** - * @see TelecomServiceImpl#hasVoiceMailNumber + * @see TelecomServiceImpl#getVoiceMailNumber */ - boolean hasVoiceMailNumber(in PhoneAccountHandle accountHandle); + String getVoiceMailNumber(in PhoneAccountHandle accountHandle, String callingPackage); /** * @see TelecomServiceImpl#getLine1Number */ - String getLine1Number(in PhoneAccountHandle accountHandle); + String getLine1Number(in PhoneAccountHandle accountHandle, String callingPackage); /** * @see TelecomServiceImpl#getDefaultPhoneApp @@ -147,12 +149,12 @@ interface ITelecomService { /** * @see TelecomServiceImpl#isInCall */ - boolean isInCall(); + boolean isInCall(String callingPackage); /** * @see TelecomServiceImpl#isRinging */ - boolean isRinging(); + boolean isRinging(String callingPackage); /** * @see TelecomServiceImpl#getCallState @@ -192,12 +194,12 @@ interface ITelecomService { /** * @see TelecomServiceImpl#isTtySupported */ - boolean isTtySupported(); + boolean isTtySupported(String callingPackage); /** * @see TelecomServiceImpl#getCurrentTtyMode */ - int getCurrentTtyMode(); + int getCurrentTtyMode(String callingPackage); /** * @see TelecomServiceImpl#addNewIncomingCall @@ -208,4 +210,9 @@ interface ITelecomService { * @see TelecomServiceImpl#addNewUnknownCall */ void addNewUnknownCall(in PhoneAccountHandle phoneAccount, in Bundle extras); + + /** + * @see TelecomServiceImpl#placeCall + */ + void placeCall(in Uri handle, in Bundle extras, String callingPackage); } |