diff options
Diffstat (limited to 'telecomm/java')
29 files changed, 1003 insertions, 554 deletions
diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java index 465c5f4..33013ac 100644 --- a/telecomm/java/android/telecom/AudioState.java +++ b/telecomm/java/android/telecom/AudioState.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -24,8 +25,12 @@ import java.util.Locale; /** * Encapsulates the telecom audio state, including the current audio routing, supported audio * routing and mute. + * @deprecated - use {@link CallAudioState} instead. + * @hide */ -public final class AudioState implements Parcelable { +@Deprecated +@SystemApi +public class AudioState implements Parcelable { /** Direct the audio stream through the device's earpiece. */ public static final int ROUTE_EARPIECE = 0x00000001; @@ -64,6 +69,12 @@ public final class AudioState implements Parcelable { supportedRouteMask = state.getSupportedRouteMask(); } + public AudioState(CallAudioState state) { + isMuted = state.isMuted(); + route = state.getRoute(); + supportedRouteMask = state.getSupportedRouteMask(); + } + @Override public boolean equals(Object obj) { if (obj == null) { diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index fee6495..d74c61c 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -202,7 +202,7 @@ 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. + * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState. */ public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000; @@ -1000,9 +1000,9 @@ public final class Call { } boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() && - !Objects.equals(mVideoCall, parcelableCall.getVideoCall()); + !Objects.equals(mVideoCall, parcelableCall.getVideoCall(this)); if (videoCallChanged) { - mVideoCall = parcelableCall.getVideoCall(); + mVideoCall = parcelableCall.getVideoCall(this); } int state = parcelableCall.getState(); diff --git a/telecomm/java/android/telecom/CameraCapabilities.aidl b/telecomm/java/android/telecom/CallAudioState.aidl index c8e0c5e..90dbbe5 100644 --- a/telecomm/java/android/telecom/CameraCapabilities.aidl +++ b/telecomm/java/android/telecom/CallAudioState.aidl @@ -1,17 +1,17 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * 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 + * 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 + * limitations under the License. */ package android.telecom; @@ -19,4 +19,4 @@ package android.telecom; /** * {@hide} */ -parcelable CameraCapabilities; +parcelable CallAudioState; diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java new file mode 100644 index 0000000..2b16722 --- /dev/null +++ b/telecomm/java/android/telecom/CallAudioState.java @@ -0,0 +1,209 @@ +/* + * 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.os.Parcel; +import android.os.Parcelable; + +import java.util.Locale; + +/** + * Encapsulates the telecom audio state, including the current audio routing, supported audio + * routing and mute. + */ +public final class CallAudioState implements Parcelable { + /** Direct the audio stream through the device's earpiece. */ + public static final int ROUTE_EARPIECE = 0x00000001; + + /** Direct the audio stream through Bluetooth. */ + public static final int ROUTE_BLUETOOTH = 0x00000002; + + /** Direct the audio stream through a wired headset. */ + public static final int ROUTE_WIRED_HEADSET = 0x00000004; + + /** Direct the audio stream through the device's speakerphone. */ + public static final int ROUTE_SPEAKER = 0x00000008; + + /** + * Direct the audio stream through the device's earpiece or wired headset if one is + * connected. + */ + public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET; + + /** Bit mask of all possible audio routes. */ + private static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET | + ROUTE_SPEAKER; + + private final boolean isMuted; + private final int route; + private final int supportedRouteMask; + + /** + * Constructor for a {@link CallAudioState} object. + * + * @param muted {@code true} if the call is muted, {@code false} otherwise. + * @param route The current audio route being used. + * Allowed values: + * {@link #ROUTE_EARPIECE} + * {@link #ROUTE_BLUETOOTH} + * {@link #ROUTE_WIRED_HEADSET} + * {@link #ROUTE_SPEAKER} + * @param supportedRouteMask Bit mask of all routes supported by this call. This should be a + * bitwise combination of the following values: + * {@link #ROUTE_EARPIECE} + * {@link #ROUTE_BLUETOOTH} + * {@link #ROUTE_WIRED_HEADSET} + * {@link #ROUTE_SPEAKER} + */ + public CallAudioState(boolean muted, int route, int supportedRouteMask) { + this.isMuted = muted; + this.route = route; + this.supportedRouteMask = supportedRouteMask; + } + + /** @hide */ + public CallAudioState(CallAudioState state) { + isMuted = state.isMuted(); + route = state.getRoute(); + supportedRouteMask = state.getSupportedRouteMask(); + } + + /** @hide */ + @SuppressWarnings("deprecation") + public CallAudioState(AudioState state) { + isMuted = state.isMuted(); + route = state.getRoute(); + supportedRouteMask = state.getSupportedRouteMask(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof CallAudioState)) { + return false; + } + CallAudioState state = (CallAudioState) obj; + return isMuted() == state.isMuted() && getRoute() == state.getRoute() && + getSupportedRouteMask() == state.getSupportedRouteMask(); + } + + @Override + public String toString() { + return String.format(Locale.US, + "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s]", + isMuted, + audioRouteToString(route), + audioRouteToString(supportedRouteMask)); + } + + /** + * @return {@code true} if the call is muted, {@code false} otherwise. + */ + public boolean isMuted() { + return isMuted; + } + + /** + * @return The current audio route being used. + */ + public int getRoute() { + return route; + } + + /** + * @return Bit mask of all routes supported by this call. + */ + public int getSupportedRouteMask() { + return supportedRouteMask; + } + + /** + * Converts the provided audio route into a human readable string representation. + * + * @param route to convert into a string. + * + * @return String representation of the provided audio route. + */ + public static String audioRouteToString(int route) { + if (route == 0 || (route & ~ROUTE_ALL) != 0x0) { + return "UNKNOWN"; + } + + StringBuffer buffer = new StringBuffer(); + if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) { + listAppend(buffer, "EARPIECE"); + } + if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) { + listAppend(buffer, "BLUETOOTH"); + } + if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) { + listAppend(buffer, "WIRED_HEADSET"); + } + if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) { + listAppend(buffer, "SPEAKER"); + } + + return buffer.toString(); + } + + /** + * Responsible for creating AudioState objects for deserialized Parcels. + */ + public static final Parcelable.Creator<CallAudioState> CREATOR = + new Parcelable.Creator<CallAudioState> () { + + @Override + public CallAudioState createFromParcel(Parcel source) { + boolean isMuted = source.readByte() == 0 ? false : true; + int route = source.readInt(); + int supportedRouteMask = source.readInt(); + return new CallAudioState(isMuted, route, supportedRouteMask); + } + + @Override + public CallAudioState[] newArray(int size) { + return new CallAudioState[size]; + } + }; + + /** + * {@inheritDoc} + */ + @Override + public int describeContents() { + return 0; + } + + /** + * Writes AudioState object into a serializeable Parcel. + */ + @Override + public void writeToParcel(Parcel destination, int flags) { + destination.writeByte((byte) (isMuted ? 1 : 0)); + destination.writeInt(route); + destination.writeInt(supportedRouteMask); + } + + private static void listAppend(StringBuffer buffer, String str) { + if (buffer.length() > 0) { + buffer.append(", "); + } + buffer.append(str); + } +} diff --git a/telecomm/java/android/telecom/CameraCapabilities.java b/telecomm/java/android/telecom/CameraCapabilities.java deleted file mode 100644 index 6242956..0000000 --- a/telecomm/java/android/telecom/CameraCapabilities.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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.os.Parcel; -import android.os.Parcelable; - -/** - * Represents the camera capabilities important to a Video Telephony provider. - */ -public final class CameraCapabilities implements Parcelable { - - /** - * The width of the camera video in pixels. - */ - private final int mWidth; - - /** - * The height of the camera video in pixels. - */ - private final int mHeight; - - /** - * Whether the camera supports zoom. - */ - private final boolean mZoomSupported; - - /** - * The maximum zoom supported by the camera. - */ - private final float mMaxZoom; - - /** - * Create a call camera capabilities instance. - * - * @param width The width of the camera video (in pixels). - * @param height The height of the camera video (in pixels). - */ - public CameraCapabilities(int width, int height) { - this(width, height, false, 1.0f); - } - - /** - * Create a call camera capabilities instance that optionally - * supports zoom. - * - * @param width The width of the camera video (in pixels). - * @param height The height of the camera video (in pixels). - * @param zoomSupported True when camera supports zoom. - * @param maxZoom Maximum zoom supported by camera. - * @hide - */ - public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) { - mWidth = width; - mHeight = height; - mZoomSupported = zoomSupported; - mMaxZoom = maxZoom; - } - - /** - * Responsible for creating CallCameraCapabilities objects from deserialized Parcels. - **/ - public static final Parcelable.Creator<CameraCapabilities> CREATOR = - new Parcelable.Creator<CameraCapabilities> () { - /** - * Creates a CallCameraCapabilities instances from a parcel. - * - * @param source The parcel. - * @return The CallCameraCapabilities. - */ - @Override - public CameraCapabilities createFromParcel(Parcel source) { - int width = source.readInt(); - int height = source.readInt(); - boolean supportsZoom = source.readByte() != 0; - float maxZoom = source.readFloat(); - - return new CameraCapabilities(width, height, supportsZoom, maxZoom); - } - - @Override - public CameraCapabilities[] newArray(int size) { - return new CameraCapabilities[size]; - } - }; - - /** - * Describe the kinds of special objects contained in this Parcelable's - * marshalled representation. - * - * @return a bitmask indicating the set of special object types marshalled - * by the Parcelable. - */ - @Override - public int describeContents() { - return 0; - } - - /** - * Flatten this object in to a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written. - * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}. - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(getWidth()); - dest.writeInt(getHeight()); - dest.writeByte((byte) (isZoomSupported() ? 1 : 0)); - dest.writeFloat(getMaxZoom()); - } - - /** - * The width of the camera video in pixels. - */ - public int getWidth() { - return mWidth; - } - - /** - * The height of the camera video in pixels. - */ - public int getHeight() { - return mHeight; - } - - /** - * Whether the camera supports zoom. - * @hide - */ - public boolean isZoomSupported() { - return mZoomSupported; - } - - /** - * The maximum zoom supported by the camera. - * @hide - */ - public float getMaxZoom() { - return mMaxZoom; - } -} diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 0424548..d8d9ab6 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.SystemApi; import android.telecom.Connection.VideoProvider; import java.util.ArrayList; @@ -62,7 +63,7 @@ public abstract class Conference implements Conferenceable { Collections.unmodifiableList(mConferenceableConnections); private PhoneAccountHandle mPhoneAccount; - private AudioState mAudioState; + private CallAudioState mCallAudioState; private int mState = Connection.STATE_NEW; private DisconnectCause mDisconnectCause; private int mConnectionCapabilities; @@ -116,7 +117,7 @@ public abstract class Conference implements Conferenceable { } /** - * Returns the capabilities of a conference. See {@code CAPABILITY_*} constants in class + * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class * {@link Connection} for valid values. * * @return A bitmask of the capabilities of the conference call. @@ -172,14 +173,26 @@ public abstract class Conference implements Conferenceable { * @return The audio state of the conference, describing how its audio is currently * being routed by the system. This is {@code null} if this Conference * does not directly know about its audio state. + * @deprecated Use {@link #getCallAudioState()} instead. + * @hide */ + @Deprecated + @SystemApi public final AudioState getAudioState() { - return mAudioState; + return new AudioState(mCallAudioState); + } + + /** + * @return The audio state of the conference, describing how its audio is currently + * being routed by the system. This is {@code null} if this Conference + * does not directly know about its audio state. + */ + public final CallAudioState getCallAudioState() { + return mCallAudioState; } /** * Returns VideoProvider of the primary call. This can be null. - * @hide */ public VideoProvider getVideoProvider() { return null; @@ -187,7 +200,6 @@ public abstract class Conference implements Conferenceable { /** * Returns video state of the primary call. - * @hide */ public int getVideoState() { return VideoProfile.VideoState.AUDIO_ONLY; @@ -250,10 +262,21 @@ public abstract class Conference implements Conferenceable { * Notifies this conference that the {@link #getAudioState()} property has a new value. * * @param state The new call audio state. + * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead. + * @hide */ + @SystemApi + @Deprecated public void onAudioStateChanged(AudioState state) {} /** + * Notifies this conference that the {@link #getCallAudioState()} property has a new value. + * + * @param state The new call audio state. + */ + public void onCallAudioStateChanged(CallAudioState state) {} + + /** * Notifies this conference that a connection has been added to it. * * @param connection The newly added connection. @@ -367,13 +390,12 @@ public abstract class Conference implements Conferenceable { /** * Set the video state for the conference. - * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, - * {@link VideoProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoProfile.VideoState#TX_ENABLED}, - * {@link VideoProfile.VideoState#RX_ENABLED}. + * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, + * {@link VideoProfile#STATE_BIDIRECTIONAL}, + * {@link VideoProfile#STATE_TX_ENABLED}, + * {@link VideoProfile#STATE_RX_ENABLED}. * * @param videoState The new video state. - * @hide */ public final void setVideoState(Connection c, int videoState) { Log.d(this, "setVideoState Conference: %s Connection: %s VideoState: %s", @@ -387,7 +409,6 @@ public abstract class Conference implements Conferenceable { * Sets the video connection provider. * * @param videoProvider The video provider. - * @hide */ public final void setVideoProvider(Connection c, Connection.VideoProvider videoProvider) { Log.d(this, "setVideoProvider Conference: %s Connection: %s VideoState: %s", @@ -462,7 +483,9 @@ public abstract class Conference implements Conferenceable { * the connection from which the conference will retrieve its current state. * * @return The primary connection. + * @hide */ + @SystemApi public Connection getPrimaryConnection() { if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) { return null; @@ -471,22 +494,42 @@ public abstract class Conference implements Conferenceable { } /** - * Sets the connect time of the {@code Conference}. + * @hide + * @deprecated Use {@link #setConnectionTime}. + */ + @Deprecated + @SystemApi + public final void setConnectTimeMillis(long connectTimeMillis) { + setConnectionTime(connectTimeMillis); + } + + /** + * Sets the connection start time of the {@code Conference}. * - * @param connectTimeMillis The connection time, in milliseconds. + * @param connectionTimeMillis The connection time, in milliseconds. */ - public void setConnectTimeMillis(long connectTimeMillis) { - mConnectTimeMillis = connectTimeMillis; + public final void setConnectionTime(long connectionTimeMillis) { + mConnectTimeMillis = connectionTimeMillis; } /** - * Retrieves the connect time of the {@code Conference}, if specified. A value of + * @hide + * @deprecated Use {@link #getConnectionTime}. + */ + @Deprecated + @SystemApi + public final long getConnectTimeMillis() { + return getConnectionTime(); + } + + /** + * Retrieves the connection start time of the {@code Conference}, if specified. A value of * {@link #CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the start time * of the conference. * - * @return The time the {@code Conference} has been connected. + * @return The time at which the {@code Conference} was connected. */ - public final long getConnectTimeMillis() { + public final long getConnectionTime() { return mConnectTimeMillis; } @@ -496,10 +539,11 @@ public abstract class Conference implements Conferenceable { * @param state The new audio state. * @hide */ - final void setAudioState(AudioState state) { - Log.d(this, "setAudioState %s", state); - mAudioState = state; - onAudioStateChanged(state); + final void setCallAudioState(CallAudioState state) { + Log.d(this, "setCallAudioState %s", state); + mCallAudioState = state; + onAudioStateChanged(getAudioState()); + onCallAudioStateChanged(state); } private void setState(int newState) { diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 3060f40..f39f813 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -16,9 +16,11 @@ package android.telecom; +import com.android.internal.os.SomeArgs; import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Handler; import android.os.IBinder; @@ -105,38 +107,32 @@ public abstract class Connection implements Conferenceable { /** * Local device supports receiving video. - * @hide */ public static final int CAPABILITY_SUPPORTS_VT_LOCAL_RX = 0x00000100; /** * Local device supports transmitting video. - * @hide */ public static final int CAPABILITY_SUPPORTS_VT_LOCAL_TX = 0x00000200; /** * Local device supports bidirectional video calling. - * @hide */ public static final int CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL = CAPABILITY_SUPPORTS_VT_LOCAL_RX | CAPABILITY_SUPPORTS_VT_LOCAL_TX; /** * Remote device supports receiving video. - * @hide */ public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 0x00000400; /** * Remote device supports transmitting video. - * @hide */ public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 0x00000800; /** * Remote device supports bidirectional video calling. - * @hide */ public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL = CAPABILITY_SUPPORTS_VT_REMOTE_RX | CAPABILITY_SUPPORTS_VT_REMOTE_TX; @@ -186,14 +182,12 @@ public abstract class Connection implements Conferenceable { /** * Call can be upgraded to a video call. - * @hide */ public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000; /** * For video calls, indicates whether the outgoing video for the call can be paused using - * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState. - * @hide + * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState. */ public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000; @@ -471,9 +465,16 @@ public abstract class Connection implements Conferenceable { case MSG_SET_ZOOM: onSetZoom((Float) msg.obj); break; - case MSG_SEND_SESSION_MODIFY_REQUEST: - onSendSessionModifyRequest((VideoProfile) msg.obj); + case MSG_SEND_SESSION_MODIFY_REQUEST: { + SomeArgs args = (SomeArgs) msg.obj; + try { + onSendSessionModifyRequest((VideoProfile) args.arg1, + (VideoProfile) args.arg2); + } finally { + args.recycle(); + } break; + } case MSG_SEND_SESSION_MODIFY_RESPONSE: onSendSessionModifyResponse((VideoProfile) msg.obj); break; @@ -484,7 +485,7 @@ public abstract class Connection implements Conferenceable { onRequestConnectionDataUsage(); break; case MSG_SET_PAUSE_IMAGE: - onSetPauseImage((String) msg.obj); + onSetPauseImage((Uri) msg.obj); break; default: break; @@ -527,9 +528,11 @@ public abstract class Connection implements Conferenceable { mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget(); } - public void sendSessionModifyRequest(VideoProfile requestProfile) { - mMessageHandler.obtainMessage( - MSG_SEND_SESSION_MODIFY_REQUEST, requestProfile).sendToTarget(); + public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = fromProfile; + args.arg2 = toProfile; + mMessageHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget(); } public void sendSessionModifyResponse(VideoProfile responseProfile) { @@ -545,7 +548,7 @@ public abstract class Connection implements Conferenceable { mMessageHandler.obtainMessage(MSG_REQUEST_CONNECTION_DATA_USAGE).sendToTarget(); } - public void setPauseImage(String uri) { + public void setPauseImage(Uri uri) { mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget(); } } @@ -606,9 +609,11 @@ public abstract class Connection implements Conferenceable { * Some examples of session modification requests: upgrade connection from audio to video, * downgrade connection from video to audio, pause video. * - * @param requestProfile The requested connection video properties. + * @param fromProfile The video properties prior to the request. + * @param toProfile The video properties with the requested changes made. */ - public abstract void onSendSessionModifyRequest(VideoProfile requestProfile); + public abstract void onSendSessionModifyRequest(VideoProfile fromProfile, + VideoProfile toProfile); /**te * Provides a response to a request to change the current connection session video @@ -638,7 +643,7 @@ public abstract class Connection implements Conferenceable { * * @param uri URI of image to display. */ - public abstract void onSetPauseImage(String uri); + public abstract void onSetPauseImage(Uri uri); /** * Invokes callback method defined in listening {@link InCallService} implementations. @@ -722,7 +727,7 @@ public abstract class Connection implements Conferenceable { * * @param dataUsage The updated data usage. */ - public void changeCallDataUsage(long dataUsage) { + public void setCallDataUsage(long dataUsage) { if (mVideoCallbacks != null) { try { for (IVideoCallback callback : mVideoCallbacks.values()) { @@ -736,9 +741,20 @@ public abstract class Connection implements Conferenceable { /** * Invokes callback method defined in listening {@link InCallService} implementations. * + * @param dataUsage The updated data usage. + * @deprecated - Use {@link #setCallDataUsage(long)} instead. + * @hide + */ + public void changeCallDataUsage(long dataUsage) { + setCallDataUsage(dataUsage); + } + + /** + * Invokes callback method defined in listening {@link InCallService} implementations. + * * @param cameraCapabilities The changed camera capabilities. */ - public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { + public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) { if (mVideoCallbacks != null) { try { for (IVideoCallback callback : mVideoCallbacks.values()) { @@ -752,6 +768,12 @@ public abstract class Connection implements Conferenceable { /** * Invokes callback method defined in listening {@link InCallService} implementations. * + * Allowed values: + * {@link VideoProfile#QUALITY_HIGH}, + * {@link VideoProfile#QUALITY_MEDIUM}, + * {@link VideoProfile#QUALITY_LOW}, + * {@link VideoProfile#QUALITY_DEFAULT}. + * * @param videoQuality The updated video quality. */ public void changeVideoQuality(int videoQuality) { @@ -796,7 +818,7 @@ public abstract class Connection implements Conferenceable { Collections.unmodifiableList(mConferenceables); private int mState = STATE_NEW; - private AudioState mAudioState; + private CallAudioState mCallAudioState; private Uri mAddress; private int mAddressPresentation; private String mCallerDisplayName; @@ -855,10 +877,10 @@ public abstract class Connection implements Conferenceable { /** * Returns the video state of the connection. - * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, - * {@link VideoProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoProfile.VideoState#TX_ENABLED}, - * {@link VideoProfile.VideoState#RX_ENABLED}. + * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, + * {@link VideoProfile#STATE_BIDIRECTIONAL}, + * {@link VideoProfile#STATE_TX_ENABLED}, + * {@link VideoProfile#STATE_RX_ENABLED}. * * @return The video state of the connection. * @hide @@ -871,9 +893,22 @@ public abstract class Connection implements Conferenceable { * @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. + * @deprecated Use {@link #getCallAudioState()} instead. + * @hide */ + @SystemApi + @Deprecated public final AudioState getAudioState() { - return mAudioState; + return new AudioState(mCallAudioState); + } + + /** + * @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. + */ + public final CallAudioState getCallAudioState() { + return mCallAudioState; } /** @@ -947,11 +982,12 @@ public abstract class Connection implements Conferenceable { * @param state The new audio state. * @hide */ - final void setAudioState(AudioState state) { + final void setCallAudioState(CallAudioState state) { checkImmutable(); Log.d(this, "setAudioState %s", state); - mAudioState = state; - onAudioStateChanged(state); + mCallAudioState = state; + onAudioStateChanged(getAudioState()); + onCallAudioStateChanged(state); } /** @@ -1023,13 +1059,12 @@ public abstract class Connection implements Conferenceable { /** * Set the video state for the connection. - * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, - * {@link VideoProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoProfile.VideoState#TX_ENABLED}, - * {@link VideoProfile.VideoState#RX_ENABLED}. + * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, + * {@link VideoProfile#STATE_BIDIRECTIONAL}, + * {@link VideoProfile#STATE_TX_ENABLED}, + * {@link VideoProfile#STATE_RX_ENABLED}. * * @param videoState The new video state. - * @hide */ public final void setVideoState(int videoState) { checkImmutable(); @@ -1093,7 +1128,6 @@ public abstract class Connection implements Conferenceable { /** * Sets the video connection provider. * @param videoProvider The video provider. - * @hide */ public final void setVideoProvider(VideoProvider videoProvider) { checkImmutable(); @@ -1340,10 +1374,21 @@ public abstract class Connection implements Conferenceable { * Notifies this Connection that the {@link #getAudioState()} property has a new value. * * @param state The new connection audio state. + * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead. + * @hide */ + @SystemApi + @Deprecated public void onAudioStateChanged(AudioState state) {} /** + * Notifies this Connection that the {@link #getCallAudioState()} property has a new value. + * + * @param state The new connection audio state. + */ + public void onCallAudioStateChanged(CallAudioState state) {} + + /** * Notifies this Connection of an internal state change. This method is called after the * state is changed. * @@ -1402,7 +1447,6 @@ public abstract class Connection implements Conferenceable { * a request to accept. * * @param videoState The video state in which to answer the connection. - * @hide */ public void onAnswer(int videoState) {} diff --git a/telecomm/java/android/telecom/ConnectionRequest.java b/telecomm/java/android/telecom/ConnectionRequest.java index 71b481b..975df5d 100644 --- a/telecomm/java/android/telecom/ConnectionRequest.java +++ b/telecomm/java/android/telecom/ConnectionRequest.java @@ -50,7 +50,6 @@ public final class ConnectionRequest implements Parcelable { * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. * @param extras Application-specific extra data. * @param videoState Determines the video state for the connection. - * @hide */ public ConnectionRequest( PhoneAccountHandle accountHandle, @@ -89,13 +88,12 @@ public final class ConnectionRequest implements Parcelable { /** * Describes the video states supported by the client requesting the connection. - * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, - * {@link VideoProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoProfile.VideoState#TX_ENABLED}, - * {@link VideoProfile.VideoState#RX_ENABLED}. + * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, + * {@link VideoProfile#STATE_BIDIRECTIONAL}, + * {@link VideoProfile#STATE_TX_ENABLED}, + * {@link VideoProfile#STATE_RX_ENABLED}. * * @return The video state for the connection. - * @hide */ public int getVideoState() { return mVideoState; diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 4185651..199100b 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -50,7 +50,7 @@ import java.util.concurrent.ConcurrentHashMap; * <pre> * <service android:name="com.example.package.MyConnectionService" * android:label="@string/some_label_for_my_connection_service" - * android:permission="android.permission.BIND_CONNECTION_SERVICE"> + * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"> * <intent-filter> * <action android:name="android.telecom.ConnectionService" /> * </intent-filter> @@ -90,7 +90,7 @@ public abstract class ConnectionService extends Service { private static final int MSG_DISCONNECT = 6; private static final int MSG_HOLD = 7; private static final int MSG_UNHOLD = 8; - private static final int MSG_ON_AUDIO_STATE_CHANGED = 9; + private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9; private static final int MSG_PLAY_DTMF_TONE = 10; private static final int MSG_STOP_DTMF_TONE = 11; private static final int MSG_CONFERENCE = 12; @@ -147,7 +147,6 @@ public abstract class ConnectionService extends Service { } @Override - /** @hide */ public void answerVideo(String callId, int videoState) { SomeArgs args = SomeArgs.obtain(); args.arg1 = callId; @@ -181,11 +180,11 @@ public abstract class ConnectionService extends Service { } @Override - public void onAudioStateChanged(String callId, AudioState audioState) { + public void onCallAudioStateChanged(String callId, CallAudioState callAudioState) { SomeArgs args = SomeArgs.obtain(); args.arg1 = callId; - args.arg2 = audioState; - mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget(); + args.arg2 = callAudioState; + mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget(); } @Override @@ -305,12 +304,12 @@ public abstract class ConnectionService extends Service { case MSG_UNHOLD: unhold((String) msg.obj); break; - case MSG_ON_AUDIO_STATE_CHANGED: { + case MSG_ON_CALL_AUDIO_STATE_CHANGED: { SomeArgs args = (SomeArgs) msg.obj; try { String callId = (String) args.arg1; - AudioState audioState = (AudioState) args.arg2; - onAudioStateChanged(callId, audioState); + CallAudioState audioState = (CallAudioState) args.arg2; + onCallAudioStateChanged(callId, new CallAudioState(audioState)); } finally { args.recycle(); } @@ -689,12 +688,14 @@ public abstract class ConnectionService extends Service { } } - private void onAudioStateChanged(String callId, AudioState audioState) { - Log.d(this, "onAudioStateChanged %s %s", callId, audioState); + private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) { + Log.d(this, "onAudioStateChanged %s %s", callId, callAudioState); if (mConnectionById.containsKey(callId)) { - findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState); + findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState( + callAudioState); } else { - findConferenceForAction(callId, "onAudioStateChanged").setAudioState(audioState); + findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState( + callAudioState); } } diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java index fd0c06d..d3df151 100644 --- a/telecomm/java/android/telecom/DefaultDialerManager.java +++ b/telecomm/java/android/telecom/DefaultDialerManager.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.net.Uri; import android.provider.Settings; import android.text.TextUtils; @@ -151,14 +152,14 @@ public class DefaultDialerManager { for (ResolveInfo resolveInfo : resolveInfoList) { final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; + if (activityInfo != null && !packageNames.contains(activityInfo.packageName)) { + packageNames.add(activityInfo.packageName); } - packageNames.add(activityInfo.packageName); } - // TODO: Filter for apps that don't handle DIAL intent with tel scheme - return packageNames; + final Intent dialIntentWithTelScheme = new Intent(Intent.ACTION_DIAL); + dialIntentWithTelScheme.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, "", null)); + return filterByIntent(context, packageNames, dialIntentWithTelScheme); } /** @@ -182,6 +183,36 @@ public class DefaultDialerManager { || packageName.equals(tm.getSystemDialerPackage()); } + /** + * Filter a given list of package names for those packages that contain an activity that has + * an intent filter for a given intent. + * + * @param context A valid context + * @param packageNames List of package names to filter. + * @return The filtered list. + */ + private static List<String> filterByIntent(Context context, List<String> packageNames, + Intent intent) { + if (packageNames == null || packageNames.isEmpty()) { + return new ArrayList<>(); + } + + final List<String> result = new ArrayList<>(); + final List<ResolveInfo> resolveInfoList = + context.getPackageManager().queryIntentActivities(intent, 0); + final int length = resolveInfoList.size(); + for (int i = 0; i < length; i++) { + final ActivityInfo info = resolveInfoList.get(i).activityInfo; + if (info != null && packageNames.contains(info.packageName) + && !result.contains(info.packageName)) { + result.add(info.packageName); + } + } + + return result; + } + + private static TelecomManager getTelecomManager(Context context) { return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); } diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index 62b8dea..0cf7212 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -119,7 +119,7 @@ public final class InCallAdapter { } /** - * Sets the audio route (speaker, bluetooth, etc...). See {@link AudioState}. + * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}. * * @param route The audio route to use. */ diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index 3cb4e87..e37cff7 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -20,6 +20,7 @@ import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; +import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -51,7 +52,7 @@ public abstract class InCallService extends Service { private static final int MSG_ADD_CALL = 2; private static final int MSG_UPDATE_CALL = 3; private static final int MSG_SET_POST_DIAL_WAIT = 4; - private static final int MSG_ON_AUDIO_STATE_CHANGED = 5; + private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 5; private static final int MSG_BRING_TO_FOREGROUND = 6; private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7; @@ -86,8 +87,8 @@ public abstract class InCallService extends Service { } break; } - case MSG_ON_AUDIO_STATE_CHANGED: - mPhone.internalAudioStateChanged((AudioState) msg.obj); + case MSG_ON_CALL_AUDIO_STATE_CHANGED: + mPhone.internalCallAudioStateChanged((CallAudioState) msg.obj); break; case MSG_BRING_TO_FOREGROUND: mPhone.internalBringToForeground(msg.arg1 == 1); @@ -132,8 +133,8 @@ public abstract class InCallService extends Service { } @Override - public void onAudioStateChanged(AudioState audioState) { - mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget(); + public void onCallAudioStateChanged(CallAudioState callAudioState) { + mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, callAudioState).sendToTarget(); } @Override @@ -155,6 +156,10 @@ public abstract class InCallService extends Service { InCallService.this.onAudioStateChanged(audioState); } + public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { + InCallService.this.onCallAudioStateChanged(callAudioState); + }; + /** ${inheritDoc} */ @Override public void onBringToForeground(Phone phone, boolean showDialpad) { @@ -247,14 +252,27 @@ public abstract class InCallService extends Service { * * @return An object encapsulating the audio state. Returns null if the service is not * fully initialized. + * @deprecated Use {@link #getCallAudioState()} instead. + * @hide */ + @Deprecated public final AudioState getAudioState() { return mPhone == null ? null : mPhone.getAudioState(); } /** + * 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 CallAudioState getCallAudioState() { + return mPhone == null ? null : mPhone.getCallAudioState(); + } + + /** * Sets the microphone mute state. When this request is honored, there will be change to - * the {@link #getAudioState()}. + * the {@link #getCallAudioState()}. * * @param state {@code true} if the microphone should be muted; {@code false} otherwise. */ @@ -266,7 +284,7 @@ public abstract class InCallService extends Service { /** * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will - * be change to the {@link #getAudioState()}. + * be change to the {@link #getCallAudioState()}. * * @param route The audio route to use. */ @@ -310,11 +328,22 @@ public abstract class InCallService extends Service { * Called when the audio state changes. * * @param audioState The new {@link AudioState}. + * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState) instead}. + * @hide */ + @Deprecated public void onAudioStateChanged(AudioState audioState) { } /** + * Called when the audio state changes. + * + * @param audioState The new {@link CallAudioState}. + */ + public void onCallAudioStateChanged(CallAudioState 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. @@ -466,7 +495,7 @@ public abstract class InCallService extends Service { * * @param uri URI of image to display. */ - public abstract void setPauseImage(String uri); + public abstract void setPauseImage(Uri uri); /** * Callback class which invokes callbacks after video call actions occur. @@ -546,7 +575,8 @@ public abstract class InCallService extends Service { * * @param cameraCapabilities The changed camera capabilities. */ - public abstract void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities); + public abstract void onCameraCapabilitiesChanged( + VideoProfile.CameraCapabilities cameraCapabilities); } } } diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java index 1a30910..bb65ce9 100644 --- a/telecomm/java/android/telecom/ParcelableCall.java +++ b/telecomm/java/android/telecom/ParcelableCall.java @@ -178,10 +178,10 @@ public final class ParcelableCall implements Parcelable { * Returns an object for remotely communicating through the video call provider's binder. * @return The video call. */ - public InCallService.VideoCall getVideoCall() { + public InCallService.VideoCall getVideoCall(Call call) { if (mVideoCall == null && mVideoCallProvider != null) { try { - mVideoCall = new VideoCallImpl(mVideoCallProvider); + mVideoCall = new VideoCallImpl(mVideoCallProvider, call); } catch (RemoteException ignored) { // Ignore RemoteException. } diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java index 4cdfd2e..8eb091b 100644 --- a/telecomm/java/android/telecom/Phone.java +++ b/telecomm/java/android/telecom/Phone.java @@ -41,10 +41,21 @@ public final class Phone { * * @param phone The {@code Phone} calling this method. * @param audioState The new {@link AudioState}. + * + * @deprecated Use {@link #onCallAudioStateChanged(Phone, CallAudioState)} instead. */ + @Deprecated public void onAudioStateChanged(Phone phone, AudioState audioState) { } /** + * Called when the audio state changes. + * + * @param phone The {@code Phone} calling this method. + * @param callAudioState The new {@link CallAudioState}. + */ + public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { } + + /** * 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. @@ -100,7 +111,7 @@ public final class Phone { private final InCallAdapter mInCallAdapter; - private AudioState mAudioState; + private CallAudioState mCallAudioState; private final List<Listener> mListeners = new CopyOnWriteArrayList<>(); @@ -145,10 +156,10 @@ public final class Phone { } } - final void internalAudioStateChanged(AudioState audioState) { - if (!Objects.equals(mAudioState, audioState)) { - mAudioState = audioState; - fireAudioStateChanged(audioState); + final void internalCallAudioStateChanged(CallAudioState callAudioState) { + if (!Objects.equals(mCallAudioState, callAudioState)) { + mCallAudioState = callAudioState; + fireCallAudioStateChanged(callAudioState); } } @@ -271,9 +282,20 @@ public final class Phone { * Obtains the current phone call audio state of the {@code Phone}. * * @return An object encapsulating the audio state. + * @deprecated Use {@link #getCallAudioState()} instead. */ + @Deprecated public final AudioState getAudioState() { - return mAudioState; + return new AudioState(mCallAudioState); + } + + /** + * Obtains the current phone call audio state of the {@code Phone}. + * + * @return An object encapsulating the audio state. + */ + public final CallAudioState getCallAudioState() { + return mCallAudioState; } private void fireCallAdded(Call call) { @@ -288,9 +310,10 @@ public final class Phone { } } - private void fireAudioStateChanged(AudioState audioState) { + private void fireCallAudioStateChanged(CallAudioState audioState) { for (Listener listener : mListeners) { - listener.onAudioStateChanged(this, audioState); + listener.onCallAudioStateChanged(this, audioState); + listener.onAudioStateChanged(this, new AudioState(audioState)); } } diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index bab460d..f05a1ef 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -26,6 +26,7 @@ import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -47,7 +48,7 @@ import java.util.MissingResourceException; * should supply a valid {@link PhoneAccountHandle} that references the connection service * implementation Telecom will use to interact with the app. */ -public class PhoneAccount implements Parcelable { +public final class PhoneAccount implements Parcelable { /** * Flag indicating that this {@code PhoneAccount} can act as a connection manager for @@ -127,6 +128,7 @@ public class PhoneAccount implements Parcelable { /** * Indicating no icon tint is set. + * @hide */ public static final int NO_ICON_TINT = 0; @@ -144,14 +146,11 @@ public class PhoneAccount implements Parcelable { private final Uri mAddress; private final Uri mSubscriptionAddress; private final int mCapabilities; - private final int mIconResId; - private final String mIconPackageName; - private final Bitmap mIconBitmap; - private final int mIconTint; private final int mHighlightColor; private final CharSequence mLabel; private final CharSequence mShortDescription; private final List<String> mSupportedUriSchemes; + private final Icon mIcon; /** * Helper class for creating a {@link PhoneAccount}. @@ -161,14 +160,11 @@ public class PhoneAccount implements Parcelable { private Uri mAddress; private Uri mSubscriptionAddress; private int mCapabilities; - private int mIconResId; - private String mIconPackageName; - private Bitmap mIconBitmap; - private int mIconTint = NO_ICON_TINT; private int mHighlightColor = NO_HIGHLIGHT_COLOR; private CharSequence mLabel; private CharSequence mShortDescription; private List<String> mSupportedUriSchemes = new ArrayList<String>(); + private Icon mIcon; /** * Creates a builder with the specified {@link PhoneAccountHandle} and label. @@ -189,14 +185,11 @@ public class PhoneAccount implements Parcelable { mAddress = phoneAccount.getAddress(); mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); mCapabilities = phoneAccount.getCapabilities(); - mIconResId = phoneAccount.getIconResId(); - mIconPackageName = phoneAccount.getIconPackageName(); - mIconBitmap = phoneAccount.getIconBitmap(); - mIconTint = phoneAccount.getIconTint(); mHighlightColor = phoneAccount.getHighlightColor(); mLabel = phoneAccount.getLabel(); mShortDescription = phoneAccount.getShortDescription(); mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); + mIcon = phoneAccount.getIcon(); } /** @@ -233,65 +226,12 @@ public class PhoneAccount implements Parcelable { } /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param packageContext The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @return The builder. - */ - public Builder setIcon(Context packageContext, int iconResId) { - return setIcon(packageContext.getPackageName(), iconResId); - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param iconPackageName The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @return The builder. - */ - public Builder setIcon(String iconPackageName, int iconResId) { - return setIcon(iconPackageName, iconResId, NO_ICON_TINT); - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. + * Sets the icon. See {@link PhoneAccount#getIcon}. * - * @param packageContext The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @param iconTint A color with which to tint this icon. - * @return The builder. + * @param icon The icon to set. */ - public Builder setIcon(Context packageContext, int iconResId, int iconTint) { - return setIcon(packageContext.getPackageName(), iconResId, iconTint); - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param iconPackageName The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @param iconTint A color with which to tint this icon. - * @return The builder. - */ - public Builder setIcon(String iconPackageName, int iconResId, int iconTint) { - this.mIconPackageName = iconPackageName; - this.mIconResId = iconResId; - this.mIconTint = iconTint; - return this; - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param iconBitmap The icon bitmap. - * @return The builder. - */ - public Builder setIcon(Bitmap iconBitmap) { - this.mIconBitmap = iconBitmap; - this.mIconPackageName = null; - this.mIconResId = NO_RESOURCE_ID; - this.mIconTint = NO_ICON_TINT; + public Builder setIcon(Icon icon) { + mIcon = icon; return this; } @@ -363,10 +303,7 @@ public class PhoneAccount implements Parcelable { mAddress, mSubscriptionAddress, mCapabilities, - mIconResId, - mIconPackageName, - mIconBitmap, - mIconTint, + mIcon, mHighlightColor, mLabel, mShortDescription, @@ -379,10 +316,7 @@ public class PhoneAccount implements Parcelable { Uri address, Uri subscriptionAddress, int capabilities, - int iconResId, - String iconPackageName, - Bitmap iconBitmap, - int iconTint, + Icon icon, int highlightColor, CharSequence label, CharSequence shortDescription, @@ -391,10 +325,7 @@ public class PhoneAccount implements Parcelable { mAddress = address; mSubscriptionAddress = subscriptionAddress; mCapabilities = capabilities; - mIconResId = iconResId; - mIconPackageName = iconPackageName; - mIconBitmap = iconBitmap; - mIconTint = iconTint; + mIcon = icon; mHighlightColor = highlightColor; mLabel = label; mShortDescription = shortDescription; @@ -497,6 +428,15 @@ public class PhoneAccount implements Parcelable { } /** + * The icon to represent this {@code PhoneAccount}. + * + * @return The icon. + */ + public Icon getIcon() { + return mIcon; + } + + /** * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI * scheme. * @@ -518,59 +458,6 @@ public class PhoneAccount implements Parcelable { } /** - * The icon resource ID for the icon of this {@code PhoneAccount}. - * <p> - * Creators of a {@code PhoneAccount} who possess the icon in static resources should prefer - * this method of indicating the icon rather than using {@link #getIconBitmap()}, since it - * leads to less resource usage. - * <p> - * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}. - * - * @return A resource ID. - */ - public int getIconResId() { - return mIconResId; - } - - /** - * The package name from which to load the icon of this {@code PhoneAccount}. - * <p> - * If this property is {@code null}, the resource {@link #getIconResId()} will be loaded from - * the package in the {@link ComponentName} of the {@link #getAccountHandle()}. - * <p> - * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}. - * - * @return A package name. - */ - public String getIconPackageName() { - return mIconPackageName; - } - - /** - * A tint to apply to the icon of this {@code PhoneAccount}. - * - * @return A hexadecimal color value. - */ - public int getIconTint() { - return mIconTint; - } - - /** - * A literal icon bitmap to represent this {@code PhoneAccount} in a user interface. - * <p> - * If this property is specified, it is to be considered the preferred icon. Otherwise, the - * resource specified by {@link #getIconResId()} should be used. - * <p> - * Clients wishing to display a {@code PhoneAccount} should use - * {@link #createIconDrawable(Context)}. - * - * @return A bitmap. - */ - public Bitmap getIconBitmap() { - return mIconBitmap; - } - - /** * A highlight color to use in displaying information about this {@code PhoneAccount}. * * @return A hexadecimal color value. @@ -579,41 +466,6 @@ public class PhoneAccount implements Parcelable { return mHighlightColor; } - /** - * Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user - * interface. Uses the properties {@link #getIconResId()}, {@link #getIconPackageName()}, and - * {@link #getIconBitmap()} as necessary. - * - * @param context A {@code Context} to use for loading {@code Drawable}s. - * - * @return An icon for this {@code PhoneAccount}. - */ - public Drawable createIconDrawable(Context context) { - if (mIconBitmap != null) { - return new BitmapDrawable(context.getResources(), mIconBitmap); - } - - if (mIconResId != 0) { - try { - Context packageContext = context.createPackageContext(mIconPackageName, 0); - try { - Drawable iconDrawable = packageContext.getDrawable(mIconResId); - if (mIconTint != NO_ICON_TINT) { - iconDrawable.setTint(mIconTint); - } - return iconDrawable; - } catch (NotFoundException | MissingResourceException e) { - Log.e(this, e, "Cannot find icon %d in package %s", - mIconResId, mIconPackageName); - } - } catch (PackageManager.NameNotFoundException e) { - Log.w(this, "Cannot find package %s", mIconPackageName); - } - } - - return new ColorDrawable(Color.TRANSPARENT); - } - // // Parcelable implementation // @@ -644,19 +496,16 @@ public class PhoneAccount implements Parcelable { mSubscriptionAddress.writeToParcel(out, flags); } out.writeInt(mCapabilities); - out.writeInt(mIconResId); - out.writeString(mIconPackageName); - if (mIconBitmap == null) { - out.writeInt(0); - } else { - out.writeInt(1); - mIconBitmap.writeToParcel(out, flags); - } - out.writeInt(mIconTint); out.writeInt(mHighlightColor); out.writeCharSequence(mLabel); out.writeCharSequence(mShortDescription); out.writeStringList(mSupportedUriSchemes); + if (mIcon == null) { + out.writeInt(0); + } else { + out.writeInt(1); + mIcon.writeToParcel(out, flags); + } } public static final Creator<PhoneAccount> CREATOR @@ -689,18 +538,15 @@ public class PhoneAccount implements Parcelable { mSubscriptionAddress = null; } mCapabilities = in.readInt(); - mIconResId = in.readInt(); - mIconPackageName = in.readString(); - if (in.readInt() > 0) { - mIconBitmap = Bitmap.CREATOR.createFromParcel(in); - } else { - mIconBitmap = null; - } - mIconTint = in.readInt(); mHighlightColor = in.readInt(); mLabel = in.readCharSequence(); mShortDescription = in.readCharSequence(); mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList()); + if (in.readInt() > 0) { + mIcon = Icon.CREATOR.createFromParcel(in); + } else { + mIcon = null; + } } @Override diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java index 60917b2..6dc6e9c 100644 --- a/telecomm/java/android/telecom/PhoneAccountHandle.java +++ b/telecomm/java/android/telecom/PhoneAccountHandle.java @@ -35,7 +35,7 @@ import java.util.Objects; * * See {@link PhoneAccount}, {@link TelecomManager}. */ -public class PhoneAccountHandle implements Parcelable { +public final class PhoneAccountHandle implements Parcelable { private final ComponentName mComponentName; private final String mId; private final UserHandle mUserHandle; diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java index a76bf59..095a88f 100644 --- a/telecomm/java/android/telecom/RemoteConference.java +++ b/telecomm/java/android/telecom/RemoteConference.java @@ -18,6 +18,7 @@ package android.telecom; import com.android.internal.telecom.IConnectionService; +import android.annotation.SystemApi; import android.os.Handler; import android.os.RemoteException; @@ -29,7 +30,10 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; /** - * Represents a conference call which can contain any number of {@link Connection} objects. + * A conference provided to a {@link ConnectionService} by another {@code ConnectionService} + * running in a different process. + * + * @see ConnectionService#onRemoteConferenceAdded */ public final class RemoteConference { @@ -62,18 +66,18 @@ public final class RemoteConference { private DisconnectCause mDisconnectCause; private int mConnectionCapabilities; - /** {@hide} */ + /** @hide */ RemoteConference(String id, IConnectionService connectionService) { mId = id; mConnectionService = connectionService; } - /** {@hide} */ + /** @hide */ String getId() { return mId; } - /** {@hide} */ + /** @hide */ void setDestroyed() { for (RemoteConnection connection : mChildConnections) { connection.setConference(null); @@ -90,7 +94,7 @@ public final class RemoteConference { } } - /** {@hide} */ + /** @hide */ void setState(final int newState) { if (newState != Connection.STATE_ACTIVE && newState != Connection.STATE_HOLDING && @@ -116,7 +120,7 @@ public final class RemoteConference { } } - /** {@hide} */ + /** @hide */ void addConnection(final RemoteConnection connection) { if (!mChildConnections.contains(connection)) { mChildConnections.add(connection); @@ -134,7 +138,7 @@ public final class RemoteConference { } } - /** {@hide} */ + /** @hide */ void removeConnection(final RemoteConnection connection) { if (mChildConnections.contains(connection)) { mChildConnections.remove(connection); @@ -152,7 +156,7 @@ public final class RemoteConference { } } - /** {@hide} */ + /** @hide */ void setConnectionCapabilities(final int connectionCapabilities) { if (mConnectionCapabilities != connectionCapabilities) { mConnectionCapabilities = connectionCapabilities; @@ -187,7 +191,7 @@ public final class RemoteConference { } } - /** {@hide} */ + /** @hide */ void setDisconnected(final DisconnectCause disconnectCause) { if (mState != Connection.STATE_DISCONNECTED) { mDisconnectCause = disconnectCause; @@ -205,18 +209,37 @@ public final class RemoteConference { } } + /** + * Returns the list of {@link RemoteConnection}s contained in this conference. + * + * @return A list of child connections. + */ public final List<RemoteConnection> getConnections() { return mUnmodifiableChildConnections; } + /** + * Gets the state of the conference call. See {@link Connection} for valid values. + * + * @return A constant representing the state the conference call is currently in. + */ public final int getState() { return mState; } + /** + * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class + * {@link Connection} for valid values. + * + * @return A bitmask of the capabilities of the conference call. + */ public final int getConnectionCapabilities() { return mConnectionCapabilities; } + /** + * Disconnects the conference call as well as the child {@link RemoteConnection}s. + */ public void disconnect() { try { mConnectionService.disconnect(mId); @@ -224,6 +247,13 @@ public final class RemoteConference { } } + /** + * Removes the specified {@link RemoteConnection} from the conference. This causes the + * {@link RemoteConnection} to become a standalone connection. This is a no-op if the + * {@link RemoteConnection} does not belong to this conference. + * + * @param connection The remote-connection to remove. + */ public void separate(RemoteConnection connection) { if (mChildConnections.contains(connection)) { try { @@ -233,6 +263,16 @@ public final class RemoteConference { } } + /** + * Merges all {@link RemoteConnection}s of this conference into a single call. This should be + * invoked only if the conference contains the capability + * {@link Connection#CAPABILITY_MERGE_CONFERENCE}, otherwise it is a no-op. The presence of said + * capability indicates that the connections of this conference, despite being part of the + * same conference object, are yet to have their audio streams merged; this is a common pattern + * for CDMA conference calls, but the capability is not used for GSM and SIP conference calls. + * Invoking this method will cause the unmerged child connections to merge their audio + * streams. + */ public void merge() { try { mConnectionService.mergeConference(mId); @@ -240,6 +280,15 @@ public final class RemoteConference { } } + /** + * Swaps the active audio stream between the conference's child {@link RemoteConnection}s. + * This should be invoked only if the conference contains the capability + * {@link Connection#CAPABILITY_SWAP_CONFERENCE}, otherwise it is a no-op. This is only used by + * {@link ConnectionService}s that create conferences for connections that do not yet have + * their audio streams merged; this is a common pattern for CDMA conference calls, but the + * capability is not used for GSM and SIP conference calls. Invoking this method will change the + * active audio stream to a different child connection. + */ public void swap() { try { mConnectionService.swapConference(mId); @@ -247,6 +296,9 @@ public final class RemoteConference { } } + /** + * Puts the conference on hold. + */ public void hold() { try { mConnectionService.hold(mId); @@ -254,6 +306,9 @@ public final class RemoteConference { } } + /** + * Unholds the conference call. + */ public void unhold() { try { mConnectionService.unhold(mId); @@ -261,10 +316,22 @@ public final class RemoteConference { } } + /** + * Returns the {@link DisconnectCause} for the conference if it is in the state + * {@link Connection#STATE_DISCONNECTED}. If the conference is not disconnected, this will + * return null. + * + * @return The disconnect cause. + */ public DisconnectCause getDisconnectCause() { return mDisconnectCause; } + /** + * Requests that the conference start playing the specified DTMF tone. + * + * @param digit The digit for which to play a DTMF tone. + */ public void playDtmfTone(char digit) { try { mConnectionService.playDtmfTone(mId, digit); @@ -272,6 +339,11 @@ public final class RemoteConference { } } + /** + * Stops the most recent request to play a DTMF tone. + * + * @see #playDtmfTone + */ public void stopDtmfTone() { try { mConnectionService.stopDtmfTone(mId); @@ -279,21 +351,57 @@ public final class RemoteConference { } } + /** + * Request to change the conference's audio routing to the specified state. The specified state + * can include audio routing (Bluetooth, Speaker, etc) and muting state. + * + * @see android.telecom.AudioState + * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead. + * @hide + */ + @SystemApi + @Deprecated public void setAudioState(AudioState state) { + setCallAudioState(new CallAudioState(state)); + } + + /** + * Request to change the conference's audio routing to the specified state. The specified state + * can include audio routing (Bluetooth, Speaker, etc) and muting state. + */ + public void setCallAudioState(CallAudioState state) { try { - mConnectionService.onAudioStateChanged(mId, state); + mConnectionService.onCallAudioStateChanged(mId, state); } catch (RemoteException e) { } } + + /** + * Returns a list of independent connections that can me merged with this conference. + * + * @return A list of conferenceable connections. + */ public List<RemoteConnection> getConferenceableConnections() { return mUnmodifiableConferenceableConnections; } + /** + * Register a callback through which to receive state updates for this conference. + * + * @param callback The callback to notify of state changes. + */ public final void registerCallback(Callback callback) { registerCallback(callback, new Handler()); } + /** + * Registers a callback through which to receive state updates for this conference. + * Callbacks will be notified using the specified handler, if provided. + * + * @param callback The callback to notify of state changes. + * @param handler The handler on which to execute the callbacks. + */ public final void registerCallback(Callback callback, Handler handler) { unregisterCallback(callback); if (callback != null && handler != null) { @@ -301,6 +409,13 @@ public final class RemoteConference { } } + /** + * Unregisters a previously registered callback. + * + * @see #registerCallback + * + * @param callback The callback to unregister. + */ public final void unregisterCallback(Callback callback) { if (callback != null) { for (CallbackRecord<Callback> record : mCallbackRecords) { diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java index 1493b20..08485a3 100644 --- a/telecomm/java/android/telecom/RemoteConnection.java +++ b/telecomm/java/android/telecom/RemoteConnection.java @@ -20,6 +20,7 @@ import com.android.internal.telecom.IConnectionService; import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Handler; import android.os.IBinder; @@ -220,7 +221,7 @@ public final class RemoteConnection { public void onCameraCapabilitiesChanged( VideoProvider videoProvider, - CameraCapabilities cameraCapabilities) {} + VideoProfile.CameraCapabilities cameraCapabilities) {} public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {} } @@ -267,7 +268,8 @@ public final class RemoteConnection { } @Override - public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { + public void changeCameraCapabilities( + VideoProfile.CameraCapabilities cameraCapabilities) { for (Listener l : mListeners) { l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities); } @@ -350,9 +352,9 @@ public final class RemoteConnection { } } - public void sendSessionModifyRequest(VideoProfile reqProfile) { + public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) { try { - mVideoProviderBinder.sendSessionModifyRequest(reqProfile); + mVideoProviderBinder.sendSessionModifyRequest(fromProfile, toProfile); } catch (RemoteException e) { } } @@ -378,7 +380,7 @@ public final class RemoteConnection { } } - public void setPauseImage(String uri) { + public void setPauseImage(Uri uri) { try { mVideoProviderBinder.setPauseImage(uri); } catch (RemoteException e) { @@ -775,11 +777,24 @@ public final class RemoteConnection { * Set the audio state of this {@code RemoteConnection}. * * @param state The audio state of this {@code RemoteConnection}. + * @hide + * @deprecated Use {@link #setCallAudioState(CallAudioState) instead. */ + @SystemApi + @Deprecated public void setAudioState(AudioState state) { + setCallAudioState(new CallAudioState(state)); + } + + /** + * Set the audio state of this {@code RemoteConnection}. + * + * @param state The audio state of this {@code RemoteConnection}. + */ + public void setCallAudioState(CallAudioState state) { try { if (mConnected) { - mConnectionService.onAudioStateChanged(mConnectionId, state); + mConnectionService.onCallAudioStateChanged(mConnectionId, state); } } catch (RemoteException ignored) { } diff --git a/telecomm/java/android/telecom/StatusHints.java b/telecomm/java/android/telecom/StatusHints.java index a32eae7..99c8d7f 100644 --- a/telecomm/java/android/telecom/StatusHints.java +++ b/telecomm/java/android/telecom/StatusHints.java @@ -16,15 +16,15 @@ package android.telecom; +import android.annotation.SystemApi; import android.content.ComponentName; import android.content.Context; -import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import java.util.MissingResourceException; import java.util.Objects; /** @@ -32,24 +32,34 @@ import java.util.Objects; */ public final class StatusHints implements Parcelable { - private final ComponentName mPackageName; private final CharSequence mLabel; - private final int mIconResId; + private final Icon mIcon; private final Bundle mExtras; + /** + * @hide + */ + @SystemApi @Deprecated public StatusHints(ComponentName packageName, CharSequence label, int iconResId, Bundle extras) { - mPackageName = packageName; + this(label, Icon.createWithResource(packageName.getPackageName(), iconResId), extras); + } + + public StatusHints(CharSequence label, Icon icon, Bundle extras) { mLabel = label; - mIconResId = iconResId; + mIcon = icon; mExtras = extras; } /** * @return A package used to load the icon. + * + * @hide */ + @SystemApi @Deprecated public ComponentName getPackageName() { - return mPackageName; + // Minimal compatibility shim for legacy apps' tests + return new ComponentName("", ""); } /** @@ -63,16 +73,30 @@ public final class StatusHints implements Parcelable { * The icon resource ID for the icon to show. * * @return A resource ID. + * + * @hide */ + @SystemApi @Deprecated public int getIconResId() { - return mIconResId; + // Minimal compatibility shim for legacy apps' tests + return 0; } /** * @return An icon displayed in the in-call UI. + * + * @hide */ + @SystemApi @Deprecated public Drawable getIcon(Context context) { - return getIcon(context, mIconResId); + return mIcon.loadDrawable(context); + } + + /** + * @return An icon depicting the status. + */ + public Icon getIcon() { + return mIcon; } /** @@ -89,9 +113,8 @@ public final class StatusHints implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { - out.writeParcelable(mPackageName, flags); out.writeCharSequence(mLabel); - out.writeInt(mIconResId); + out.writeParcelable(mIcon, 0); out.writeParcelable(mExtras, 0); } @@ -107,36 +130,17 @@ public final class StatusHints implements Parcelable { }; private StatusHints(Parcel in) { - mPackageName = in.readParcelable(getClass().getClassLoader()); mLabel = in.readCharSequence(); - mIconResId = in.readInt(); + mIcon = in.readParcelable(getClass().getClassLoader()); mExtras = in.readParcelable(getClass().getClassLoader()); } - private Drawable getIcon(Context context, int resId) { - Context packageContext; - try { - packageContext = context.createPackageContext(mPackageName.getPackageName(), 0); - } catch (PackageManager.NameNotFoundException e) { - Log.e(this, e, "Cannot find package %s", mPackageName.getPackageName()); - return null; - } - try { - return packageContext.getDrawable(resId); - } catch (MissingResourceException e) { - Log.e(this, e, "Cannot find icon %d in package %s", - resId, mPackageName.getPackageName()); - return null; - } - } - @Override public boolean equals(Object other) { if (other != null && other instanceof StatusHints) { StatusHints otherHints = (StatusHints) other; - return Objects.equals(otherHints.getPackageName(), getPackageName()) && - Objects.equals(otherHints.getLabel(), getLabel()) && - otherHints.getIconResId() == getIconResId() && + return Objects.equals(otherHints.getLabel(), getLabel()) && + Objects.equals(otherHints.getIcon(), getIcon()) && Objects.equals(otherHints.getExtras(), getExtras()); } return false; @@ -144,7 +148,6 @@ public final class StatusHints implements Parcelable { @Override public int hashCode() { - return Objects.hashCode(mPackageName) + Objects.hashCode(mLabel) + mIconResId + - Objects.hashCode(mExtras); + return Objects.hashCode(mLabel) + Objects.hashCode(mIcon) + Objects.hashCode(mExtras); } } diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 1431eb8..c8ed2b0 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -142,10 +142,10 @@ public class TelecomManager { * Optional extra for {@link android.content.Intent#ACTION_CALL} containing an integer that * determines the desired video state for an outgoing call. * Valid options: - * {@link VideoProfile.VideoState#AUDIO_ONLY}, - * {@link VideoProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoProfile.VideoState#RX_ENABLED}, - * {@link VideoProfile.VideoState#TX_ENABLED}. + * {@link VideoProfile#STATE_AUDIO_ONLY}, + * {@link VideoProfile#STATE_BIDIRECTIONAL}, + * {@link VideoProfile#STATE_RX_ENABLED}, + * {@link VideoProfile#STATE_TX_ENABLED}. */ public static final String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE"; @@ -333,16 +333,24 @@ public class TelecomManager { * displayed to the user. */ - /** Property is displayed normally. */ + /** + * Indicates that the address or number of a call is allowed to be displayed for caller ID. + */ public static final int PRESENTATION_ALLOWED = 1; - /** Property was blocked. */ + /** + * Indicates that the address or number of a call is blocked by the other party. + */ public static final int PRESENTATION_RESTRICTED = 2; - /** Presentation was not specified or is unknown. */ + /** + * Indicates that the address or number of a call is not specified or known by the carrier. + */ public static final int PRESENTATION_UNKNOWN = 3; - /** Property should be displayed as a pay phone. */ + /** + * Indicates that the address or number of a call belongs to a pay phone. + */ public static final int PRESENTATION_PAYPHONE = 4; private static final String TAG = "TelecomManager"; @@ -1143,8 +1151,12 @@ public class TelecomManager { public void placeCall(Uri address, Bundle extras) { ITelecomService service = getTelecomService(); if (service != null) { + if (address == null) { + Log.w(TAG, "Cannot place call to empty address."); + } try { - service.placeCall(address, extras, mContext.getOpPackageName()); + service.placeCall(address, extras == null ? new Bundle() : extras, + mContext.getOpPackageName()); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecomService#placeCall", e); } diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java index 7a82c1b..c8072d1 100644 --- a/telecomm/java/android/telecom/VideoCallImpl.java +++ b/telecomm/java/android/telecom/VideoCallImpl.java @@ -16,6 +16,7 @@ package android.telecom; +import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -40,6 +41,8 @@ public class VideoCallImpl extends VideoCall { private final IVideoProvider mVideoProvider; private final VideoCallListenerBinder mBinder; private VideoCall.Callback mCallback; + private int mVideoQuality = VideoProfile.QUALITY_UNKNOWN; + private Call mCall; private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { @Override @@ -96,7 +99,7 @@ public class VideoCallImpl extends VideoCall { } @Override - public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { + public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) { mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities).sendToTarget(); } @@ -158,9 +161,10 @@ public class VideoCallImpl extends VideoCall { break; case MSG_CHANGE_CAMERA_CAPABILITIES: mCallback.onCameraCapabilitiesChanged( - (CameraCapabilities) msg.obj); + (VideoProfile.CameraCapabilities) msg.obj); break; case MSG_CHANGE_VIDEO_QUALITY: + mVideoQuality = msg.arg1; mCallback.onVideoQualityChanged(msg.arg1); break; default: @@ -171,12 +175,13 @@ public class VideoCallImpl extends VideoCall { private Handler mHandler; - VideoCallImpl(IVideoProvider videoProvider) throws RemoteException { + VideoCallImpl(IVideoProvider videoProvider, Call call) throws RemoteException { mVideoProvider = videoProvider; mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0); mBinder = new VideoCallListenerBinder(); mVideoProvider.addVideoCallback(mBinder); + mCall = call; } public void destroy() { @@ -251,10 +256,24 @@ public class VideoCallImpl extends VideoCall { } } - /** {@inheritDoc} */ + /** + * Sends a session modification request to the video provider. + * <p> + * The {@link InCallService} will create the {@code requestProfile} based on the current + * video state (i.e. {@link Call.Details#getVideoState()}). It is, however, possible that the + * video state maintained by the {@link InCallService} could get out of sync with what is known + * by the {@link android.telecom.Connection.VideoProvider}. To remove ambiguity, the + * {@link VideoCallImpl} passes along the pre-modify video profile to the {@code VideoProvider} + * to ensure it has full context of the requested change. + * + * @param requestProfile The requested video profile. + */ public void sendSessionModifyRequest(VideoProfile requestProfile) { try { - mVideoProvider.sendSessionModifyRequest(requestProfile); + VideoProfile originalProfile = new VideoProfile(mCall.getDetails().getVideoState(), + mVideoQuality); + + mVideoProvider.sendSessionModifyRequest(originalProfile, requestProfile); } catch (RemoteException e) { } } @@ -284,7 +303,7 @@ public class VideoCallImpl extends VideoCall { } /** {@inheritDoc} */ - public void setPauseImage(String uri) { + public void setPauseImage(Uri uri) { try { mVideoProvider.setPauseImage(uri); } catch (RemoteException e) { diff --git a/telecomm/java/android/telecom/VideoCallbackServant.java b/telecomm/java/android/telecom/VideoCallbackServant.java index 1123621..1fbad22 100644 --- a/telecomm/java/android/telecom/VideoCallbackServant.java +++ b/telecomm/java/android/telecom/VideoCallbackServant.java @@ -98,7 +98,7 @@ final class VideoCallbackServant { break; } case MSG_CHANGE_CAMERA_CAPABILITIES: { - mDelegate.changeCameraCapabilities((CameraCapabilities) msg.obj); + mDelegate.changeCameraCapabilities((VideoProfile.CameraCapabilities) msg.obj); break; } case MSG_CHANGE_VIDEO_QUALITY: { @@ -148,7 +148,8 @@ final class VideoCallbackServant { } @Override - public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) + public void changeCameraCapabilities( + VideoProfile.CameraCapabilities cameraCapabilities) throws RemoteException { mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities) .sendToTarget(); diff --git a/telecomm/java/android/telecom/VideoProfile.aidl b/telecomm/java/android/telecom/VideoProfile.aidl index 091b569..0b32721 100644 --- a/telecomm/java/android/telecom/VideoProfile.aidl +++ b/telecomm/java/android/telecom/VideoProfile.aidl @@ -21,3 +21,4 @@ package android.telecom; * {@hide} */ parcelable VideoProfile; +parcelable VideoProfile.CameraCapabilities; diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java index 902fddb..71de505 100644 --- a/telecomm/java/android/telecom/VideoProfile.java +++ b/telecomm/java/android/telecom/VideoProfile.java @@ -48,6 +48,31 @@ public class VideoProfile implements Parcelable { */ public static final int QUALITY_DEFAULT = 4; + /** + * Call is currently in an audio-only mode with no video transmission or receipt. + */ + public static final int STATE_AUDIO_ONLY = 0x0; + + /** + * Video transmission is enabled. + */ + public static final int STATE_TX_ENABLED = 0x1; + + /** + * Video reception is enabled. + */ + public static final int STATE_RX_ENABLED = 0x2; + + /** + * Video signal is bi-directional. + */ + public static final int STATE_BIDIRECTIONAL = STATE_TX_ENABLED | STATE_RX_ENABLED; + + /** + * Video is paused. + */ + public static final int STATE_PAUSED = 0x4; + private final int mVideoState; private final int mQuality; @@ -74,11 +99,11 @@ public class VideoProfile implements Parcelable { /** * The video state of the call. - * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, - * {@link VideoProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoProfile.VideoState#TX_ENABLED}, - * {@link VideoProfile.VideoState#RX_ENABLED}, - * {@link VideoProfile.VideoState#PAUSED}. + * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, + * {@link VideoProfile#STATE_BIDIRECTIONAL}, + * {@link VideoProfile#STATE_TX_ENABLED}, + * {@link VideoProfile#STATE_RX_ENABLED}, + * {@link VideoProfile#STATE_PAUSED}. */ public int getVideoState() { return mVideoState; @@ -162,28 +187,41 @@ public class VideoProfile implements Parcelable { public static class VideoState { /** * Call is currently in an audio-only mode with no video transmission or receipt. + * @deprecated Use {@link VideoProfile#STATE_AUDIO_ONLY} instead + * @hide */ - public static final int AUDIO_ONLY = 0x0; + public static final int AUDIO_ONLY = VideoProfile.STATE_AUDIO_ONLY; /** * Video transmission is enabled. + * @deprecated Use {@link VideoProfile#STATE_TX_ENABLED} instead + * @hide */ - public static final int TX_ENABLED = 0x1; + public static final int TX_ENABLED = VideoProfile.STATE_TX_ENABLED; /** * Video reception is enabled. + * @deprecated Use {@link VideoProfile#STATE_RX_ENABLED} instead + * @hide */ - public static final int RX_ENABLED = 0x2; + public static final int RX_ENABLED = VideoProfile.STATE_RX_ENABLED; /** * Video signal is bi-directional. + * @deprecated Use {@link VideoProfile#STATE_BIDIRECTIONAL} instead + * @hide */ - public static final int BIDIRECTIONAL = TX_ENABLED | RX_ENABLED; + public static final int BIDIRECTIONAL = VideoProfile.STATE_BIDIRECTIONAL; /** * Video is paused. + * @deprecated Use {@link VideoProfile#STATE_PAUSED} instead + * @hide */ - public static final int PAUSED = 0x4; + public static final int PAUSED = VideoProfile.STATE_PAUSED; + + /** @hide */ + private VideoState() {} /** * Whether the video state is audio only. @@ -191,7 +229,8 @@ public class VideoProfile implements Parcelable { * @return Returns true if the video state is audio only. */ public static boolean isAudioOnly(int videoState) { - return !hasState(videoState, TX_ENABLED) && !hasState(videoState, RX_ENABLED); + return !hasState(videoState, VideoProfile.STATE_TX_ENABLED) + && !hasState(videoState, VideoProfile.STATE_RX_ENABLED); } /** @@ -201,8 +240,9 @@ public class VideoProfile implements Parcelable { * @return Returns true if the video state TX or RX or Bidirectional */ public static boolean isVideo(int videoState) { - return hasState(videoState, TX_ENABLED) || hasState(videoState, RX_ENABLED) - || hasState(videoState, BIDIRECTIONAL); + return hasState(videoState, VideoProfile.STATE_TX_ENABLED) + || hasState(videoState, VideoProfile.STATE_RX_ENABLED) + || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL); } /** @@ -211,7 +251,7 @@ public class VideoProfile implements Parcelable { * @return Returns true if the video transmission is enabled. */ public static boolean isTransmissionEnabled(int videoState) { - return hasState(videoState, TX_ENABLED); + return hasState(videoState, VideoProfile.STATE_TX_ENABLED); } /** @@ -220,7 +260,7 @@ public class VideoProfile implements Parcelable { * @return Returns true if the video transmission is enabled. */ public static boolean isReceptionEnabled(int videoState) { - return hasState(videoState, RX_ENABLED); + return hasState(videoState, VideoProfile.STATE_RX_ENABLED); } /** @@ -229,7 +269,7 @@ public class VideoProfile implements Parcelable { * @return Returns true if the video signal is bi-directional. */ public static boolean isBidirectional(int videoState) { - return hasState(videoState, BIDIRECTIONAL); + return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL); } /** @@ -238,7 +278,7 @@ public class VideoProfile implements Parcelable { * @return Returns true if the video is paused. */ public static boolean isPaused(int videoState) { - return hasState(videoState, PAUSED); + return hasState(videoState, VideoProfile.STATE_PAUSED); } /** @@ -278,4 +318,142 @@ public class VideoProfile implements Parcelable { return sb.toString(); } } + + /** + * Represents the camera capabilities important to a Video Telephony provider. + */ + public static final class CameraCapabilities implements Parcelable { + + /** + * The width of the camera video in pixels. + */ + private final int mWidth; + + /** + * The height of the camera video in pixels. + */ + private final int mHeight; + + /** + * Whether the camera supports zoom. + */ + private final boolean mZoomSupported; + + /** + * The maximum zoom supported by the camera. + */ + private final float mMaxZoom; + + /** + * Create a call camera capabilities instance. + * + * @param width The width of the camera video (in pixels). + * @param height The height of the camera video (in pixels). + */ + public CameraCapabilities(int width, int height) { + this(width, height, false, 1.0f); + } + + /** + * Create a call camera capabilities instance that optionally + * supports zoom. + * + * @param width The width of the camera video (in pixels). + * @param height The height of the camera video (in pixels). + * @param zoomSupported True when camera supports zoom. + * @param maxZoom Maximum zoom supported by camera. + * @hide + */ + public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) { + mWidth = width; + mHeight = height; + mZoomSupported = zoomSupported; + mMaxZoom = maxZoom; + } + + /** + * Responsible for creating CallCameraCapabilities objects from deserialized Parcels. + **/ + public static final Parcelable.Creator<CameraCapabilities> CREATOR = + new Parcelable.Creator<CameraCapabilities> () { + /** + * Creates a CallCameraCapabilities instances from a parcel. + * + * @param source The parcel. + * @return The CallCameraCapabilities. + */ + @Override + public CameraCapabilities createFromParcel(Parcel source) { + int width = source.readInt(); + int height = source.readInt(); + boolean supportsZoom = source.readByte() != 0; + float maxZoom = source.readFloat(); + + return new CameraCapabilities(width, height, supportsZoom, maxZoom); + } + + @Override + public CameraCapabilities[] newArray(int size) { + return new CameraCapabilities[size]; + } + }; + + /** + * Describe the kinds of special objects contained in this Parcelable's + * marshalled representation. + * + * @return a bitmask indicating the set of special object types marshalled + * by the Parcelable. + */ + @Override + public int describeContents() { + return 0; + } + + /** + * Flatten this object in to a Parcel. + * + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written. + * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}. + */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(getWidth()); + dest.writeInt(getHeight()); + dest.writeByte((byte) (isZoomSupported() ? 1 : 0)); + dest.writeFloat(getMaxZoom()); + } + + /** + * The width of the camera video in pixels. + */ + public int getWidth() { + return mWidth; + } + + /** + * The height of the camera video in pixels. + */ + public int getHeight() { + return mHeight; + } + + /** + * Whether the camera supports zoom. + * @hide + */ + public boolean isZoomSupported() { + return mZoomSupported; + } + + /** + * The maximum zoom supported by the camera. + * @hide + */ + public float getMaxZoom() { + return mMaxZoom; + } + } + } diff --git a/telecomm/java/android/telecom/Voicemail.java b/telecomm/java/android/telecom/Voicemail.java index f5b8052..151917e 100644 --- a/telecomm/java/android/telecom/Voicemail.java +++ b/telecomm/java/android/telecom/Voicemail.java @@ -28,6 +28,7 @@ import android.os.Parcelable; public class Voicemail implements Parcelable { private final Long mTimestamp; private final String mNumber; + private final PhoneAccountHandle mPhoneAccount; private final Long mId; private final Long mDuration; private final String mSource; @@ -36,10 +37,12 @@ public class Voicemail implements Parcelable { private final Boolean mIsRead; private final Boolean mHasContent; - private Voicemail(Long timestamp, String number, Long id, Long duration, String source, - String providerData, Uri uri, Boolean isRead, Boolean hasContent) { + private Voicemail(Long timestamp, String number, PhoneAccountHandle phoneAccountHandle, Long id, + Long duration, String source, String providerData, Uri uri, Boolean isRead, + Boolean hasContent) { mTimestamp = timestamp; mNumber = number; + mPhoneAccount = phoneAccountHandle; mId = id; mDuration = duration; mSource = source; @@ -77,6 +80,7 @@ public class Voicemail implements Parcelable { public static class Builder { private Long mBuilderTimestamp; private String mBuilderNumber; + private PhoneAccountHandle mBuilderPhoneAccount; private Long mBuilderId; private Long mBuilderDuration; private String mBuilderSourcePackage; @@ -99,6 +103,11 @@ public class Voicemail implements Parcelable { return this; } + public Builder setPhoneAccount(PhoneAccountHandle phoneAccount) { + mBuilderPhoneAccount = phoneAccount; + return this; + } + public Builder setId(long id) { mBuilderId = id; return this; @@ -139,9 +148,9 @@ public class Voicemail implements Parcelable { mBuilderTimestamp = mBuilderTimestamp == null ? 0 : mBuilderTimestamp; mBuilderDuration = mBuilderDuration == null ? 0: mBuilderDuration; mBuilderIsRead = mBuilderIsRead == null ? false : mBuilderIsRead; - return new Voicemail(mBuilderTimestamp, mBuilderNumber, mBuilderId, mBuilderDuration, - mBuilderSourcePackage, mBuilderSourceData, mBuilderUri, mBuilderIsRead, - mBuilderHasContent); + return new Voicemail(mBuilderTimestamp, mBuilderNumber, mBuilderPhoneAccount, + mBuilderId, mBuilderDuration, mBuilderSourcePackage, mBuilderSourceData, + mBuilderUri, mBuilderIsRead, mBuilderHasContent); } } @@ -161,6 +170,11 @@ public class Voicemail implements Parcelable { return mNumber; } + /** The phone account associated with the voicemail, null if not set. */ + public PhoneAccountHandle getPhoneAccount() { + return mPhoneAccount; + } + /** The timestamp the voicemail was received, in millis since the epoch, zero if not set. */ public long getTimestampMillis() { return mTimestamp; @@ -225,6 +239,12 @@ public class Voicemail implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeLong(mTimestamp); dest.writeCharSequence(mNumber); + if (mPhoneAccount == null) { + dest.writeInt(0); + } else { + dest.writeInt(1); + mPhoneAccount.writeToParcel(dest, flags); + } dest.writeLong(mId); dest.writeLong(mDuration); dest.writeCharSequence(mSource); @@ -263,6 +283,11 @@ public class Voicemail implements Parcelable { private Voicemail(Parcel in) { mTimestamp = in.readLong(); mNumber = (String) in.readCharSequence(); + if (in.readInt() > 0) { + mPhoneAccount = PhoneAccountHandle.CREATOR.createFromParcel(in); + } else { + mPhoneAccount = null; + } mId = in.readLong(); mDuration = in.readLong(); mSource = (String) in.readCharSequence(); diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl index 339a982..c2e8530 100644 --- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl +++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl @@ -17,7 +17,7 @@ package com.android.internal.telecom; import android.os.Bundle; -import android.telecom.AudioState; +import android.telecom.CallAudioState; import android.telecom.ConnectionRequest; import android.telecom.PhoneAccountHandle; @@ -56,7 +56,7 @@ oneway interface IConnectionService { void unhold(String callId); - void onAudioStateChanged(String activeCallId, in AudioState audioState); + void onCallAudioStateChanged(String activeCallId, in CallAudioState callAudioState); void playDtmfTone(String callId, char digit); diff --git a/telecomm/java/com/android/internal/telecom/IInCallService.aidl b/telecomm/java/com/android/internal/telecom/IInCallService.aidl index d26f6cb..ded47d5 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallService.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallService.aidl @@ -17,7 +17,7 @@ package com.android.internal.telecom; import android.app.PendingIntent; -import android.telecom.AudioState; +import android.telecom.CallAudioState; import android.telecom.ParcelableCall; import com.android.internal.telecom.IInCallAdapter; @@ -40,7 +40,7 @@ oneway interface IInCallService { void setPostDialWait(String callId, String remaining); - void onAudioStateChanged(in AudioState audioState); + void onCallAudioStateChanged(in CallAudioState callAudioState); void bringToForeground(boolean showDialpad); diff --git a/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl b/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl index 59f8f0c..cdfad02 100644 --- a/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl +++ b/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl @@ -16,7 +16,6 @@ package com.android.internal.telecom; -import android.telecom.CameraCapabilities; import android.telecom.VideoProfile; /** @@ -41,7 +40,7 @@ oneway interface IVideoCallback { void changeCallDataUsage(long dataUsage); - void changeCameraCapabilities(in CameraCapabilities cameraCapabilities); + void changeCameraCapabilities(in VideoProfile.CameraCapabilities cameraCapabilities); void changeVideoQuality(int videoQuality); } diff --git a/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl b/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl index bff3865..68e5fd4 100644 --- a/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl +++ b/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl @@ -16,6 +16,7 @@ package com.android.internal.telecom; +import android.net.Uri; import android.view.Surface; import android.telecom.VideoProfile; @@ -39,7 +40,7 @@ oneway interface IVideoProvider { void setZoom(float value); - void sendSessionModifyRequest(in VideoProfile reqProfile); + void sendSessionModifyRequest(in VideoProfile fromProfile, in VideoProfile toProfile); void sendSessionModifyResponse(in VideoProfile responseProfile); @@ -47,5 +48,5 @@ oneway interface IVideoProvider { void requestCallDataUsage(); - void setPauseImage(String uri); + void setPauseImage(in Uri uri); } |
