diff options
author | Brad Ebinger <breadley@google.com> | 2018-01-22 13:51:52 -0800 |
---|---|---|
committer | Brad Ebinger <breadley@google.com> | 2018-02-01 15:45:29 -0800 |
commit | 0e370b4a02b6687c775c002c59157f4465bb86d0 (patch) | |
tree | 2dc8d0b39289b7ccbf8c1297fdba6dfe55786b32 /telephony/java/android/telephony | |
parent | 5b1883b5f10ab13aee449d9524d7fb71c8ba0b6c (diff) |
Make ImsService API @SystemApi
Marks the ImsService API as @SystemAPI.
Bug: 63987047
Test: Build, Telephony unit tests
Merged-In: I10f8a09950be87cb166b718d1dcc2954fba872cb
Change-Id: I10f8a09950be87cb166b718d1dcc2954fba872cb
Diffstat (limited to 'telephony/java/android/telephony')
42 files changed, 5578 insertions, 485 deletions
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 47ba483a6440..a10d55a11f1a 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -27,8 +27,8 @@ import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ServiceManager; import android.service.carrier.CarrierService; +import android.telephony.ims.ImsReasonInfo; -import com.android.ims.ImsReasonInfo; import com.android.internal.telephony.ICarrierConfigLoader; /** @@ -1409,7 +1409,7 @@ public class CarrierConfigManager { "allow_video_calling_fallback_bool"; /** - * Defines operator-specific {@link com.android.ims.ImsReasonInfo} mappings. + * Defines operator-specific {@link ImsReasonInfo} mappings. * * Format: "ORIGINAL_CODE|MESSAGE|NEW_CODE" * Where {@code ORIGINAL_CODE} corresponds to a {@link ImsReasonInfo#getCode()} code, diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.aidl b/telephony/java/android/telephony/ims/ImsCallForwardInfo.aidl new file mode 100644 index 000000000000..b322b39be7e4 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable ImsCallForwardInfo; diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java new file mode 100644 index 000000000000..6d7218179067 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provides the call forward information for the supplementary service configuration. + * + * @hide + */ +@SystemApi +public final class ImsCallForwardInfo implements Parcelable { + // Refer to ImsUtInterface#CDIV_CF_XXX + /** @hide */ + public int mCondition; + // 0: disabled, 1: enabled + /** @hide */ + public int mStatus; + // 0x91: International, 0x81: Unknown + /** @hide */ + public int mToA; + // Service class + /** @hide */ + public int mServiceClass; + // Number (it will not include the "sip" or "tel" URI scheme) + /** @hide */ + public String mNumber; + // No reply timer for CF + /** @hide */ + public int mTimeSeconds; + + /** @hide */ + public ImsCallForwardInfo() { + } + + /** @hide */ + public ImsCallForwardInfo(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mCondition); + out.writeInt(mStatus); + out.writeInt(mToA); + out.writeString(mNumber); + out.writeInt(mTimeSeconds); + out.writeInt(mServiceClass); + } + + @Override + public String toString() { + return super.toString() + ", Condition: " + mCondition + + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled") + + ", ToA: " + mToA + + ", Service Class: " + mServiceClass + + ", Number=" + mNumber + + ", Time (seconds): " + mTimeSeconds; + } + + private void readFromParcel(Parcel in) { + mCondition = in.readInt(); + mStatus = in.readInt(); + mToA = in.readInt(); + mNumber = in.readString(); + mTimeSeconds = in.readInt(); + mServiceClass = in.readInt(); + } + + public static final Creator<ImsCallForwardInfo> CREATOR = + new Creator<ImsCallForwardInfo>() { + @Override + public ImsCallForwardInfo createFromParcel(Parcel in) { + return new ImsCallForwardInfo(in); + } + + @Override + public ImsCallForwardInfo[] newArray(int size) { + return new ImsCallForwardInfo[size]; + } + }; + + public int getCondition() { + return mCondition; + } + + public int getStatus() { + return mStatus; + } + + public int getToA() { + return mToA; + } + + public int getServiceClass() { + return mServiceClass; + } + + public String getNumber() { + return mNumber; + } + + public int getTimeSeconds() { + return mTimeSeconds; + } +} diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.aidl b/telephony/java/android/telephony/ims/ImsCallProfile.aidl new file mode 100644 index 000000000000..e24e14530916 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsCallProfile.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable ImsCallProfile; diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java new file mode 100644 index 000000000000..27e5f943982b --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -0,0 +1,608 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.PersistableBundle; +import android.telecom.VideoProfile; +import android.util.Log; + +import com.android.internal.telephony.PhoneConstants; + +/** + * Parcelable object to handle IMS call profile. + * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111. + * It provides the service and call type, the additional information related to the call. + * + * @hide + */ +@SystemApi +public final class ImsCallProfile implements Parcelable { + private static final String TAG = "ImsCallProfile"; + + /** + * Service types + */ + /** + * It is for a special case. It helps that the application can make a call + * without IMS connection (not registered). + * In the moment of the call initiation, the device try to connect to the IMS network + * and initiates the call. + */ + public static final int SERVICE_TYPE_NONE = 0; + /** + * It is a default type and can be selected when the device is connected to the IMS network. + */ + public static final int SERVICE_TYPE_NORMAL = 1; + /** + * It is for an emergency call. + */ + public static final int SERVICE_TYPE_EMERGENCY = 2; + + /** + * Call types + */ + /** + * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade) + */ + public static final int CALL_TYPE_VOICE_N_VIDEO = 1; + /** + * IR.92 (Voice only) + */ + public static final int CALL_TYPE_VOICE = 2; + /** + * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade) + */ + public static final int CALL_TYPE_VIDEO_N_VOICE = 3; + /** + * Video Telephony (audio / video two way) + */ + public static final int CALL_TYPE_VT = 4; + /** + * Video Telephony (audio two way / video TX one way) + */ + public static final int CALL_TYPE_VT_TX = 5; + /** + * Video Telephony (audio two way / video RX one way) + */ + public static final int CALL_TYPE_VT_RX = 6; + /** + * Video Telephony (audio two way / video inactive) + */ + public static final int CALL_TYPE_VT_NODIR = 7; + /** + * VideoShare (video two way) + */ + public static final int CALL_TYPE_VS = 8; + /** + * VideoShare (video TX one way) + */ + public static final int CALL_TYPE_VS_TX = 9; + /** + * VideoShare (video RX one way) + */ + public static final int CALL_TYPE_VS_RX = 10; + + /** + * Extra properties for IMS call. + */ + /** + * Boolean extra properties - "true" / "false" + * conference : Indicates if the session is for the conference call or not. + * e_call : Indicates if the session is for the emergency call or not. + * vms : Indicates if the session is connected to the voice mail system or not. + * call_mode_changeable : Indicates if the session is able to upgrade/downgrade + * the video during voice call. + * conference_avail : Indicates if the session can be extended to the conference. + */ + /** + * @hide + */ + public static final String EXTRA_CONFERENCE = "conference"; + /** + * @hide + */ + public static final String EXTRA_E_CALL = "e_call"; + /** + * @hide + */ + public static final String EXTRA_VMS = "vms"; + /** + * @hide + */ + public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable"; + /** + * @hide + */ + public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail"; + + // Extra string for internal use only. OEMs should not use + // this for packing extras. + /** + * @hide + */ + public static final String EXTRA_OEM_EXTRAS = "OemCallExtras"; + + /** + * Rule for originating identity (number) presentation, MO/MT. + * {@link ImsCallProfile#OIR_DEFAULT} + * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} + * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} + */ + public static final String EXTRA_OIR = "oir"; + /** + * Rule for calling name presentation + * {@link ImsCallProfile#OIR_DEFAULT} + * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} + * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} + */ + public static final String EXTRA_CNAP = "cnap"; + /** + * To identify the Ims call type, MO + * {@link ImsCallProfile#DIALSTRING_NORMAL} + * {@link ImsCallProfile#DIALSTRING_SS_CONF} + * {@link ImsCallProfile#DIALSTRING_USSD} + */ + public static final String EXTRA_DIALSTRING = "dialstring"; + + /** + * Values for EXTRA_OIR / EXTRA_CNAP + */ + /** + * Default presentation for Originating Identity. + */ + public static final int OIR_DEFAULT = 0; // "user subscription default value" + /** + * Restricted presentation for Originating Identity. + */ + public static final int OIR_PRESENTATION_RESTRICTED = 1; + /** + * Not restricted presentation for Originating Identity. + */ + public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; + /** + * Presentation unknown for Originating Identity. + */ + public static final int OIR_PRESENTATION_UNKNOWN = 3; + /** + * Payphone presentation for Originating Identity. + */ + public static final int OIR_PRESENTATION_PAYPHONE = 4; + + //Values for EXTRA_DIALSTRING + /** + * A default or normal normal call. + */ + public static final int DIALSTRING_NORMAL = 0; + /** + * Call for SIP-based user configuration + */ + public static final int DIALSTRING_SS_CONF = 1; + /** + * Call for USSD message + */ + public static final int DIALSTRING_USSD = 2; + + /** + * Values for causes that restrict call types + */ + // Default cause not restricted at peer and HD is supported + public static final int CALL_RESTRICT_CAUSE_NONE = 0; + // Service not supported by RAT at peer + public static final int CALL_RESTRICT_CAUSE_RAT = 1; + // Service Disabled at peer + public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; + // HD is not supported + public static final int CALL_RESTRICT_CAUSE_HD = 3; + + /** + * String extra properties + * oi : Originating identity (number), MT only + * cna : Calling name + * ussd : For network-initiated USSD, MT only + * remote_uri : Connected user identity (it can be used for the conference) + * ChildNum: Child number info. + * Codec: Codec info. + * DisplayText: Display text for the call. + * AdditionalCallInfo: Additional call info. + * CallPull: Boolean value specifying if the call is a pulled call. + */ + public static final String EXTRA_OI = "oi"; + public static final String EXTRA_CNA = "cna"; + public static final String EXTRA_USSD = "ussd"; + public static final String EXTRA_REMOTE_URI = "remote_uri"; + public static final String EXTRA_CHILD_NUMBER = "ChildNum"; + public static final String EXTRA_CODEC = "Codec"; + public static final String EXTRA_DISPLAY_TEXT = "DisplayText"; + public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; + public static final String EXTRA_IS_CALL_PULL = "CallPull"; + + /** + * Extra key which the RIL can use to indicate the radio technology used for a call. + * Valid values are: + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}, + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined + * {@code RIL_RADIO_TECHNOLOGY_*} constants. + * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer + * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g. + * "14" vs (int) 14). + * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection# + * updateWifiStateFromExtras(Bundle)} to determine whether to set the + * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection. + */ + public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; + + /** + * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'. Used to ensure + * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE} + * extra key. Should be removed when the non-compliant modems are fixed. + * @hide + */ + public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech"; + + /** @hide */ + public int mServiceType; + /** @hide */ + public int mCallType; + /** @hide */ + public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE; + + /** + * Extras associated with this {@link ImsCallProfile}. + * <p> + * Valid data types include: + * <ul> + * <li>{@link Integer} (and int)</li> + * <li>{@link Long} (and long)</li> + * <li>{@link Double} (and double)</li> + * <li>{@link String}</li> + * <li>{@code int[]}</li> + * <li>{@code long[]}</li> + * <li>{@code double[]}</li> + * <li>{@code String[]}</li> + * <li>{@link PersistableBundle}</li> + * <li>{@link Boolean} (and boolean)</li> + * <li>{@code boolean[]}</li> + * <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li> + * </ul> + * <p> + * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across + * a {@link android.os.Binder}. + */ + /** @hide */ + public Bundle mCallExtras; + /** @hide */ + public ImsStreamMediaProfile mMediaProfile; + + /** @hide */ + public ImsCallProfile(Parcel in) { + readFromParcel(in); + } + + /** @hide */ + public ImsCallProfile() { + mServiceType = SERVICE_TYPE_NORMAL; + mCallType = CALL_TYPE_VOICE_N_VIDEO; + mCallExtras = new Bundle(); + mMediaProfile = new ImsStreamMediaProfile(); + } + + /** @hide */ + public ImsCallProfile(int serviceType, int callType) { + mServiceType = serviceType; + mCallType = callType; + mCallExtras = new Bundle(); + mMediaProfile = new ImsStreamMediaProfile(); + } + + public String getCallExtra(String name) { + return getCallExtra(name, ""); + } + + public String getCallExtra(String name, String defaultValue) { + if (mCallExtras == null) { + return defaultValue; + } + + return mCallExtras.getString(name, defaultValue); + } + + public boolean getCallExtraBoolean(String name) { + return getCallExtraBoolean(name, false); + } + + public boolean getCallExtraBoolean(String name, boolean defaultValue) { + if (mCallExtras == null) { + return defaultValue; + } + + return mCallExtras.getBoolean(name, defaultValue); + } + + public int getCallExtraInt(String name) { + return getCallExtraInt(name, -1); + } + + public int getCallExtraInt(String name, int defaultValue) { + if (mCallExtras == null) { + return defaultValue; + } + + return mCallExtras.getInt(name, defaultValue); + } + + public void setCallExtra(String name, String value) { + if (mCallExtras != null) { + mCallExtras.putString(name, value); + } + } + + public void setCallExtraBoolean(String name, boolean value) { + if (mCallExtras != null) { + mCallExtras.putBoolean(name, value); + } + } + + public void setCallExtraInt(String name, int value) { + if (mCallExtras != null) { + mCallExtras.putInt(name, value); + } + } + + public void updateCallType(ImsCallProfile profile) { + mCallType = profile.mCallType; + } + + public void updateCallExtras(ImsCallProfile profile) { + mCallExtras.clear(); + mCallExtras = (Bundle) profile.mCallExtras.clone(); + } + + @Override + public String toString() { + return "{ serviceType=" + mServiceType + + ", callType=" + mCallType + + ", restrictCause=" + mRestrictCause + + ", mediaProfile=" + mMediaProfile.toString() + " }"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + Bundle filteredExtras = maybeCleanseExtras(mCallExtras); + out.writeInt(mServiceType); + out.writeInt(mCallType); + out.writeBundle(filteredExtras); + out.writeParcelable(mMediaProfile, 0); + } + + private void readFromParcel(Parcel in) { + mServiceType = in.readInt(); + mCallType = in.readInt(); + mCallExtras = in.readBundle(); + mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader()); + } + + public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() { + @Override + public ImsCallProfile createFromParcel(Parcel in) { + return new ImsCallProfile(in); + } + + @Override + public ImsCallProfile[] newArray(int size) { + return new ImsCallProfile[size]; + } + }; + + public int getServiceType() { + return mServiceType; + } + + public int getCallType() { + return mCallType; + } + + public int getRestrictCause() { + return mRestrictCause; + } + + public Bundle getCallExtras() { + return mCallExtras; + } + + public ImsStreamMediaProfile getMediaProfile() { + return mMediaProfile; + } + + /** + * Converts from the call types defined in {@link ImsCallProfile} to the + * video state values defined in {@link VideoProfile}. + * + * @param callProfile The call profile. + * @return The video state. + */ + public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) { + int videostate = getVideoStateFromCallType(callProfile.mCallType); + if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) { + videostate |= VideoProfile.STATE_PAUSED; + } else { + videostate &= ~VideoProfile.STATE_PAUSED; + } + return videostate; + } + + /** + * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state. + * @param callType The call type. + * @return The video state. + */ + public static int getVideoStateFromCallType(int callType) { + int videostate = VideoProfile.STATE_AUDIO_ONLY; + switch (callType) { + case CALL_TYPE_VT_TX: + videostate = VideoProfile.STATE_TX_ENABLED; + break; + case CALL_TYPE_VT_RX: + videostate = VideoProfile.STATE_RX_ENABLED; + break; + case CALL_TYPE_VT: + videostate = VideoProfile.STATE_BIDIRECTIONAL; + break; + case CALL_TYPE_VOICE: + videostate = VideoProfile.STATE_AUDIO_ONLY; + break; + default: + videostate = VideoProfile.STATE_AUDIO_ONLY; + break; + } + return videostate; + } + + /** + * Converts from the video state values defined in {@link VideoProfile} + * to the call types defined in {@link ImsCallProfile}. + * + * @param videoState The video state. + * @return The call type. + */ + public static int getCallTypeFromVideoState(int videoState) { + boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED); + boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED); + boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED); + if (isPaused) { + return ImsCallProfile.CALL_TYPE_VT_NODIR; + } else if (videoTx && !videoRx) { + return ImsCallProfile.CALL_TYPE_VT_TX; + } else if (!videoTx && videoRx) { + return ImsCallProfile.CALL_TYPE_VT_RX; + } else if (videoTx && videoRx) { + return ImsCallProfile.CALL_TYPE_VT; + } + return ImsCallProfile.CALL_TYPE_VOICE; + } + + /** + * Badly named old method, kept for compatibility. + * See {@link #presentationToOir(int)}. + * @hide + */ + public static int presentationToOIR(int presentation) { + switch (presentation) { + case PhoneConstants.PRESENTATION_RESTRICTED: + return ImsCallProfile.OIR_PRESENTATION_RESTRICTED; + case PhoneConstants.PRESENTATION_ALLOWED: + return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED; + case PhoneConstants.PRESENTATION_PAYPHONE: + return ImsCallProfile.OIR_PRESENTATION_PAYPHONE; + case PhoneConstants.PRESENTATION_UNKNOWN: + return ImsCallProfile.OIR_PRESENTATION_UNKNOWN; + default: + return ImsCallProfile.OIR_DEFAULT; + } + } + + /** + * Translate presentation value to OIR value + * @param presentation + * @return OIR values + */ + public static int presentationToOir(int presentation) { + return presentationToOIR(presentation); + } + + /** + * Translate OIR value to presentation value + * @param oir value + * @return presentation value + * @hide + */ + public static int OIRToPresentation(int oir) { + switch(oir) { + case ImsCallProfile.OIR_PRESENTATION_RESTRICTED: + return PhoneConstants.PRESENTATION_RESTRICTED; + case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED: + return PhoneConstants.PRESENTATION_ALLOWED; + case ImsCallProfile.OIR_PRESENTATION_PAYPHONE: + return PhoneConstants.PRESENTATION_PAYPHONE; + case ImsCallProfile.OIR_PRESENTATION_UNKNOWN: + return PhoneConstants.PRESENTATION_UNKNOWN; + default: + return PhoneConstants.PRESENTATION_UNKNOWN; + } + } + + /** + * Checks if video call is paused + * @return true if call is video paused + */ + public boolean isVideoPaused() { + return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE; + } + + /** + * Determines if the {@link ImsCallProfile} represents a video call. + * + * @return {@code true} if the profile is for a video call, {@code false} otherwise. + */ + public boolean isVideoCall() { + return VideoProfile.isVideo(getVideoStateFromCallType(mCallType)); + } + + /** + * Cleanses a {@link Bundle} to ensure that it contains only data of type: + * 1. Primitive data types (e.g. int, bool, and other values determined by + * {@link android.os.PersistableBundle#isValidType(Object)}). + * 2. Other Bundles. + * 3. {@link Parcelable} objects in the {@code android.*} namespace. + * @param extras the source {@link Bundle} + * @return where all elements are valid types the source {@link Bundle} is returned unmodified, + * otherwise a copy of the {@link Bundle} with the invalid elements is returned. + */ + private Bundle maybeCleanseExtras(Bundle extras) { + if (extras == null) { + return null; + } + + int startSize = extras.size(); + Bundle filtered = extras.filterValues(); + int endSize = filtered.size(); + if (startSize != endSize) { + Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were " + + "removed - only primitive types and system parcelables are permitted."); + } + return filtered; + } + + /** + * Determines if a video state is set in a video state bit-mask. + * + * @param videoState The video state bit mask. + * @param videoStateToCheck The particular video state to check. + * @return True if the video state is set in the bit-mask. + */ + private static boolean isVideoStateSet(int videoState, int videoStateToCheck) { + return (videoState & videoStateToCheck) == videoStateToCheck; + } +} diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java new file mode 100644 index 000000000000..207965d5a2f6 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsCallSession.java @@ -0,0 +1,1408 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Message; +import android.os.RemoteException; +import android.telephony.ims.aidl.IImsCallSessionListener; + +import java.util.Objects; +import java.util.concurrent.Executor; + +import android.telephony.ims.stub.ImsCallSessionImplBase; +import android.util.Log; + +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsVideoCallProvider; + +/** + * Provides the call initiation/termination, and media exchange between two IMS endpoints. + * It directly communicates with IMS service which implements the IMS protocol behavior. + * + * @hide + */ +public class ImsCallSession { + private static final String TAG = "ImsCallSession"; + + /** + * Defines IMS call session state. Please use {@link ImsCallSessionImplBase.State} definition. + * This is kept around for capability reasons. + */ + public static class State { + public static final int IDLE = 0; + public static final int INITIATED = 1; + public static final int NEGOTIATING = 2; + public static final int ESTABLISHING = 3; + public static final int ESTABLISHED = 4; + + public static final int RENEGOTIATING = 5; + public static final int REESTABLISHING = 6; + + public static final int TERMINATING = 7; + public static final int TERMINATED = 8; + + public static final int INVALID = (-1); + + /** + * Converts the state to string. + */ + public static String toString(int state) { + switch (state) { + case IDLE: + return "IDLE"; + case INITIATED: + return "INITIATED"; + case NEGOTIATING: + return "NEGOTIATING"; + case ESTABLISHING: + return "ESTABLISHING"; + case ESTABLISHED: + return "ESTABLISHED"; + case RENEGOTIATING: + return "RENEGOTIATING"; + case REESTABLISHING: + return "REESTABLISHING"; + case TERMINATING: + return "TERMINATING"; + case TERMINATED: + return "TERMINATED"; + default: + return "UNKNOWN"; + } + } + + private State() { + } + } + + /** + * Listener for events relating to an IMS session, such as when a session is being + * recieved ("on ringing") or a call is outgoing ("on calling"). + * <p>Many of these events are also received by {@link ImsCall.Listener}.</p> + * @hide + */ + public static class Listener { + /** + * Called when a request is sent out to initiate a new session + * and 1xx response is received from the network. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionProgressing(ImsCallSession session, + ImsStreamMediaProfile profile) { + // no-op + } + + /** + * Called when the session is established. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionStarted(ImsCallSession session, + ImsCallProfile profile) { + // no-op + } + + /** + * Called when the session establishment is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the session establishment failure + */ + public void callSessionStartFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the session is terminated. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the session termination + */ + public void callSessionTerminated(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the session is in hold. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionHeld(ImsCallSession session, + ImsCallProfile profile) { + } + + /** + * Called when the session hold is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the session hold failure + */ + public void callSessionHoldFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the session hold is received from the remote user. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionHoldReceived(ImsCallSession session, + ImsCallProfile profile) { + } + + /** + * Called when the session resume is done. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionResumed(ImsCallSession session, + ImsCallProfile profile) { + } + + /** + * Called when the session resume is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the session resume failure + */ + public void callSessionResumeFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the session resume is received from the remote user. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionResumeReceived(ImsCallSession session, + ImsCallProfile profile) { + } + + /** + * Called when the session merge has been started. At this point, the {@code newSession} + * represents the session which has been initiated to the IMS conference server for the + * new merged conference. + * + * @param session the session object that carries out the IMS session + * @param newSession the session object that is merged with an active & hold session + */ + public void callSessionMergeStarted(ImsCallSession session, + ImsCallSession newSession, ImsCallProfile profile) { + } + + /** + * Called when the session merge is successful and the merged session is active. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionMergeComplete(ImsCallSession session) { + } + + /** + * Called when the session merge has failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the call merge failure + */ + public void callSessionMergeFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the session is updated (except for hold/unhold). + * + * @param session the session object that carries out the IMS session + */ + public void callSessionUpdated(ImsCallSession session, + ImsCallProfile profile) { + } + + /** + * Called when the session update is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the session update failure + */ + public void callSessionUpdateFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the session update is received from the remote user. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionUpdateReceived(ImsCallSession session, + ImsCallProfile profile) { + // no-op + } + + /** + * Called when the session is extended to the conference session. + * + * @param session the session object that carries out the IMS session + * @param newSession the session object that is extended to the conference + * from the active session + */ + public void callSessionConferenceExtended(ImsCallSession session, + ImsCallSession newSession, ImsCallProfile profile) { + } + + /** + * Called when the conference extension is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the conference extension failure + */ + public void callSessionConferenceExtendFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + } + + /** + * Called when the conference extension is received from the remote user. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionConferenceExtendReceived(ImsCallSession session, + ImsCallSession newSession, ImsCallProfile profile) { + // no-op + } + + /** + * Called when the invitation request of the participants is delivered to the conference + * server. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) { + // no-op + } + + /** + * Called when the invitation request of the participants is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the conference invitation failure + */ + public void callSessionInviteParticipantsRequestFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + // no-op + } + + /** + * Called when the removal request of the participants is delivered to the conference + * server. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) { + // no-op + } + + /** + * Called when the removal request of the participants is failed. + * + * @param session the session object that carries out the IMS session + * @param reasonInfo detailed reason of the conference removal failure + */ + public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session, + ImsReasonInfo reasonInfo) { + // no-op + } + + /** + * Called when the conference state is updated. + * + * @param session the session object that carries out the IMS session + */ + public void callSessionConferenceStateUpdated(ImsCallSession session, + ImsConferenceState state) { + // no-op + } + + /** + * Called when the USSD message is received from the network. + * + * @param mode mode of the USSD message (REQUEST / NOTIFY) + * @param ussdMessage USSD message + */ + public void callSessionUssdMessageReceived(ImsCallSession session, + int mode, String ussdMessage) { + // no-op + } + + /** + * Called when an {@link ImsCallSession} may handover from one radio technology to another. + * For example, the session may handover from WIFI to LTE if conditions are right. + * <p> + * If handover is attempted, + * {@link #callSessionHandover(ImsCallSession, int, int, ImsReasonInfo)} or + * {@link #callSessionHandoverFailed(ImsCallSession, int, int, ImsReasonInfo)} will be + * called to indicate the success or failure of the handover. + * + * @param session IMS session object + * @param srcAccessTech original access technology + * @param targetAccessTech new access technology + */ + public void callSessionMayHandover(ImsCallSession session, int srcAccessTech, + int targetAccessTech) { + // no-op + } + + /** + * Called when session access technology changes + * + * @param session IMS session object + * @param srcAccessTech original access technology + * @param targetAccessTech new access technology + * @param reasonInfo + */ + public void callSessionHandover(ImsCallSession session, + int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { + // no-op + } + + /** + * Called when session access technology change fails + * + * @param session IMS session object + * @param srcAccessTech original access technology + * @param targetAccessTech new access technology + * @param reasonInfo handover failure reason + */ + public void callSessionHandoverFailed(ImsCallSession session, + int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { + // no-op + } + + /** + * Called when TTY mode of remote party changed + * + * @param session IMS session object + * @param mode TTY mode of remote party + */ + public void callSessionTtyModeReceived(ImsCallSession session, + int mode) { + // no-op + } + + /** + * Notifies of a change to the multiparty state for this {@code ImsCallSession}. + * + * @param session The call session. + * @param isMultiParty {@code true} if the session became multiparty, {@code false} + * otherwise. + */ + public void callSessionMultipartyStateChanged(ImsCallSession session, + boolean isMultiParty) { + // no-op + } + + /** + * Called when the session supplementary service is received + * + * @param session the session object that carries out the IMS session + */ + public void callSessionSuppServiceReceived(ImsCallSession session, + ImsSuppServiceNotification suppServiceInfo) { + } + + /** + * Received RTT modify request from Remote Party + */ + public void callSessionRttModifyRequestReceived(ImsCallSession session, + ImsCallProfile callProfile) { + // no-op + } + + /** + * Received response for RTT modify request + */ + public void callSessionRttModifyResponseReceived(int status) { + // no -op + } + + /** + * Device received RTT message from Remote UE + */ + public void callSessionRttMessageReceived(String rttMessage) { + // no-op + } + } + + private final IImsCallSession miSession; + private boolean mClosed = false; + private Listener mListener; + + /** @hide */ + public ImsCallSession(IImsCallSession iSession) { + miSession = iSession; + + if (iSession != null) { + try { + iSession.setListener(new IImsCallSessionListenerProxy()); + } catch (RemoteException e) { + } + } else { + mClosed = true; + } + } + + /** @hide */ + public ImsCallSession(IImsCallSession iSession, Listener listener) { + this(iSession); + setListener(listener); + } + + /** + * Closes this object. This object is not usable after being closed. + */ + public void close() { + synchronized (this) { + if (mClosed) { + return; + } + + try { + miSession.close(); + mClosed = true; + } catch (RemoteException e) { + } + } + } + + /** + * Gets the call ID of the session. + * + * @return the call ID + */ + public String getCallId() { + if (mClosed) { + return null; + } + + try { + return miSession.getCallId(); + } catch (RemoteException e) { + return null; + } + } + + /** + * Gets the call profile that this session is associated with + * + * @return the call profile that this session is associated with + */ + public ImsCallProfile getCallProfile() { + if (mClosed) { + return null; + } + + try { + return miSession.getCallProfile(); + } catch (RemoteException e) { + return null; + } + } + + /** + * Gets the local call profile that this session is associated with + * + * @return the local call profile that this session is associated with + */ + public ImsCallProfile getLocalCallProfile() { + if (mClosed) { + return null; + } + + try { + return miSession.getLocalCallProfile(); + } catch (RemoteException e) { + return null; + } + } + + /** + * Gets the remote call profile that this session is associated with + * + * @return the remote call profile that this session is associated with + */ + public ImsCallProfile getRemoteCallProfile() { + if (mClosed) { + return null; + } + + try { + return miSession.getRemoteCallProfile(); + } catch (RemoteException e) { + return null; + } + } + + /** + * Gets the video call provider for the session. + * + * @return The video call provider. + * @hide + */ + public IImsVideoCallProvider getVideoCallProvider() { + if (mClosed) { + return null; + } + + try { + return miSession.getVideoCallProvider(); + } catch (RemoteException e) { + return null; + } + } + + /** + * Gets the value associated with the specified property of this session. + * + * @return the string value associated with the specified property + */ + public String getProperty(String name) { + if (mClosed) { + return null; + } + + try { + return miSession.getProperty(name); + } catch (RemoteException e) { + return null; + } + } + + /** + * Gets the session state. + * The value returned must be one of the states in {@link State}. + * + * @return the session state + */ + public int getState() { + if (mClosed) { + return State.INVALID; + } + + try { + return miSession.getState(); + } catch (RemoteException e) { + return State.INVALID; + } + } + + /** + * Determines if the {@link ImsCallSession} is currently alive (e.g. not in a terminated or + * closed state). + * + * @return {@code True} if the session is alive. + */ + public boolean isAlive() { + if (mClosed) { + return false; + } + + int state = getState(); + switch (state) { + case State.IDLE: + case State.INITIATED: + case State.NEGOTIATING: + case State.ESTABLISHING: + case State.ESTABLISHED: + case State.RENEGOTIATING: + case State.REESTABLISHING: + return true; + default: + return false; + } + } + + /** + * Gets the native IMS call session. + * @hide + */ + public IImsCallSession getSession() { + return miSession; + } + + /** + * Checks if the session is in call. + * + * @return true if the session is in call + */ + public boolean isInCall() { + if (mClosed) { + return false; + } + + try { + return miSession.isInCall(); + } catch (RemoteException e) { + return false; + } + } + + /** + * Sets the listener to listen to the session events. A {@link ImsCallSession} + * can only hold one listener at a time. Subsequent calls to this method + * override the previous listener. + * + * @param listener to listen to the session events of this object + * @hide + */ + public void setListener(Listener listener) { + mListener = listener; + } + + /** + * Mutes or unmutes the mic for the active call. + * + * @param muted true if the call is muted, false otherwise + */ + public void setMute(boolean muted) { + if (mClosed) { + return; + } + + try { + miSession.setMute(muted); + } catch (RemoteException e) { + } + } + + /** + * Initiates an IMS call with the specified target and call profile. + * The session listener is called back upon defined session events. + * The method is only valid to call when the session state is in + * {@link ImsCallSession.State#IDLE}. + * + * @param callee dialed string to make the call to + * @param profile call profile to make the call with the specified service type, + * call type and media information + * @see Listener#callSessionStarted, Listener#callSessionStartFailed + */ + public void start(String callee, ImsCallProfile profile) { + if (mClosed) { + return; + } + + try { + miSession.start(callee, profile); + } catch (RemoteException e) { + } + } + + /** + * Initiates an IMS conference call with the specified target and call profile. + * The session listener is called back upon defined session events. + * The method is only valid to call when the session state is in + * {@link ImsCallSession.State#IDLE}. + * + * @param participants participant list to initiate an IMS conference call + * @param profile call profile to make the call with the specified service type, + * call type and media information + * @see Listener#callSessionStarted, Listener#callSessionStartFailed + */ + public void start(String[] participants, ImsCallProfile profile) { + if (mClosed) { + return; + } + + try { + miSession.startConference(participants, profile); + } catch (RemoteException e) { + } + } + + /** + * Accepts an incoming call or session update. + * + * @param callType call type specified in {@link ImsCallProfile} to be answered + * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered + * @see Listener#callSessionStarted + */ + public void accept(int callType, ImsStreamMediaProfile profile) { + if (mClosed) { + return; + } + + try { + miSession.accept(callType, profile); + } catch (RemoteException e) { + } + } + + /** + * Rejects an incoming call or session update. + * + * @param reason reason code to reject an incoming call + * @see Listener#callSessionStartFailed + */ + public void reject(int reason) { + if (mClosed) { + return; + } + + try { + miSession.reject(reason); + } catch (RemoteException e) { + } + } + + /** + * Terminates a call. + * + * @see Listener#callSessionTerminated + */ + public void terminate(int reason) { + if (mClosed) { + return; + } + + try { + miSession.terminate(reason); + } catch (RemoteException e) { + } + } + + /** + * Puts a call on hold. When it succeeds, {@link Listener#callSessionHeld} is called. + * + * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call + * @see Listener#callSessionHeld, Listener#callSessionHoldFailed + */ + public void hold(ImsStreamMediaProfile profile) { + if (mClosed) { + return; + } + + try { + miSession.hold(profile); + } catch (RemoteException e) { + } + } + + /** + * Continues a call that's on hold. When it succeeds, + * {@link Listener#callSessionResumed} is called. + * + * @param profile stream media profile {@link ImsStreamMediaProfile} to resume the call + * @see Listener#callSessionResumed, Listener#callSessionResumeFailed + */ + public void resume(ImsStreamMediaProfile profile) { + if (mClosed) { + return; + } + + try { + miSession.resume(profile); + } catch (RemoteException e) { + } + } + + /** + * Merges the active & hold call. When it succeeds, + * {@link Listener#callSessionMergeStarted} is called. + * + * @see Listener#callSessionMergeStarted , Listener#callSessionMergeFailed + */ + public void merge() { + if (mClosed) { + return; + } + + try { + miSession.merge(); + } catch (RemoteException e) { + } + } + + /** + * Updates the current call's properties (ex. call mode change: video upgrade / downgrade). + * + * @param callType call type specified in {@link ImsCallProfile} to be updated + * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated + * @see Listener#callSessionUpdated, Listener#callSessionUpdateFailed + */ + public void update(int callType, ImsStreamMediaProfile profile) { + if (mClosed) { + return; + } + + try { + miSession.update(callType, profile); + } catch (RemoteException e) { + } + } + + /** + * Extends this call to the conference call with the specified recipients. + * + * @param participants list to be invited to the conference call after extending the call + * @see Listener#callSessionConferenceExtended + * @see Listener#callSessionConferenceExtendFailed + */ + public void extendToConference(String[] participants) { + if (mClosed) { + return; + } + + try { + miSession.extendToConference(participants); + } catch (RemoteException e) { + } + } + + /** + * Requests the conference server to invite an additional participants to the conference. + * + * @param participants list to be invited to the conference call + * @see Listener#callSessionInviteParticipantsRequestDelivered + * @see Listener#callSessionInviteParticipantsRequestFailed + */ + public void inviteParticipants(String[] participants) { + if (mClosed) { + return; + } + + try { + miSession.inviteParticipants(participants); + } catch (RemoteException e) { + } + } + + /** + * Requests the conference server to remove the specified participants from the conference. + * + * @param participants participant list to be removed from the conference call + * @see Listener#callSessionRemoveParticipantsRequestDelivered + * @see Listener#callSessionRemoveParticipantsRequestFailed + */ + public void removeParticipants(String[] participants) { + if (mClosed) { + return; + } + + try { + miSession.removeParticipants(participants); + } catch (RemoteException e) { + } + } + + + /** + * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, + * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, + * and event flash to 16. Currently, event flash is not supported. + * + * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. + */ + public void sendDtmf(char c, Message result) { + if (mClosed) { + return; + } + + try { + miSession.sendDtmf(c, result); + } catch (RemoteException e) { + } + } + + /** + * Starts a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, + * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, + * and event flash to 16. Currently, event flash is not supported. + * + * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. + */ + public void startDtmf(char c) { + if (mClosed) { + return; + } + + try { + miSession.startDtmf(c); + } catch (RemoteException e) { + } + } + + /** + * Stops a DTMF code. + */ + public void stopDtmf() { + if (mClosed) { + return; + } + + try { + miSession.stopDtmf(); + } catch (RemoteException e) { + } + } + + /** + * Sends an USSD message. + * + * @param ussdMessage USSD message to send + */ + public void sendUssd(String ussdMessage) { + if (mClosed) { + return; + } + + try { + miSession.sendUssd(ussdMessage); + } catch (RemoteException e) { + } + } + + /** + * Determines if the session is multiparty. + * + * @return {@code True} if the session is multiparty. + */ + public boolean isMultiparty() { + if (mClosed) { + return false; + } + + try { + return miSession.isMultiparty(); + } catch (RemoteException e) { + return false; + } + } + + /** + * Sends Rtt Message + * + * @param rttMessage rtt text to be sent + */ + public void sendRttMessage(String rttMessage) { + if (mClosed) { + return; + } + + try { + miSession.sendRttMessage(rttMessage); + } catch (RemoteException e) { + } + } + + /** + * Sends RTT Upgrade request + * + * @param to : expected profile + */ + public void sendRttModifyRequest(ImsCallProfile to) { + if (mClosed) { + return; + } + + try { + miSession.sendRttModifyRequest(to); + } catch (RemoteException e) { + } + } + + /** + * Sends RTT Upgrade response + * + * @param response : response for upgrade + */ + public void sendRttModifyResponse(boolean response) { + if (mClosed) { + return; + } + + try { + miSession.sendRttModifyResponse(response); + } catch (RemoteException e) { + } + } + + /** + * A listener type for receiving notification on IMS call session events. + * When an event is generated for an {@link IImsCallSession}, + * the application is notified by having one of the methods called on + * the {@link IImsCallSessionListener}. + */ + private class IImsCallSessionListenerProxy extends IImsCallSessionListener.Stub { + /** + * Notifies the result of the basic session operation (setup / terminate). + */ + @Override + public void callSessionProgressing(ImsStreamMediaProfile profile) { + if (mListener != null) { + mListener.callSessionProgressing(ImsCallSession.this, profile); + } + } + + @Override + public void callSessionInitiated(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionStarted(ImsCallSession.this, profile); + } + } + + @Override + public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo); + } + } + + @Override + public void callSessionTerminated(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionTerminated(ImsCallSession.this, reasonInfo); + } + } + + /** + * Notifies the result of the call hold/resume operation. + */ + @Override + public void callSessionHeld(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionHeld(ImsCallSession.this, profile); + } + } + + @Override + public void callSessionHoldFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo); + } + } + + @Override + public void callSessionHoldReceived(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionHoldReceived(ImsCallSession.this, profile); + } + } + + @Override + public void callSessionResumed(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionResumed(ImsCallSession.this, profile); + } + } + + @Override + public void callSessionResumeFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo); + } + } + + @Override + public void callSessionResumeReceived(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionResumeReceived(ImsCallSession.this, profile); + } + } + + /** + * Notifies the start of a call merge operation. + * + * @param newSession The merged call session. + * @param profile The call profile. + */ + @Override + public void callSessionMergeStarted(IImsCallSession newSession, ImsCallProfile profile) { + // This callback can be used for future use to add additional + // functionality that may be needed between conference start and complete + Log.d(TAG, "callSessionMergeStarted"); + } + + /** + * Notifies the successful completion of a call merge operation. + * + * @param newSession The call session. + */ + @Override + public void callSessionMergeComplete(IImsCallSession newSession) { + if (mListener != null) { + if (newSession != null) { + // Check if the active session is the same session that was + // active before the merge request was sent. + ImsCallSession validActiveSession = ImsCallSession.this; + try { + if (!Objects.equals(miSession.getCallId(), newSession.getCallId())) { + // New session created after conference + validActiveSession = new ImsCallSession(newSession); + } + } catch (RemoteException rex) { + Log.e(TAG, "callSessionMergeComplete: exception for getCallId!"); + } + mListener.callSessionMergeComplete(validActiveSession); + } else { + // Session already exists. Hence no need to pass + mListener.callSessionMergeComplete(null); + } + } + } + + /** + * Notifies of a failure to perform a call merge operation. + * + * @param reasonInfo The merge failure reason. + */ + @Override + public void callSessionMergeFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo); + } + } + + /** + * Notifies the result of call upgrade / downgrade or any other call updates. + */ + @Override + public void callSessionUpdated(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionUpdated(ImsCallSession.this, profile); + } + } + + @Override + public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo); + } + } + + @Override + public void callSessionUpdateReceived(ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionUpdateReceived(ImsCallSession.this, profile); + } + } + + /** + * Notifies the result of conference extension. + */ + @Override + public void callSessionConferenceExtended(IImsCallSession newSession, + ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionConferenceExtended(ImsCallSession.this, + new ImsCallSession(newSession), profile); + } + } + + @Override + public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo); + } + } + + @Override + public void callSessionConferenceExtendReceived(IImsCallSession newSession, + ImsCallProfile profile) { + if (mListener != null) { + mListener.callSessionConferenceExtendReceived(ImsCallSession.this, + new ImsCallSession(newSession), profile); + } + } + + /** + * Notifies the result of the participant invitation / removal to/from + * the conference session. + */ + @Override + public void callSessionInviteParticipantsRequestDelivered() { + if (mListener != null) { + mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this); + } + } + + @Override + public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this, + reasonInfo); + } + } + + @Override + public void callSessionRemoveParticipantsRequestDelivered() { + if (mListener != null) { + mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this); + } + } + + @Override + public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this, + reasonInfo); + } + } + + /** + * Notifies the changes of the conference info. in the conference session. + */ + @Override + public void callSessionConferenceStateUpdated(ImsConferenceState state) { + if (mListener != null) { + mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state); + } + } + + /** + * Notifies the incoming USSD message. + */ + @Override + public void callSessionUssdMessageReceived(int mode, String ussdMessage) { + if (mListener != null) { + mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage); + } + } + + /** + * Notifies of a case where a {@link ImsCallSession} may + * potentially handover from one radio technology to another. + * @param srcAccessTech The source radio access technology; one of the access technology + * constants defined in {@link android.telephony.ServiceState}. For + * example + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. + * @param targetAccessTech The target radio access technology; one of the access technology + * constants defined in {@link android.telephony.ServiceState}. For + * example + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. + */ + @Override + public void callSessionMayHandover(int srcAccessTech, int targetAccessTech) { + if (mListener != null) { + mListener.callSessionMayHandover(ImsCallSession.this, srcAccessTech, + targetAccessTech); + } + } + + /** + * Notifies of handover information for this call + */ + @Override + public void callSessionHandover(int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionHandover(ImsCallSession.this, srcAccessTech, + targetAccessTech, reasonInfo); + } + } + + /** + * Notifies of handover failure info for this call + */ + @Override + public void callSessionHandoverFailed(int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { + if (mListener != null) { + mListener.callSessionHandoverFailed(ImsCallSession.this, srcAccessTech, + targetAccessTech, reasonInfo); + } + } + + /** + * Notifies the TTY mode received from remote party. + */ + @Override + public void callSessionTtyModeReceived(int mode) { + if (mListener != null) { + mListener.callSessionTtyModeReceived(ImsCallSession.this, mode); + } + } + + /** + * Notifies of a change to the multiparty state for this {@code ImsCallSession}. + * + * @param isMultiParty {@code true} if the session became multiparty, {@code false} + * otherwise. + */ + public void callSessionMultipartyStateChanged(boolean isMultiParty) { + if (mListener != null) { + mListener.callSessionMultipartyStateChanged(ImsCallSession.this, isMultiParty); + } + } + + @Override + public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppServiceInfo ) { + if (mListener != null) { + mListener.callSessionSuppServiceReceived(ImsCallSession.this, suppServiceInfo); + } + } + + /** + * Received RTT modify request from remote party + */ + @Override + public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) { + if (mListener != null) { + mListener.callSessionRttModifyRequestReceived(ImsCallSession.this, callProfile); + } + } + + /** + * Received response for RTT modify request + */ + @Override + public void callSessionRttModifyResponseReceived(int status) { + if (mListener != null) { + mListener.callSessionRttModifyResponseReceived(status); + } + } + + /** + * RTT Message received + */ + @Override + public void callSessionRttMessageReceived(String rttMessage) { + if (mListener != null) { + mListener.callSessionRttMessageReceived(rttMessage); + } + } + } + + /** + * Provides a string representation of the {@link ImsCallSession}. Primarily intended for + * use in log statements. + * + * @return String representation of session. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[ImsCallSession objId:"); + sb.append(System.identityHashCode(this)); + sb.append(" state:"); + sb.append(State.toString(getState())); + sb.append(" callId:"); + sb.append(getCallId()); + sb.append("]"); + return sb.toString(); + } +} diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java index 96c7af6bd039..a7f124a5b791 100644 --- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java +++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java @@ -16,343 +16,508 @@ package android.telephony.ims; +import android.annotation.SystemApi; import android.os.RemoteException; import android.telephony.ims.aidl.IImsCallSessionListener; +import android.telephony.ims.stub.ImsCallSessionImplBase; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsConferenceState; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsSuppServiceNotification; import com.android.ims.internal.IImsCallSession; -import com.android.ims.internal.ImsCallSession; /** - * Proxy class for interfacing with the framework's Call session for an ongoing IMS call. - * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsCallSessionListener maintained by other ImsServices. + * Listener interface for notifying the Framework's {@link ImsCallSession} for updates to an ongoing + * IMS call. * * @hide */ +// DO NOT remove or change the existing APIs, only add new ones to this implementation or you +// will break other implementations of ImsCallSessionListener maintained by other ImsServices. +// TODO: APIs in here do not conform to API guidelines yet. This can be changed if +// ImsCallSessionListenerConverter is also changed. +@SystemApi public class ImsCallSessionListener { private final IImsCallSessionListener mListener; + /** @hide */ public ImsCallSessionListener(IImsCallSessionListener l) { mListener = l; } /** - * Called when a request is sent out to initiate a new session - * and 1xx response is received from the network. + * A request has been sent out to initiate a new IMS call session and a 1xx response has been + * received from the network. */ - public void callSessionProgressing(ImsStreamMediaProfile profile) - throws RemoteException { - mListener.callSessionProgressing(profile); + public void callSessionProgressing(ImsStreamMediaProfile profile) { + try { + mListener.callSessionProgressing(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session is initiated. + * The IMS call session has been initiated. * - * @param profile the associated {@link ImsCallSession}. + * @param profile the associated {@link ImsCallProfile}. */ - public void callSessionInitiated(ImsCallProfile profile) throws RemoteException { - mListener.callSessionInitiated(profile); + public void callSessionInitiated(ImsCallProfile profile) { + try { + mListener.callSessionInitiated(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session establishment has failed. + * The IMS call session establishment has failed. * - * @param reasonInfo detailed reason of the session establishment failure + * @param reasonInfo {@link ImsReasonInfo} detailing the reason of the IMS call session + * establishment failure. */ - public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionInitiatedFailed(reasonInfo); + public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionInitiatedFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session is terminated. + * The IMS call session has been terminated. * - * @param reasonInfo detailed reason of the session termination + * @param reasonInfo {@link ImsReasonInfo} detailing the reason of the session termination. */ - public void callSessionTerminated(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionTerminated(reasonInfo); + public void callSessionTerminated(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionTerminated(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session is on hold. + * The IMS call session has started the process of holding the call. If it fails, + * {@link #callSessionHoldFailed(ImsReasonInfo)} should be called. + * + * If the IMS call session is resumed, call {@link #callSessionResumed(ImsCallProfile)}. + * + * @param profile The associated {@link ImsCallProfile} of the call session that has been put + * on hold. */ - public void callSessionHeld(ImsCallProfile profile) throws RemoteException { - mListener.callSessionHeld(profile); + public void callSessionHeld(ImsCallProfile profile) { + try { + mListener.callSessionHeld(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session hold has failed. + * The IMS call session has failed to be held. * - * @param reasonInfo detailed reason of the session hold failure + * @param reasonInfo {@link ImsReasonInfo} detailing the reason of the session hold failure. */ - public void callSessionHoldFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionHoldFailed(reasonInfo); + public void callSessionHoldFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionHoldFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session hold is received from the remote user. + * This IMS Call session has been put on hold by the remote party. + * + * @param profile The {@link ImsCallProfile} associated with this IMS call session. */ - public void callSessionHoldReceived(ImsCallProfile profile) throws RemoteException { - mListener.callSessionHoldReceived(profile); + public void callSessionHoldReceived(ImsCallProfile profile) { + try { + mListener.callSessionHoldReceived(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session resume is done. + * The IMS call session has started the process of resuming the call. If the process of resuming + * the call fails, call {@link #callSessionResumeFailed(ImsReasonInfo)}. + * + * @param profile The {@link ImsCallProfile} associated with this IMS call session. */ - public void callSessionResumed(ImsCallProfile profile) throws RemoteException { - mListener.callSessionResumed(profile); + public void callSessionResumed(ImsCallProfile profile) { + try { + mListener.callSessionResumed(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session resume has failed. + * The IMS call session resume has failed. * - * @param reasonInfo detailed reason of the session resume failure + * @param reasonInfo {@link ImsReasonInfo} containing the detailed reason of the session resume + * failure. */ - public void callSessionResumeFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionResumeFailed(reasonInfo); + public void callSessionResumeFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionResumeFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session resume is received from the remote user. + * The remote party has resumed this IMS call session. + * + * @param profile {@link ImsCallProfile} associated with the IMS call session. */ - public void callSessionResumeReceived(ImsCallProfile profile) throws RemoteException { - mListener.callSessionResumeReceived(profile); + public void callSessionResumeReceived(ImsCallProfile profile) { + try { + mListener.callSessionResumeReceived(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session merge has been started. At this point, the {@code newSession} - * represents the session which has been initiated to the IMS conference server for the - * new merged conference. + * The IMS call session merge has been started. At this point, the {@code newSession} + * represents the IMS call session which represents the new merged conference and has been + * initiated to the IMS conference server. * - * @param newSession the session object that is merged with an active & hold session + * @param newSession the {@link ImsCallSessionImplBase} that represents the merged active & held + * sessions. + * @param profile The {@link ImsCallProfile} associated with this IMS call session. */ - public void callSessionMergeStarted(ImsCallSession newSession, ImsCallProfile profile) - throws RemoteException { - mListener.callSessionMergeStarted(newSession != null ? newSession.getSession() : null, - profile); + public void callSessionMergeStarted(ImsCallSessionImplBase newSession, ImsCallProfile profile) + { + try { + mListener.callSessionMergeStarted(newSession != null ? + newSession.getServiceImpl() : null, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session merge has been started. At this point, the {@code newSession} - * represents the session which has been initiated to the IMS conference server for the - * new merged conference. - * - * @param newSession the session object that is merged with an active & hold session + * Compatibility method for older implementations. + * See {@link #callSessionMergeStarted(ImsCallSessionImplBase, ImsCallProfile)}. * * @hide */ public void callSessionMergeStarted(IImsCallSession newSession, ImsCallProfile profile) - throws RemoteException { - mListener.callSessionMergeStarted(newSession, profile); + { + try { + mListener.callSessionMergeStarted(newSession, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session merge is successful and the merged session is active. + * The session merge is successful and the merged {@link ImsCallSession} is active. * - * @param newSession the new session object that is used for the conference + * @param newSession the new {@link ImsCallSessionImplBase} + * that represents the conference IMS call + * session. */ - public void callSessionMergeComplete(ImsCallSession newSession) throws RemoteException { - mListener.callSessionMergeComplete(newSession != null ? newSession.getSession() : null); + public void callSessionMergeComplete(ImsCallSessionImplBase newSession) { + try { + mListener.callSessionMergeComplete(newSession != null ? + newSession.getServiceImpl() : null); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session merge is successful and the merged session is active. + * Compatibility method for older implementations of ImsService. * - * @param newSession the new session object that is used for the conference + * See {@link #callSessionMergeComplete(ImsCallSessionImplBase)}}. * * @hide */ - public void callSessionMergeComplete(IImsCallSession newSession) throws RemoteException { - mListener.callSessionMergeComplete(newSession); + public void callSessionMergeComplete(IImsCallSession newSession) { + try { + mListener.callSessionMergeComplete(newSession); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session merge has failed. + * The IMS call session merge has failed. * - * @param reasonInfo detailed reason of the call merge failure + * @param reasonInfo {@link ImsReasonInfo} contining the reason for the call merge failure. */ - public void callSessionMergeFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionMergeFailed(reasonInfo); + public void callSessionMergeFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionMergeFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session is updated (except for hold/unhold). + * The IMS call session profile has been updated. Does not include holding or resuming a call. + * + * @param profile The {@link ImsCallProfile} associated with the updated IMS call session. */ - public void callSessionUpdated(ImsCallProfile profile) throws RemoteException { - mListener.callSessionUpdated(profile); + public void callSessionUpdated(ImsCallProfile profile) { + try { + mListener.callSessionUpdated(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session update has failed. + * The IMS call session profile update has failed. * - * @param reasonInfo detailed reason of the session update failure + * @param reasonInfo {@link ImsReasonInfo} containing a reason for the session update failure. */ - public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionUpdateFailed(reasonInfo); + public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionUpdateFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session update is received from the remote user. + * The IMS call session profile has received an update from the remote user. + * + * @param profile The new {@link ImsCallProfile} associated with the update. */ - public void callSessionUpdateReceived(ImsCallProfile profile) throws RemoteException { - mListener.callSessionUpdateReceived(profile); + public void callSessionUpdateReceived(ImsCallProfile profile) { + try { + mListener.callSessionUpdateReceived(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** * Called when the session has been extended to a conference session. * - * @param newSession the session object that is extended to the conference - * from the active session + * If the conference extension fails, call + * {@link #callSessionConferenceExtendFailed(ImsReasonInfo)}. + * + * @param newSession the session object that is extended to the conference from the active + * IMS Call session. + * @param profile The {@link ImsCallProfile} associated with the IMS call session. */ - public void callSessionConferenceExtended(ImsCallSession newSession, ImsCallProfile profile) - throws RemoteException { - mListener.callSessionConferenceExtended(newSession != null ? newSession.getSession() : null, - profile); + public void callSessionConferenceExtended(ImsCallSessionImplBase newSession, + ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtended( + newSession != null ? newSession.getServiceImpl() : null, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the session has been extended to a conference session. + * Compatibility method to interface with older versions of ImsService. + * See {@link #callSessionConferenceExtended(ImsCallSessionImplBase, ImsCallProfile)}. * - * @param newSession the session object that is extended to the conference - * from the active session * @hide */ - public void callSessionConferenceExtended(IImsCallSession newSession, ImsCallProfile profile) - throws RemoteException { - mListener.callSessionConferenceExtended(newSession, profile); + public void callSessionConferenceExtended(IImsCallSession newSession, ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtended(newSession, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the conference extension has failed. + * The previous conference extension has failed. * - * @param reasonInfo detailed reason of the conference extension failure + * @param reasonInfo {@link ImsReasonInfo} containing the detailed reason of the conference + * extension failure. */ - public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionConferenceExtendFailed(reasonInfo); + public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionConferenceExtendFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the conference extension is received from the remote user. + * A conference extension has been received received from the remote party. + * + * @param newSession An {@link ImsCallSessionImplBase} + * representing the extended IMS call session. + * @param profile The {@link ImsCallProfile} associated with the new IMS call session. */ - public void callSessionConferenceExtendReceived(ImsCallSession newSession, - ImsCallProfile profile) throws RemoteException { - mListener.callSessionConferenceExtendReceived(newSession != null - ? newSession.getSession() : null, profile); + public void callSessionConferenceExtendReceived(ImsCallSessionImplBase newSession, + ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtendReceived(newSession != null + ? newSession.getServiceImpl() : null, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the conference extension is received from the remote user. + * Compatibility method to interface with older versions of ImsService. + * See {@link #callSessionConferenceExtendReceived(ImsCallSessionImplBase, ImsCallProfile)}. * * @hide */ public void callSessionConferenceExtendReceived(IImsCallSession newSession, - ImsCallProfile profile) throws RemoteException { - mListener.callSessionConferenceExtendReceived(newSession, profile); + ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtendReceived(newSession, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the invitation request of the participants is delivered to the conference + * The request to invite participants to the conference has been delivered to the conference * server. */ - public void callSessionInviteParticipantsRequestDelivered() throws RemoteException { - mListener.callSessionInviteParticipantsRequestDelivered(); + public void callSessionInviteParticipantsRequestDelivered() { + try { + mListener.callSessionInviteParticipantsRequestDelivered(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the invitation request of the participants has failed. + * The previous request to invite participants to the conference (see + * {@link #callSessionInviteParticipantsRequestDelivered()}) has failed. * - * @param reasonInfo detailed reason of the conference invitation failure + * @param reasonInfo {@link ImsReasonInfo} detailing the reason forthe conference invitation + * failure. */ public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) - throws RemoteException { - mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); + { + try { + mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the removal request of the participants is delivered to the conference + * The request to remove participants from the conference has been delivered to the conference * server. */ - public void callSessionRemoveParticipantsRequestDelivered() throws RemoteException { - mListener.callSessionRemoveParticipantsRequestDelivered(); + public void callSessionRemoveParticipantsRequestDelivered() { + try { + mListener.callSessionRemoveParticipantsRequestDelivered(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the removal request of the participants has failed. + * The previous request to remove participants from the conference (see + * {@link #callSessionRemoveParticipantsRequestDelivered()}) has failed. * - * @param reasonInfo detailed reason of the conference removal failure + * @param reasonInfo {@link ImsReasonInfo} detailing the reason for the conference removal + * failure. */ public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) - throws RemoteException { - mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); + { + try { + mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Notifies the framework of the updated Call session conference state. + * The IMS call session's conference state has changed. * - * @param state the new {@link ImsConferenceState} associated with the conference. + * @param state The new {@link ImsConferenceState} associated with the conference. */ - public void callSessionConferenceStateUpdated(ImsConferenceState state) throws RemoteException { - mListener.callSessionConferenceStateUpdated(state); + public void callSessionConferenceStateUpdated(ImsConferenceState state) { + try { + mListener.callSessionConferenceStateUpdated(state); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Notifies the incoming USSD message. + * The IMS call session has received a Ussd message. + * + * @param mode The mode of the USSD message, either + * {@link ImsCallSessionImplBase#USSD_MODE_NOTIFY} or + * {@link ImsCallSessionImplBase#USSD_MODE_REQUEST}. + * @param ussdMessage The USSD message. */ public void callSessionUssdMessageReceived(int mode, String ussdMessage) - throws RemoteException { - mListener.callSessionUssdMessageReceived(mode, ussdMessage); + { + try { + mListener.callSessionUssdMessageReceived(mode, ussdMessage); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Notifies of a case where a {@link com.android.ims.internal.ImsCallSession} may potentially - * handover from one radio technology to another. + * An {@link ImsCallSession} may potentially handover from one radio + * technology to another. * - * @param srcAccessTech The source radio access technology; one of the access technology - * constants defined in {@link android.telephony.ServiceState}. For - * example - * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. + * @param srcAccessTech The source radio access technology; one of the access technology + * constants defined in {@link android.telephony.ServiceState}. For example + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. * @param targetAccessTech The target radio access technology; one of the access technology - * constants defined in {@link android.telephony.ServiceState}. For - * example - * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. + * constants defined in {@link android.telephony.ServiceState}. For example + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. */ public void callSessionMayHandover(int srcAccessTech, int targetAccessTech) - throws RemoteException { - mListener.callSessionMayHandover(srcAccessTech, targetAccessTech); + { + try { + mListener.callSessionMayHandover(srcAccessTech, targetAccessTech); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when session access technology changes. + * The IMS call session's access technology has changed. * - * @param srcAccessTech original access technology - * @param targetAccessTech new access technology - * @param reasonInfo + * @param srcAccessTech original access technology, defined in + * {@link android.telephony.ServiceState}. + * @param targetAccessTech new access technology, defined in + * {@link android.telephony.ServiceState}. + * @param reasonInfo The {@link ImsReasonInfo} associated with this handover. */ public void callSessionHandover(int srcAccessTech, int targetAccessTech, - ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionHandover(srcAccessTech, targetAccessTech, reasonInfo); + ImsReasonInfo reasonInfo) { + try { + mListener.callSessionHandover(srcAccessTech, targetAccessTech, reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when session access technology change fails. + * The IMS call session's access technology change has failed.. * * @param srcAccessTech original access technology * @param targetAccessTech new access technology - * @param reasonInfo handover failure reason + * @param reasonInfo An {@link ImsReasonInfo} detailing the reason for the failure. */ public void callSessionHandoverFailed(int srcAccessTech, int targetAccessTech, - ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionHandoverFailed(srcAccessTech, targetAccessTech, reasonInfo); + ImsReasonInfo reasonInfo) { + try { + mListener.callSessionHandoverFailed(srcAccessTech, targetAccessTech, reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the TTY mode is changed by the remote party. + * The TTY mode has been changed by the remote party. * * @param mode one of the following: - * {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - @@ -360,53 +525,79 @@ public class ImsCallSessionListener { * {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - * {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} */ - public void callSessionTtyModeReceived(int mode) throws RemoteException { - mListener.callSessionTtyModeReceived(mode); + public void callSessionTtyModeReceived(int mode) { + try { + mListener.callSessionTtyModeReceived(mode); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the multiparty state is changed for this {@code ImsCallSession}. + * The multiparty state has been changed for this {@code ImsCallSession}. * - * @param isMultiParty {@code true} if the session became multiparty, - * {@code false} otherwise. + * @param isMultiParty {@code true} if the session became multiparty, {@code false} otherwise. */ - - public void callSessionMultipartyStateChanged(boolean isMultiParty) throws RemoteException { - mListener.callSessionMultipartyStateChanged(isMultiParty); + public void callSessionMultipartyStateChanged(boolean isMultiParty) { + try { + mListener.callSessionMultipartyStateChanged(isMultiParty); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Called when the supplementary service information is received for the current session. + * Supplementary service information has been received for the current IMS call session. + * + * @param suppSrvNotification The {@link ImsSuppServiceNotification} containing the change. */ public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppSrvNotification) - throws RemoteException { - mListener.callSessionSuppServiceReceived(suppSrvNotification); + { + try { + mListener.callSessionSuppServiceReceived(suppSrvNotification); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Received RTT modify request from the remote party. + * An RTT modify request has been received from the remote party. * - * @param callProfile ImsCallProfile with updated attributes + * @param callProfile An {@link ImsCallProfile} with the updated attributes */ public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) - throws RemoteException { - mListener.callSessionRttModifyRequestReceived(callProfile); + { + try { + mListener.callSessionRttModifyRequestReceived(callProfile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** + * An RTT modify response has been received. + * * @param status the received response for RTT modify request. */ - public void callSessionRttModifyResponseReceived(int status) throws RemoteException { - mListener.callSessionRttModifyResponseReceived(status); + public void callSessionRttModifyResponseReceived(int status) { + try { + mListener.callSessionRttModifyResponseReceived(status); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } /** - * Device received RTT message from Remote UE. + * An RTT message has been received from the remote party. * - * @param rttMessage RTT message received - */ - public void callSessionRttMessageReceived(String rttMessage) throws RemoteException { - mListener.callSessionRttMessageReceived(rttMessage); + * @param rttMessage The RTT message that has been received. + */ + public void callSessionRttMessageReceived(String rttMessage) { + try { + mListener.callSessionRttMessageReceived(rttMessage); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } } diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.aidl b/telephony/java/android/telephony/ims/ImsConferenceState.aidl new file mode 100644 index 000000000000..e2b371c1440e --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsConferenceState.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable ImsConferenceState; diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java new file mode 100644 index 000000000000..66d2f8d929d3 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsConferenceState.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; + +import android.annotation.SystemApi; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.telecom.Call; +import android.telecom.Connection; + +/** + * Provides the conference information (defined in RFC 4575) for IMS conference call. + * + * @hide + */ +@SystemApi +public final class ImsConferenceState implements Parcelable { + /** + * conference-info : user + */ + // user (String) : Tel or SIP URI + public static final String USER = "user"; + // user > display text (String) + public static final String DISPLAY_TEXT = "display-text"; + // user > endpoint (String) : URI or GRUU or Phone number + public static final String ENDPOINT = "endpoint"; + // user > endpoint > status + public static final String STATUS = "status"; + + /** + * status-type (String) : + * "pending" : Endpoint is not yet in the session, but it is anticipated that he/she will + * join in the near future. + * "dialing-out" : Focus has dialed out to connect the endpoint to the conference, + * but the endpoint is not yet in the roster (probably being authenticated). + * "dialing-in" : Endpoint is dialing into the conference, not yet in the roster + * (probably being authenticated). + * "alerting" : PSTN alerting or SIP 180 Ringing was returned for the outbound call; + * endpoint is being alerted. + * "on-hold" : Active signaling dialog exists between an endpoint and a focus, + * but endpoint is "on-hold" for this conference, i.e., he/she is neither "hearing" + * the conference mix nor is his/her media being mixed in the conference. + * "connected" : Endpoint is a participant in the conference. Depending on the media policies, + * he/she can send and receive media to and from other participants. + * "disconnecting" : Focus is in the process of disconnecting the endpoint + * (e.g. in SIP a DISCONNECT or BYE was sent to the endpoint). + * "disconnected" : Endpoint is not a participant in the conference, and no active dialog + * exists between the endpoint and the focus. + * "muted-via-focus" : Active signaling dialog exists beween an endpoint and a focus and + * the endpoint can "listen" to the conference, but the endpoint's media is not being + * mixed into the conference. + * "connect-fail" : Endpoint fails to join the conference by rejecting the conference call. + */ + public static final String STATUS_PENDING = "pending"; + public static final String STATUS_DIALING_OUT = "dialing-out"; + public static final String STATUS_DIALING_IN = "dialing-in"; + public static final String STATUS_ALERTING = "alerting"; + public static final String STATUS_ON_HOLD = "on-hold"; + public static final String STATUS_CONNECTED = "connected"; + public static final String STATUS_DISCONNECTING = "disconnecting"; + public static final String STATUS_DISCONNECTED = "disconnected"; + public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus"; + public static final String STATUS_CONNECT_FAIL = "connect-fail"; + public static final String STATUS_SEND_ONLY = "sendonly"; + public static final String STATUS_SEND_RECV = "sendrecv"; + + /** + * conference-info : SIP status code (integer) + */ + public static final String SIP_STATUS_CODE = "sipstatuscode"; + + public final HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>(); + + /** @hide */ + public ImsConferenceState() { + } + + private ImsConferenceState(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mParticipants.size()); + + if (mParticipants.size() > 0) { + Set<Entry<String, Bundle>> entries = mParticipants.entrySet(); + + if (entries != null) { + Iterator<Entry<String, Bundle>> iterator = entries.iterator(); + + while (iterator.hasNext()) { + Entry<String, Bundle> entry = iterator.next(); + + out.writeString(entry.getKey()); + out.writeParcelable(entry.getValue(), 0); + } + } + } + } + + private void readFromParcel(Parcel in) { + int size = in.readInt(); + + for (int i = 0; i < size; ++i) { + String user = in.readString(); + Bundle state = in.readParcelable(null); + mParticipants.put(user, state); + } + } + + public static final Creator<ImsConferenceState> CREATOR = + new Creator<ImsConferenceState>() { + @Override + public ImsConferenceState createFromParcel(Parcel in) { + return new ImsConferenceState(in); + } + + @Override + public ImsConferenceState[] newArray(int size) { + return new ImsConferenceState[size]; + } + }; + + /** + * Translates an {@code ImsConferenceState} status type to a telecom connection state. + * + * @param status The status type. + * @return The corresponding {@link android.telecom.Connection} state. + */ + public static int getConnectionStateForStatus(String status) { + if (status.equals(STATUS_PENDING)) { + return Connection.STATE_INITIALIZING; + } else if (status.equals(STATUS_DIALING_IN)) { + return Connection.STATE_RINGING; + } else if (status.equals(STATUS_ALERTING) || + status.equals(STATUS_DIALING_OUT)) { + return Connection.STATE_DIALING; + } else if (status.equals(STATUS_ON_HOLD) || + status.equals(STATUS_SEND_ONLY)) { + return Connection.STATE_HOLDING; + } else if (status.equals(STATUS_CONNECTED) || + status.equals(STATUS_MUTED_VIA_FOCUS) || + status.equals(STATUS_DISCONNECTING) || + status.equals(STATUS_SEND_RECV)) { + return Connection.STATE_ACTIVE; + } else if (status.equals(STATUS_DISCONNECTED)) { + return Connection.STATE_DISCONNECTED; + } + return Call.STATE_ACTIVE; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + sb.append(ImsConferenceState.class.getSimpleName()); + sb.append(" "); + if (mParticipants.size() > 0) { + Set<Entry<String, Bundle>> entries = mParticipants.entrySet(); + + if (entries != null) { + Iterator<Entry<String, Bundle>> iterator = entries.iterator(); + sb.append("<"); + while (iterator.hasNext()) { + Entry<String, Bundle> entry = iterator.next(); + sb.append(entry.getKey()); + sb.append(": "); + Bundle participantData = entry.getValue(); + + for (String key : participantData.keySet()) { + sb.append(key); + sb.append("="); + if (ENDPOINT.equals(key) || USER.equals(key)) { + sb.append(android.telecom.Log.pii(participantData.get(key))); + } else { + sb.append(participantData.get(key)); + } + sb.append(", "); + } + } + sb.append(">"); + } + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.aidl b/telephony/java/android/telephony/ims/ImsExternalCallState.aidl new file mode 100644 index 000000000000..99d293566806 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2016 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.telephony.ims; + +parcelable ImsExternalCallState; diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java new file mode 100644 index 000000000000..e82c115cb4b3 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.telecom.Log; +import android.telephony.Rlog; + +/* + * This file contains all the api's through which + * information received in Dialog Event Package can be + * queried + */ + +/** + * Parcelable object to handle MultiEndpoint Dialog Information + * @hide + */ +@SystemApi +public final class ImsExternalCallState implements Parcelable { + + private static final String TAG = "ImsExternalCallState"; + + // Dialog States + public static final int CALL_STATE_CONFIRMED = 1; + public static final int CALL_STATE_TERMINATED = 2; + // Dialog Id + private int mCallId; + // Number + private Uri mAddress; + private boolean mIsPullable; + // CALL_STATE_CONFIRMED / CALL_STATE_TERMINATED + private int mCallState; + // ImsCallProfile#CALL_TYPE_* + private int mCallType; + private boolean mIsHeld; + + /** @hide */ + public ImsExternalCallState() { + } + + /** @hide */ + public ImsExternalCallState(int callId, Uri address, boolean isPullable, int callState, + int callType, boolean isCallheld) { + mCallId = callId; + mAddress = address; + mIsPullable = isPullable; + mCallState = callState; + mCallType = callType; + mIsHeld = isCallheld; + Rlog.d(TAG, "ImsExternalCallState = " + this); + } + + /** @hide */ + public ImsExternalCallState(Parcel in) { + mCallId = in.readInt(); + ClassLoader classLoader = ImsExternalCallState.class.getClassLoader(); + mAddress = in.readParcelable(classLoader); + mIsPullable = (in.readInt() != 0); + mCallState = in.readInt(); + mCallType = in.readInt(); + mIsHeld = (in.readInt() != 0); + Rlog.d(TAG, "ImsExternalCallState const = " + this); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mCallId); + out.writeParcelable(mAddress, 0); + out.writeInt(mIsPullable ? 1 : 0); + out.writeInt(mCallState); + out.writeInt(mCallType); + out.writeInt(mIsHeld ? 1 : 0); + Rlog.d(TAG, "ImsExternalCallState writeToParcel = " + out.toString()); + } + + public static final Parcelable.Creator<ImsExternalCallState> CREATOR = + new Parcelable.Creator<ImsExternalCallState>() { + @Override + public ImsExternalCallState createFromParcel(Parcel in) { + return new ImsExternalCallState(in); + } + + @Override + public ImsExternalCallState[] newArray(int size) { + return new ImsExternalCallState[size]; + } + }; + + public int getCallId() { + return mCallId; + } + + public Uri getAddress() { + return mAddress; + } + + public boolean isCallPullable() { + return mIsPullable; + } + + public int getCallState() { + return mCallState; + } + + public int getCallType() { + return mCallType; + } + + public boolean isCallHeld() { + return mIsHeld; + } + + @Override + public String toString() { + return "ImsExternalCallState { mCallId = " + mCallId + + ", mAddress = " + Log.pii(mAddress) + + ", mIsPullable = " + mIsPullable + + ", mCallState = " + mCallState + + ", mCallType = " + mCallType + + ", mIsHeld = " + mIsHeld + "}"; + } +} diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.aidl b/telephony/java/android/telephony/ims/ImsReasonInfo.aidl new file mode 100644 index 000000000000..604b323d1292 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable ImsReasonInfo; diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java new file mode 100644 index 000000000000..52a6ab902d9a --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -0,0 +1,512 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * This class enables an application to get details on why a method call failed. + * + * @hide + */ +@SystemApi +public final class ImsReasonInfo implements Parcelable { + + /** + * Specific code of each types + */ + public static final int CODE_UNSPECIFIED = 0; + + /** + * LOCAL + */ + // IMS -> Telephony + // The passed argument is an invalid + public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; + // The operation is invoked in invalid call state + public static final int CODE_LOCAL_ILLEGAL_STATE = 102; + // IMS service internal error + public static final int CODE_LOCAL_INTERNAL_ERROR = 103; + // IMS service goes down (service connection is lost) + public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; + // No pending incoming call exists + public static final int CODE_LOCAL_NO_PENDING_CALL = 107; + // IMS Call ended during conference merge process + public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; + + // IMS -> Telephony + // Service unavailable; by power off + public static final int CODE_LOCAL_POWER_OFF = 111; + // Service unavailable; by low battery + public static final int CODE_LOCAL_LOW_BATTERY = 112; + // Service unavailable; by out of service (data service state) + public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; + // Service unavailable; by no LTE coverage + // (VoLTE is not supported even though IMS is registered) + public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; + // Service unavailable; by located in roaming area + public static final int CODE_LOCAL_NETWORK_ROAMING = 123; + // Service unavailable; by IP changed + public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; + // Service unavailable; other + public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; + // Service unavailable; IMS connection is lost (IMS is not registered) + public static final int CODE_LOCAL_NOT_REGISTERED = 132; + + // IMS <-> Telephony + // Max call exceeded + public static final int CODE_LOCAL_CALL_EXCEEDED = 141; + // IMS <- Telephony + // Call busy + public static final int CODE_LOCAL_CALL_BUSY = 142; + // Call decline + public static final int CODE_LOCAL_CALL_DECLINE = 143; + // IMS -> Telephony + // SRVCC is in progress + public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; + // Resource reservation is failed (QoS precondition) + public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; + // Retry CS call; VoLTE service can't be provided by the network or remote end + // Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set + public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; + // Retry VoLTE call; VoLTE service can't be provided by the network temporarily + public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; + // IMS call is already terminated (in TERMINATED state) + public static final int CODE_LOCAL_CALL_TERMINATED = 148; + // Handover not feasible + public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; + + /** + * TIMEOUT (IMS -> Telephony) + */ + // 1xx waiting timer is expired after sending INVITE request (MO only) + public static final int CODE_TIMEOUT_1XX_WAITING = 201; + // User no answer during call setup operation (MO/MT) + // MO : 200 OK to INVITE request is not received, + // MT : No action from user after alerting the call + public static final int CODE_TIMEOUT_NO_ANSWER = 202; + // User no answer during call update operation (MO/MT) + // MO : 200 OK to re-INVITE request is not received, + // MT : No action from user after alerting the call + public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; + + //Call was blocked by call barring + public static final int CODE_CALL_BARRED = 240; + + //Call failures for FDN + public static final int CODE_FDN_BLOCKED = 241; + + // Network does not accept the emergency call request because IMEI was used as identification + // and this capability is not supported by the network. + public static final int CODE_IMEI_NOT_ACCEPTED = 243; + + //STK CC errors + public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; + public static final int CODE_DIAL_MODIFIED_TO_SS = 245; + public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; + public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; + public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; + public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; + public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; + public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; + + /** + * STATUSCODE (SIP response code) (IMS -> Telephony) + */ + // 3xx responses + // SIP request is redirected + public static final int CODE_SIP_REDIRECTED = 321; + // 4xx responses + // 400 : Bad Request + public static final int CODE_SIP_BAD_REQUEST = 331; + // 403 : Forbidden + public static final int CODE_SIP_FORBIDDEN = 332; + // 404 : Not Found + public static final int CODE_SIP_NOT_FOUND = 333; + // 415 : Unsupported Media Type + // 416 : Unsupported URI Scheme + // 420 : Bad Extension + public static final int CODE_SIP_NOT_SUPPORTED = 334; + // 408 : Request Timeout + public static final int CODE_SIP_REQUEST_TIMEOUT = 335; + // 480 : Temporarily Unavailable + public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; + // 484 : Address Incomplete + public static final int CODE_SIP_BAD_ADDRESS = 337; + // 486 : Busy Here + // 600 : Busy Everywhere + public static final int CODE_SIP_BUSY = 338; + // 487 : Request Terminated + public static final int CODE_SIP_REQUEST_CANCELLED = 339; + // 406 : Not Acceptable + // 488 : Not Acceptable Here + // 606 : Not Acceptable + public static final int CODE_SIP_NOT_ACCEPTABLE = 340; + // 410 : Gone + // 604 : Does Not Exist Anywhere + public static final int CODE_SIP_NOT_REACHABLE = 341; + // Others + public static final int CODE_SIP_CLIENT_ERROR = 342; + // 5xx responses + // 501 : Server Internal Error + public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; + // 503 : Service Unavailable + public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; + // 504 : Server Time-out + public static final int CODE_SIP_SERVER_TIMEOUT = 353; + // Others + public static final int CODE_SIP_SERVER_ERROR = 354; + // 6xx responses + // 603 : Decline + public static final int CODE_SIP_USER_REJECTED = 361; + // Others + public static final int CODE_SIP_GLOBAL_ERROR = 362; + // Emergency failure + public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; + public static final int CODE_EMERGENCY_PERM_FAILURE = 364; + + /** + * MEDIA (IMS -> Telephony) + */ + // Media resource initialization failed + public static final int CODE_MEDIA_INIT_FAILED = 401; + // RTP timeout (no audio / video traffic in the session) + public static final int CODE_MEDIA_NO_DATA = 402; + // Media is not supported; so dropped the call + public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; + // Unknown media related errors + public static final int CODE_MEDIA_UNSPECIFIED = 404; + + /** + * USER + */ + // Telephony -> IMS + // User triggers the call end + public static final int CODE_USER_TERMINATED = 501; + // No action while an incoming call is ringing + public static final int CODE_USER_NOANSWER = 502; + // User ignores an incoming call + public static final int CODE_USER_IGNORE = 503; + // User declines an incoming call + public static final int CODE_USER_DECLINE = 504; + // Device declines/ends a call due to low battery + public static final int CODE_LOW_BATTERY = 505; + // Device declines call due to blacklisted call ID + public static final int CODE_BLACKLISTED_CALL_ID = 506; + // IMS -> Telephony + // The call is terminated by the network or remote user + public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; + + /** + * Extra codes for the specific code value + * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED. + */ + // Try to connect CS call; normal + public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; + // Try to connect CS call without the notification to user + public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; + // Try to connect CS call by the settings of the menu + public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; + + /** + * UT + */ + public static final int CODE_UT_NOT_SUPPORTED = 801; + public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; + public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; + public static final int CODE_UT_NETWORK_ERROR = 804; + public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; + //STK CC errors + public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; + public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; + public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; + public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; + + /** + * ECBM + */ + public static final int CODE_ECBM_NOT_SUPPORTED = 901; + + /** + * Fail code used to indicate that Multi-endpoint is not supported by the Ims framework. + */ + public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; + + /** + * Ims Registration error code + */ + public static final int CODE_REGISTRATION_ERROR = 1000; + + /** + * CALL DROP error codes (Call could drop because of many reasons like Network not available, + * handover, failed, etc) + */ + + /** + * CALL DROP error code for the case when a device is ePDG capable and when the user is on an + * active wifi call and at the edge of coverage and there is no qualified LTE network available + * to handover the call to. We get a handover NOT_TRIGERRED message from the modem. This error + * code is received as part of the handover message. + */ + public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; + + /** + * MT call has ended due to a release from the network + * because the call was answered elsewhere + */ + public static final int CODE_ANSWERED_ELSEWHERE = 1014; + + /** + * For MultiEndpoint - Call Pull request has failed + */ + public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; + + /** + * For MultiEndpoint - Call has been pulled from primary to secondary + */ + public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; + + /** + * Supplementary services (HOLD/RESUME) failure error codes. + * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision. + */ + public static final int CODE_SUPP_SVC_FAILED = 1201; + public static final int CODE_SUPP_SVC_CANCELLED = 1202; + public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; + + /** + * DPD Procedure received no response or send failed + */ + public static final int CODE_IWLAN_DPD_FAILURE = 1300; + + /** + * Establishment of the ePDG Tunnel Failed + */ + public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; + + /** + * Re-keying of the ePDG Tunnel Failed; may not always result in teardown + */ + public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; + + /** + * Connection to the packet gateway is lost + */ + public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; + + /** + * The maximum number of calls allowed has been reached. Used in a multi-endpoint scenario + * where the number of calls across all connected devices has reached the maximum. + */ + public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403; + + /** + * Similar to {@link #CODE_LOCAL_CALL_DECLINE}, except indicates that a remote device has + * declined the call. Used in a multi-endpoint scenario where a remote device declined an + * incoming call. + */ + public static final int CODE_REMOTE_CALL_DECLINE = 1404; + + /** + * Indicates the call was disconnected due to the user reaching their data limit. + */ + public static final int CODE_DATA_LIMIT_REACHED = 1405; + + /** + * Indicates the call was disconnected due to the user disabling cellular data. + */ + public static final int CODE_DATA_DISABLED = 1406; + + /** + * Indicates a call was disconnected due to loss of wifi signal. + */ + public static final int CODE_WIFI_LOST = 1407; + + /** + * Indicates the registration attempt on IWLAN failed due to IKEv2 authetication failure + * during tunnel establishment. + */ + public static final int CODE_IKEV2_AUTH_FAILURE = 1408; + + /** The call cannot be established because RADIO is OFF */ + public static final int CODE_RADIO_OFF = 1500; + + /** The call cannot be established because of no valid SIM */ + public static final int CODE_NO_VALID_SIM = 1501; + + /** The failure is due internal error at modem */ + public static final int CODE_RADIO_INTERNAL_ERROR = 1502; + + /** The failure is due to UE timer expired while waiting for a response from network */ + public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; + + /** The failure is due to explicit reject from network */ + public static final int CODE_NETWORK_REJECT = 1504; + + /** The failure is due to radio access failure. ex. RACH failure */ + public static final int CODE_RADIO_ACCESS_FAILURE = 1505; + + /** Call/IMS registration failed/dropped because of a RLF */ + public static final int CODE_RADIO_LINK_FAILURE = 1506; + + /** Call/IMS registration failed/dropped because of radio link lost */ + public static final int CODE_RADIO_LINK_LOST = 1507; + + /** The call Call/IMS registration failed because of a radio uplink issue */ + public static final int CODE_RADIO_UPLINK_FAILURE = 1508; + + /** Call failed because of a RRC connection setup failure */ + public static final int CODE_RADIO_SETUP_FAILURE = 1509; + + /** Call failed/dropped because of RRC connection release from NW */ + public static final int CODE_RADIO_RELEASE_NORMAL = 1510; + + /** Call failed/dropped because of RRC abnormally released by modem/network */ + public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511; + + /** Call failed because of access class barring */ + public static final int CODE_ACCESS_CLASS_BLOCKED = 1512; + + /** Call/IMS registration is failed/dropped because of a network detach */ + public static final int CODE_NETWORK_DETACH = 1513; + + /** + * Call failed due to SIP code 380 (Alternative Service response) while dialing an "undetected + * emergency number". This scenario is important in some regions where the carrier network will + * identify other non-emergency help numbers (e.g. mountain rescue) when attempting to dial. + */ + public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; + + /* OEM specific error codes. To be used by OEMs when they don't want to + reveal error code which would be replaced by ERROR_UNSPECIFIED */ + public static final int CODE_OEM_CAUSE_1 = 0xf001; + public static final int CODE_OEM_CAUSE_2 = 0xf002; + public static final int CODE_OEM_CAUSE_3 = 0xf003; + public static final int CODE_OEM_CAUSE_4 = 0xf004; + public static final int CODE_OEM_CAUSE_5 = 0xf005; + public static final int CODE_OEM_CAUSE_6 = 0xf006; + public static final int CODE_OEM_CAUSE_7 = 0xf007; + public static final int CODE_OEM_CAUSE_8 = 0xf008; + public static final int CODE_OEM_CAUSE_9 = 0xf009; + public static final int CODE_OEM_CAUSE_10 = 0xf00a; + public static final int CODE_OEM_CAUSE_11 = 0xf00b; + public static final int CODE_OEM_CAUSE_12 = 0xf00c; + public static final int CODE_OEM_CAUSE_13 = 0xf00d; + public static final int CODE_OEM_CAUSE_14 = 0xf00e; + public static final int CODE_OEM_CAUSE_15 = 0xf00f; + + /** + * Network string error messages. + * mExtraMessage may have these values. + */ + public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED + = "Forbidden. Not Authorized for Service"; + + + // For main reason code + /** @hide */ + public final int mCode; + // For the extra code value; it depends on the code value. + /** @hide */ + public final int mExtraCode; + // For the additional message of the reason info. + /** @hide */ + public final String mExtraMessage; + + /** @hide */ + public ImsReasonInfo() { + mCode = CODE_UNSPECIFIED; + mExtraCode = CODE_UNSPECIFIED; + mExtraMessage = null; + } + + private ImsReasonInfo(Parcel in) { + mCode = in.readInt(); + mExtraCode = in.readInt(); + mExtraMessage = in.readString(); + } + + /** @hide */ + public ImsReasonInfo(int code, int extraCode) { + mCode = code; + mExtraCode = extraCode; + mExtraMessage = null; + } + + /** @hide */ + public ImsReasonInfo(int code, int extraCode, String extraMessage) { + mCode = code; + mExtraCode = extraCode; + mExtraMessage = extraMessage; + } + + /** + * + */ + public int getCode() { + return mCode; + } + + /** + * + */ + public int getExtraCode() { + return mExtraCode; + } + + /** + * + */ + public String getExtraMessage() { + return mExtraMessage; + } + + /** + * Returns the string format of {@link ImsReasonInfo} + * + * @return the string format of {@link ImsReasonInfo} + */ + public String toString() { + return "ImsReasonInfo :: {" + mCode + ", " + mExtraCode + ", " + mExtraMessage + "}"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mCode); + out.writeInt(mExtraCode); + out.writeString(mExtraMessage); + } + + public static final Creator<ImsReasonInfo> CREATOR = new Creator<ImsReasonInfo>() { + @Override + public ImsReasonInfo createFromParcel(Parcel in) { + return new ImsReasonInfo(in); + } + + @Override + public ImsReasonInfo[] newArray(int size) { + return new ImsReasonInfo[size]; + } + }; +} diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index 2f32bae88f03..2748cb5470bf 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -51,9 +51,7 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE; * ... * <service android:name=".EgImsService" * android:permission="android.permission.BIND_IMS_SERVICE" > - * <!-- Apps must declare which features they support as metadata. The different categories are - * defined below. In this example, the RCS_FEATURE feature is supported. --> - * <meta-data android:name="android.telephony.ims.RCS_FEATURE" android:value="true" /> + * ... * <intent-filter> * <action android:name="android.telephony.ims.ImsService" /> * </intent-filter> @@ -65,12 +63,33 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE; * 1) Defined as the default ImsService for the device in the device overlay using * "config_ims_package". * 2) Defined as a Carrier Provided ImsService in the Carrier Configuration using - * {@link CarrierConfigManager#KEY_CTONFIG_IMS_PACKAGE_OVERRIDE_STRING}. + * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}. + * + * There are two ways to define to the platform which {@link ImsFeature}s this {@link ImsService} + * supports, dynamic or static definitions. + * + * In the static definition, the {@link ImsFeature}s that are supported are defined in the service + * definition of the AndroidManifest.xml file as metadata: + * <!-- Apps must declare which features they support as metadata. The different categories are + * defined below. In this example, the MMTEL_FEATURE feature is supported. --> + * <meta-data android:name="android.telephony.ims.MMTEL_FEATURE" android:value="true" /> * * The features that are currently supported in an ImsService are: * - RCS_FEATURE: This ImsService implements the RcsFeature class. * - MMTEL_FEATURE: This ImsService implements the MmTelFeature class. - * @hide + * - EMERGENCY_MMTEL_FEATURE: This ImsService supports Emergency Calling for MMTEL, must be + * declared along with the MMTEL_FEATURE. If this is not specified, the framework will use + * circuit switch for emergency calling. + * + * In the dynamic definition, the supported features are not specified in the service definition + * of the AndroidManifest. Instead, the framework binds to this service and calls + * {@link #querySupportedImsFeatures()}. The {@link ImsService} then returns an + * {@link ImsFeatureConfiguration}, which the framework uses to initialize the supported + * {@link ImsFeature}s. If at any time, the list of supported {@link ImsFeature}s changes, + * {@link #onUpdateSupportedImsFeatures(ImsFeatureConfiguration)} can be called to tell the + * framework of the changes. + * + * @hide */ @SystemApi public class ImsService extends Service { @@ -127,8 +146,7 @@ public class ImsService extends Service { } @Override - public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c) - throws RemoteException { + public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c) { ImsService.this.removeImsFeature(slotId, featureType, c); } @@ -143,19 +161,18 @@ public class ImsService extends Service { } @Override - public void notifyImsFeatureReady(int slotId, int featureType) - throws RemoteException { + public void notifyImsFeatureReady(int slotId, int featureType) { ImsService.this.notifyImsFeatureReady(slotId, featureType); } @Override - public IImsConfig getConfig(int slotId) throws RemoteException { + public IImsConfig getConfig(int slotId) { ImsConfigImplBase c = ImsService.this.getConfig(slotId); return c != null ? c.getIImsConfig() : null; } @Override - public IImsRegistration getRegistration(int slotId) throws RemoteException { + public IImsRegistration getRegistration(int slotId) { ImsRegistrationImplBase r = ImsService.this.getRegistration(slotId); return r != null ? r.getBinder() : null; } @@ -277,12 +294,14 @@ public class ImsService extends Service { } /** - * When called, provide the {@link ImsFeatureConfiguration} that this ImsService currently - * supports. This will trigger the framework to set up the {@link ImsFeature}s that correspond - * to the {@link ImsFeature.FeatureType}s configured here. - * @return an {@link ImsFeatureConfiguration} containing Features this ImsService supports, - * defined in {@link ImsFeature.FeatureType}. - * @hide + * When called, provide the {@link ImsFeatureConfiguration} that this {@link ImsService} + * currently supports. This will trigger the framework to set up the {@link ImsFeature}s that + * correspond to the {@link ImsFeature}s configured here. + * + * Use {@link #onUpdateSupportedImsFeatures(ImsFeatureConfiguration)} to change the supported + * {@link ImsFeature}s. + * + * @return an {@link ImsFeatureConfiguration} containing Features this ImsService supports. */ public ImsFeatureConfiguration querySupportedImsFeatures() { // Return empty for base implementation @@ -291,9 +310,8 @@ public class ImsService extends Service { /** * Updates the framework with a new {@link ImsFeatureConfiguration} containing the updated - * features, defined in {@link ImsFeature.FeatureType} that this ImsService supports. This may - * trigger the framework to add/remove new ImsFeatures, depending on the configuration. - * @hide + * features, that this {@link ImsService} supports. This may trigger the framework to add/remove + * new ImsFeatures, depending on the configuration. */ public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) throws RemoteException { @@ -306,11 +324,12 @@ public class ImsService extends Service { /** * The ImsService has been bound and is ready for ImsFeature creation based on the Features that * the ImsService has registered for with the framework, either in the manifest or via + * {@link #querySupportedImsFeatures()}. + * * The ImsService should use this signal instead of onCreate/onBind or similar to perform * feature initialization because the framework may bind to this service multiple times to * query the ImsService's {@link ImsFeatureConfiguration} via * {@link #querySupportedImsFeatures()}before creating features. - * @hide */ public void readyForFeatureCreation() { } @@ -318,7 +337,6 @@ public class ImsService extends Service { /** * The framework has enabled IMS for the slot specified, the ImsService should register for IMS * and perform all appropriate initialization to bring up all ImsFeatures. - * @hide */ public void enableIms(int slotId) { } @@ -326,50 +344,50 @@ public class ImsService extends Service { /** * The framework has disabled IMS for the slot specified. The ImsService must deregister for IMS * and set capability status to false for all ImsFeatures. - * @hide */ public void disableIms(int slotId) { } /** - * When called, the framework is requesting that a new MmTelFeature is created for the specified - * slot. + * When called, the framework is requesting that a new {@link MmTelFeature} is created for the + * specified slot. * - * @param slotId The slot ID that the MMTel Feature is being created for. - * @return The newly created MmTelFeature associated with the slot or null if the feature is not - * supported. - * @hide + * @param slotId The slot ID that the MMTEL Feature is being created for. + * @return The newly created {@link MmTelFeature} associated with the slot or null if the + * feature is not supported. */ public MmTelFeature createMmTelFeature(int slotId) { return null; } /** - * When called, the framework is requesting that a new RcsFeature is created for the specified - * slot + * When called, the framework is requesting that a new {@link RcsFeature} is created for the + * specified slot. * * @param slotId The slot ID that the RCS Feature is being created for. - * @return The newly created RcsFeature associated with the slot or null if the feature is not - * supported. - * @hide + * @return The newly created {@link RcsFeature} associated with the slot or null if the feature + * is not supported. */ public RcsFeature createRcsFeature(int slotId) { return null; } /** + * Return the {@link ImsConfigImplBase} implementation associated with the provided slot. This + * will be used by the platform to get/set specific IMS related configurations. + * * @param slotId The slot that the IMS configuration is associated with. * @return ImsConfig implementation that is associated with the specified slot. - * @hide */ public ImsConfigImplBase getConfig(int slotId) { return new ImsConfigImplBase(); } /** + * Return the {@link ImsRegistrationImplBase} implementation associated with the provided slot. + * * @param slotId The slot that is associated with the IMS Registration. * @return the ImsRegistration implementation associated with the slot. - * @hide */ public ImsRegistrationImplBase getRegistration(int slotId) { return new ImsRegistrationImplBase(); diff --git a/telephony/java/android/telephony/ims/ImsSsData.aidl b/telephony/java/android/telephony/ims/ImsSsData.aidl new file mode 100644 index 000000000000..eff3a6b0acc7 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsSsData.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017 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.telephony.ims; + +parcelable ImsSsData; diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java new file mode 100644 index 000000000000..1ddf1994f26b --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsSsData.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provided STK Call Control Suplementary Service information + * + * {@hide} + */ +@SystemApi +public final class ImsSsData implements Parcelable { + + //ServiceType + public static final int SS_CFU = 0; + public static final int SS_CF_BUSY = 1; + public static final int SS_CF_NO_REPLY = 2; + public static final int SS_CF_NOT_REACHABLE = 3; + public static final int SS_CF_ALL = 4; + public static final int SS_CF_ALL_CONDITIONAL = 5; + public static final int SS_CFUT = 6; + public static final int SS_CLIP = 7; + public static final int SS_CLIR = 8; + public static final int SS_COLP = 9; + public static final int SS_COLR = 10; + public static final int SS_CNAP = 11; + public static final int SS_WAIT = 12; + public static final int SS_BAOC = 13; + public static final int SS_BAOIC = 14; + public static final int SS_BAOIC_EXC_HOME = 15; + public static final int SS_BAIC = 16; + public static final int SS_BAIC_ROAMING = 17; + public static final int SS_ALL_BARRING = 18; + public static final int SS_OUTGOING_BARRING = 19; + public static final int SS_INCOMING_BARRING = 20; + public static final int SS_INCOMING_BARRING_DN = 21; + public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; + + //SSRequestType + public static final int SS_ACTIVATION = 0; + public static final int SS_DEACTIVATION = 1; + public static final int SS_INTERROGATION = 2; + public static final int SS_REGISTRATION = 3; + public static final int SS_ERASURE = 4; + + //TeleserviceType + public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; + public static final int SS_ALL_TELESEVICES = 1; + public static final int SS_TELEPHONY = 2; + public static final int SS_ALL_DATA_TELESERVICES = 3; + public static final int SS_SMS_SERVICES = 4; + public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; + + // Refer to ServiceType + /** @hide */ + public int serviceType; + // Refere to SSRequestType + /** @hide */ + public int requestType; + // Refer to TeleserviceType + /** @hide */ + public int teleserviceType; + // Service Class + /** @hide */ + public int serviceClass; + // Error information + /** @hide */ + public int result; + + /** @hide */ + public int[] ssInfo; /* Valid for all supplementary services. + This field will be empty for RequestType SS_INTERROGATION + and ServiceType SS_CF_*, SS_INCOMING_BARRING_DN, + SS_INCOMING_BARRING_ANONYMOUS.*/ + + /** @hide */ + public ImsCallForwardInfo[] cfInfo; /* Valid only for supplementary services + ServiceType SS_CF_* and RequestType SS_INTERROGATION */ + + /** @hide */ + public ImsSsInfo[] imsSsInfo; /* Valid only for ServiceType SS_INCOMING_BARRING_DN and + ServiceType SS_INCOMING_BARRING_ANONYMOUS */ + + public ImsSsData() {} + + private ImsSsData(Parcel in) { + readFromParcel(in); + } + + public static final Creator<ImsSsData> CREATOR = new Creator<ImsSsData>() { + @Override + public ImsSsData createFromParcel(Parcel in) { + return new ImsSsData(in); + } + + @Override + public ImsSsData[] newArray(int size) { + return new ImsSsData[size]; + } + }; + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(serviceType); + out.writeInt(requestType); + out.writeInt(teleserviceType); + out.writeInt(serviceClass); + out.writeInt(result); + out.writeIntArray(ssInfo); + out.writeParcelableArray(cfInfo, 0); + } + + private void readFromParcel(Parcel in) { + serviceType = in.readInt(); + requestType = in.readInt(); + teleserviceType = in.readInt(); + serviceClass = in.readInt(); + result = in.readInt(); + ssInfo = in.createIntArray(); + cfInfo = (ImsCallForwardInfo[])in.readParcelableArray(this.getClass().getClassLoader()); + } + + @Override + public int describeContents() { + return 0; + } + + /** + * Old method, kept for compatibility. See {@link #isTypeCf()} + * @hide + */ + public boolean isTypeCF() { + return (serviceType == SS_CFU || serviceType == SS_CF_BUSY || + serviceType == SS_CF_NO_REPLY || serviceType == SS_CF_NOT_REACHABLE || + serviceType == SS_CF_ALL || serviceType == SS_CF_ALL_CONDITIONAL); + } + + public boolean isTypeCf() { + return isTypeCF(); + } + + public boolean isTypeUnConditional() { + return (serviceType == SS_CFU || serviceType == SS_CF_ALL); + } + + /** + * Old method, kept for compatibility. See {@link #isTypeCf()} + * @hide + */ + public boolean isTypeCW() { + return (serviceType == SS_WAIT); + } + + public boolean isTypeCw() { + return isTypeCW(); + } + + public boolean isTypeClip() { + return (serviceType == SS_CLIP); + } + + public boolean isTypeColr() { + return (serviceType == SS_COLR); + } + + public boolean isTypeColp() { + return (serviceType == SS_COLP); + } + + public boolean isTypeClir() { + return (serviceType == SS_CLIR); + } + + public boolean isTypeIcb() { + return (serviceType == SS_INCOMING_BARRING_DN || + serviceType == SS_INCOMING_BARRING_ANONYMOUS); + } + + public boolean isTypeBarring() { + return (serviceType == SS_BAOC || serviceType == SS_BAOIC || + serviceType == SS_BAOIC_EXC_HOME || serviceType == SS_BAIC || + serviceType == SS_BAIC_ROAMING || serviceType == SS_ALL_BARRING || + serviceType == SS_OUTGOING_BARRING || serviceType == SS_INCOMING_BARRING); + } + + public boolean isTypeInterrogation() { + return (requestType == SS_INTERROGATION); + } + + public String toString() { + return "[ImsSsData] " + "ServiceType: " + serviceType + + " RequestType: " + requestType + + " TeleserviceType: " + teleserviceType + + " ServiceClass: " + serviceClass + + " Result: " + result; + } +} diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.aidl b/telephony/java/android/telephony/ims/ImsSsInfo.aidl new file mode 100644 index 000000000000..66d49507c127 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsSsInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable ImsSsInfo; diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java new file mode 100644 index 000000000000..1d1292fb9f72 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsSsInfo.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provides the result to the update operation for the supplementary service configuration. + * + * @hide + */ +@SystemApi +public final class ImsSsInfo implements Parcelable { + /** + * For the status of service registration or activation/deactivation. + */ + public static final int NOT_REGISTERED = (-1); + public static final int DISABLED = 0; + public static final int ENABLED = 1; + + // 0: disabled, 1: enabled + /** @hide */ + public int mStatus; + /** @hide */ + public String mIcbNum; + + public ImsSsInfo() { + } + + private ImsSsInfo(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mStatus); + out.writeString(mIcbNum); + } + + @Override + public String toString() { + return super.toString() + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled"); + } + + private void readFromParcel(Parcel in) { + mStatus = in.readInt(); + mIcbNum = in.readString(); + } + + public static final Creator<ImsSsInfo> CREATOR = + new Creator<ImsSsInfo>() { + @Override + public ImsSsInfo createFromParcel(Parcel in) { + return new ImsSsInfo(in); + } + + @Override + public ImsSsInfo[] newArray(int size) { + return new ImsSsInfo[size]; + } + }; + + public int getStatus() { + return mStatus; + } + + public String getIcbNum() { + return mIcbNum; + } +} diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.aidl b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.aidl new file mode 100644 index 000000000000..ee321aec29d8 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable ImsStreamMediaProfile; diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java new file mode 100644 index 000000000000..243352bdd180 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Parcelable object to handle IMS stream media profile. + * It provides the media direction, quality of audio and/or video. + * + * @hide + */ +@SystemApi +public final class ImsStreamMediaProfile implements Parcelable { + private static final String TAG = "ImsStreamMediaProfile"; + + /** + * Media directions + */ + public static final int DIRECTION_INVALID = (-1); + public static final int DIRECTION_INACTIVE = 0; + public static final int DIRECTION_RECEIVE = 1; + public static final int DIRECTION_SEND = 2; + public static final int DIRECTION_SEND_RECEIVE = 3; + + /** + * Audio information + */ + public static final int AUDIO_QUALITY_NONE = 0; + public static final int AUDIO_QUALITY_AMR = 1; + public static final int AUDIO_QUALITY_AMR_WB = 2; + public static final int AUDIO_QUALITY_QCELP13K = 3; + public static final int AUDIO_QUALITY_EVRC = 4; + public static final int AUDIO_QUALITY_EVRC_B = 5; + public static final int AUDIO_QUALITY_EVRC_WB = 6; + public static final int AUDIO_QUALITY_EVRC_NW = 7; + public static final int AUDIO_QUALITY_GSM_EFR = 8; + public static final int AUDIO_QUALITY_GSM_FR = 9; + public static final int AUDIO_QUALITY_GSM_HR = 10; + public static final int AUDIO_QUALITY_G711U = 11; + public static final int AUDIO_QUALITY_G723 = 12; + public static final int AUDIO_QUALITY_G711A = 13; + public static final int AUDIO_QUALITY_G722 = 14; + public static final int AUDIO_QUALITY_G711AB = 15; + public static final int AUDIO_QUALITY_G729 = 16; + public static final int AUDIO_QUALITY_EVS_NB = 17; + public static final int AUDIO_QUALITY_EVS_WB = 18; + public static final int AUDIO_QUALITY_EVS_SWB = 19; + public static final int AUDIO_QUALITY_EVS_FB = 20; + + /** + * Video information + */ + public static final int VIDEO_QUALITY_NONE = 0; + public static final int VIDEO_QUALITY_QCIF = (1 << 0); + public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = (1 << 1); + public static final int VIDEO_QUALITY_QVGA_PORTRAIT = (1 << 2); + public static final int VIDEO_QUALITY_VGA_LANDSCAPE = (1 << 3); + public static final int VIDEO_QUALITY_VGA_PORTRAIT = (1 << 4); + + /** + * RTT Modes + */ + public static final int RTT_MODE_DISABLED = 0; + public static final int RTT_MODE_FULL = 1; + + // Audio related information + /** @hide */ + public int mAudioQuality; + /** @hide */ + public int mAudioDirection; + // Video related information + /** @hide */ + public int mVideoQuality; + /** @hide */ + public int mVideoDirection; + // Rtt related information + /** @hide */ + public int mRttMode; + + /** @hide */ + public ImsStreamMediaProfile(Parcel in) { + readFromParcel(in); + } + + /** @hide */ + public ImsStreamMediaProfile() { + mAudioQuality = AUDIO_QUALITY_NONE; + mAudioDirection = DIRECTION_SEND_RECEIVE; + mVideoQuality = VIDEO_QUALITY_NONE; + mVideoDirection = DIRECTION_INVALID; + mRttMode = RTT_MODE_DISABLED; + } + + /** @hide */ + public ImsStreamMediaProfile(int audioQuality, int audioDirection, + int videoQuality, int videoDirection) { + mAudioQuality = audioQuality; + mAudioDirection = audioDirection; + mVideoQuality = videoQuality; + mVideoDirection = videoDirection; + } + + /** @hide */ + public ImsStreamMediaProfile(int rttMode) { + mRttMode = rttMode; + } + + public void copyFrom(ImsStreamMediaProfile profile) { + mAudioQuality = profile.mAudioQuality; + mAudioDirection = profile.mAudioDirection; + mVideoQuality = profile.mVideoQuality; + mVideoDirection = profile.mVideoDirection; + mRttMode = profile.mRttMode; + } + + @Override + public String toString() { + return "{ audioQuality=" + mAudioQuality + + ", audioDirection=" + mAudioDirection + + ", videoQuality=" + mVideoQuality + + ", videoDirection=" + mVideoDirection + + ", rttMode=" + mRttMode + " }"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mAudioQuality); + out.writeInt(mAudioDirection); + out.writeInt(mVideoQuality); + out.writeInt(mVideoDirection); + out.writeInt(mRttMode); + } + + private void readFromParcel(Parcel in) { + mAudioQuality = in.readInt(); + mAudioDirection = in.readInt(); + mVideoQuality = in.readInt(); + mVideoDirection = in.readInt(); + mRttMode = in.readInt(); + } + + public static final Creator<ImsStreamMediaProfile> CREATOR = + new Creator<ImsStreamMediaProfile>() { + @Override + public ImsStreamMediaProfile createFromParcel(Parcel in) { + return new ImsStreamMediaProfile(in); + } + + @Override + public ImsStreamMediaProfile[] newArray(int size) { + return new ImsStreamMediaProfile[size]; + } + }; + + /** + * Determines if it's RTT call + * @return true if RTT call, false otherwise. + */ + public boolean isRttCall() { + return (mRttMode == RTT_MODE_FULL); + } + + /** + * Updates the RttCall attribute + */ + public void setRttMode(int rttMode) { + mRttMode = rttMode; + } + + public int getAudioQuality() { + return mAudioQuality; + } + + public int getAudioDirection() { + return mAudioDirection; + } + + public int getVideoQuality() { + return mVideoQuality; + } + + public int getVideoDirection() { + return mVideoDirection; + } + + public int getRttMode() { + return mRttMode; + } +} diff --git a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.aidl b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.aidl new file mode 100644 index 000000000000..0552780c7dd3 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package android.telephony.ims; + +parcelable ImsSuppServiceNotification; diff --git a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java new file mode 100644 index 000000000000..e6f6f1b021f8 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; + + +/** + * Parcelable object to handle IMS supplementary service notifications. + * + * @hide + */ +@SystemApi +public final class ImsSuppServiceNotification implements Parcelable { + private static final String TAG = "ImsSuppServiceNotification"; + + /** Type of notification: 0 = MO; 1 = MT */ + public final int notificationType; + /** TS 27.007 7.17 "code1" or "code2" */ + public final int code; + /** TS 27.007 7.17 "index" - Not used currently*/ + public final int index; + /** TS 27.007 7.17 "type" (MT only) - Not used currently */ + public final int type; + /** TS 27.007 7.17 "number" (MT only) */ + public final String number; + /** List of forwarded numbers, if any */ + public final String[] history; + + /** @hide */ + public ImsSuppServiceNotification(Parcel in) { + notificationType = in.readInt(); + code = in.readInt(); + index = in.readInt(); + type = in.readInt(); + number = in.readString(); + history = in.createStringArray(); + } + + @Override + public String toString() { + return "{ notificationType=" + notificationType + + ", code=" + code + + ", index=" + index + + ", type=" + type + + ", number=" + number + + ", history=" + Arrays.toString(history) + + " }"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(notificationType); + out.writeInt(code); + out.writeInt(index); + out.writeInt(type); + out.writeString(number); + out.writeStringArray(history); + } + + public static final Creator<ImsSuppServiceNotification> CREATOR = + new Creator<ImsSuppServiceNotification>() { + @Override + public ImsSuppServiceNotification createFromParcel(Parcel in) { + return new ImsSuppServiceNotification(in); + } + + @Override + public ImsSuppServiceNotification[] newArray(int size) { + return new ImsSuppServiceNotification[size]; + } + }; +} diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java new file mode 100644 index 000000000000..d50a0f738b25 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsUtListener.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.os.Bundle; +import android.os.RemoteException; +import android.util.Log; + +import com.android.ims.internal.IImsUtListener; + +/** + * Base implementation of the IMS UT listener interface, which implements stubs. + * Override these methods to implement functionality. + * @hide + */ +// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you +// will break other implementations of ImsUt maintained by other ImsServices. +@SystemApi +public class ImsUtListener { + private IImsUtListener mServiceInterface; + private static final String LOG_TAG = "ImsUtListener"; + + public void onUtConfigurationUpdated(int id) { + try { + mServiceInterface.utConfigurationUpdated(null, id); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationUpdated: remote exception"); + } + } + + public void onUtConfigurationUpdateFailed(int id, ImsReasonInfo error) { + try { + mServiceInterface.utConfigurationUpdateFailed(null, id, error); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationUpdateFailed: remote exception"); + } + } + + public void onUtConfigurationQueried(int id, Bundle ssInfo) { + try { + mServiceInterface.utConfigurationQueried(null, id, ssInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationQueried: remote exception"); + } + } + + public void onUtConfigurationQueryFailed(int id, ImsReasonInfo error) { + try { + mServiceInterface.utConfigurationQueryFailed(null, id, error); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationQueryFailed: remote exception"); + } + } + + public void onUtConfigurationCallBarringQueried(int id, ImsSsInfo[] cbInfo) { + try { + mServiceInterface.utConfigurationCallBarringQueried(null, id, cbInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationCallBarringQueried: remote exception"); + } + } + + public void onUtConfigurationCallForwardQueried(int id, ImsCallForwardInfo[] cfInfo) { + try { + mServiceInterface.utConfigurationCallForwardQueried(null, id, cfInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationCallForwardQueried: remote exception"); + } + } + + public void onUtConfigurationCallWaitingQueried(int id, ImsSsInfo[] cwInfo) { + try { + mServiceInterface.utConfigurationCallWaitingQueried(null, id, cwInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationCallWaitingQueried: remote exception"); + } + } + + public void onSupplementaryServiceIndication(ImsSsData ssData) { + try { + mServiceInterface.onSupplementaryServiceIndication(ssData); + } catch (RemoteException e) { + Log.w(LOG_TAG, "onSupplementaryServiceIndication: remote exception"); + } + } + + /** + * @hide + */ + public ImsUtListener(IImsUtListener serviceInterface) { + mServiceInterface = serviceInterface; + } +} diff --git a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java new file mode 100644 index 000000000000..b4f60b952a00 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2018 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.telephony.ims; + +import android.annotation.SystemApi; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.RemoteException; +import android.telecom.Connection; +import android.telecom.VideoProfile; +import android.telecom.VideoProfile.CameraCapabilities; +import android.view.Surface; + +import com.android.ims.internal.IImsVideoCallCallback; +import com.android.ims.internal.IImsVideoCallProvider; +import com.android.internal.os.SomeArgs; + +/** + * @hide + */ +@SystemApi +public abstract class ImsVideoCallProvider { + private static final int MSG_SET_CALLBACK = 1; + private static final int MSG_SET_CAMERA = 2; + private static final int MSG_SET_PREVIEW_SURFACE = 3; + private static final int MSG_SET_DISPLAY_SURFACE = 4; + private static final int MSG_SET_DEVICE_ORIENTATION = 5; + private static final int MSG_SET_ZOOM = 6; + private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7; + private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8; + private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9; + private static final int MSG_REQUEST_CALL_DATA_USAGE = 10; + private static final int MSG_SET_PAUSE_IMAGE = 11; + + private final ImsVideoCallProviderBinder mBinder; + + private IImsVideoCallCallback mCallback; + + /** + * Default handler used to consolidate binder method calls onto a single thread. + */ + private final Handler mProviderHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_SET_CALLBACK: + mCallback = (IImsVideoCallCallback) msg.obj; + break; + case MSG_SET_CAMERA: + { + SomeArgs args = (SomeArgs) msg.obj; + try { + onSetCamera((String) args.arg1); + onSetCamera((String) args.arg1, args.argi1); + } finally { + args.recycle(); + } + break; + } + case MSG_SET_PREVIEW_SURFACE: + onSetPreviewSurface((Surface) msg.obj); + break; + case MSG_SET_DISPLAY_SURFACE: + onSetDisplaySurface((Surface) msg.obj); + break; + case MSG_SET_DEVICE_ORIENTATION: + onSetDeviceOrientation(msg.arg1); + break; + case MSG_SET_ZOOM: + onSetZoom((Float) msg.obj); + break; + case MSG_SEND_SESSION_MODIFY_REQUEST: { + SomeArgs args = (SomeArgs) msg.obj; + try { + VideoProfile fromProfile = (VideoProfile) args.arg1; + VideoProfile toProfile = (VideoProfile) args.arg2; + + onSendSessionModifyRequest(fromProfile, toProfile); + } finally { + args.recycle(); + } + break; + } + case MSG_SEND_SESSION_MODIFY_RESPONSE: + onSendSessionModifyResponse((VideoProfile) msg.obj); + break; + case MSG_REQUEST_CAMERA_CAPABILITIES: + onRequestCameraCapabilities(); + break; + case MSG_REQUEST_CALL_DATA_USAGE: + onRequestCallDataUsage(); + break; + case MSG_SET_PAUSE_IMAGE: + onSetPauseImage((Uri) msg.obj); + break; + default: + break; + } + } + }; + + /** + * IImsVideoCallProvider stub implementation. + */ + private final class ImsVideoCallProviderBinder extends IImsVideoCallProvider.Stub { + public void setCallback(IImsVideoCallCallback callback) { + mProviderHandler.obtainMessage(MSG_SET_CALLBACK, callback).sendToTarget(); + } + + public void setCamera(String cameraId, int uid) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = cameraId; + args.argi1 = uid; + mProviderHandler.obtainMessage(MSG_SET_CAMERA, args).sendToTarget(); + } + + public void setPreviewSurface(Surface surface) { + mProviderHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget(); + } + + public void setDisplaySurface(Surface surface) { + mProviderHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget(); + } + + public void setDeviceOrientation(int rotation) { + mProviderHandler.obtainMessage(MSG_SET_DEVICE_ORIENTATION, rotation, 0).sendToTarget(); + } + + public void setZoom(float value) { + mProviderHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget(); + } + + public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = fromProfile; + args.arg2 = toProfile; + mProviderHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget(); + } + + public void sendSessionModifyResponse(VideoProfile responseProfile) { + mProviderHandler.obtainMessage( + MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget(); + } + + public void requestCameraCapabilities() { + mProviderHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget(); + } + + public void requestCallDataUsage() { + mProviderHandler.obtainMessage(MSG_REQUEST_CALL_DATA_USAGE).sendToTarget(); + } + + public void setPauseImage(Uri uri) { + mProviderHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget(); + } + } + + public ImsVideoCallProvider() { + mBinder = new ImsVideoCallProviderBinder(); + } + + /** + * Returns binder object which can be used across IPC methods. + * @hide + */ + public final IImsVideoCallProvider getInterface() { + return mBinder; + } + + /** @see Connection.VideoProvider#onSetCamera */ + public abstract void onSetCamera(String cameraId); + + /** + * Similar to {@link #onSetCamera(String)}, except includes the UID of the calling process which + * the IMS service uses when opening the camera. This ensures camera permissions are verified + * by the camera service. + * + * @param cameraId The id of the camera to be opened. + * @param uid The uid of the caller, used when opening the camera for permission verification. + * @see Connection.VideoProvider#onSetCamera + */ + public void onSetCamera(String cameraId, int uid) { + } + + /** @see Connection.VideoProvider#onSetPreviewSurface */ + public abstract void onSetPreviewSurface(Surface surface); + + /** @see Connection.VideoProvider#onSetDisplaySurface */ + public abstract void onSetDisplaySurface(Surface surface); + + /** @see Connection.VideoProvider#onSetDeviceOrientation */ + public abstract void onSetDeviceOrientation(int rotation); + + /** @see Connection.VideoProvider#onSetZoom */ + public abstract void onSetZoom(float value); + + /** @see Connection.VideoProvider#onSendSessionModifyRequest */ + public abstract void onSendSessionModifyRequest(VideoProfile fromProfile, + VideoProfile toProfile); + + /** @see Connection.VideoProvider#onSendSessionModifyResponse */ + public abstract void onSendSessionModifyResponse(VideoProfile responseProfile); + + /** @see Connection.VideoProvider#onRequestCameraCapabilities */ + public abstract void onRequestCameraCapabilities(); + + /** @see Connection.VideoProvider#onRequestCallDataUsage */ + public abstract void onRequestCallDataUsage(); + + /** @see Connection.VideoProvider#onSetPauseImage */ + public abstract void onSetPauseImage(Uri uri); + + /** @see Connection.VideoProvider#receiveSessionModifyRequest */ + public void receiveSessionModifyRequest(VideoProfile VideoProfile) { + if (mCallback != null) { + try { + mCallback.receiveSessionModifyRequest(VideoProfile); + } catch (RemoteException ignored) { + } + } + } + + /** @see Connection.VideoProvider#receiveSessionModifyResponse */ + public void receiveSessionModifyResponse( + int status, VideoProfile requestedProfile, VideoProfile responseProfile) { + if (mCallback != null) { + try { + mCallback.receiveSessionModifyResponse(status, requestedProfile, responseProfile); + } catch (RemoteException ignored) { + } + } + } + + /** @see Connection.VideoProvider#handleCallSessionEvent */ + public void handleCallSessionEvent(int event) { + if (mCallback != null) { + try { + mCallback.handleCallSessionEvent(event); + } catch (RemoteException ignored) { + } + } + } + + /** @see Connection.VideoProvider#changePeerDimensions */ + public void changePeerDimensions(int width, int height) { + if (mCallback != null) { + try { + mCallback.changePeerDimensions(width, height); + } catch (RemoteException ignored) { + } + } + } + + /** @see Connection.VideoProvider#changeCallDataUsage */ + public void changeCallDataUsage(long dataUsage) { + if (mCallback != null) { + try { + mCallback.changeCallDataUsage(dataUsage); + } catch (RemoteException ignored) { + } + } + } + + /** @see Connection.VideoProvider#changeCameraCapabilities */ + public void changeCameraCapabilities(CameraCapabilities CameraCapabilities) { + if (mCallback != null) { + try { + mCallback.changeCameraCapabilities(CameraCapabilities); + } catch (RemoteException ignored) { + } + } + } + + /** @see Connection.VideoProvider#changeVideoQuality */ + public void changeVideoQuality(int videoQuality) { + if (mCallback != null) { + try { + mCallback.changeVideoQuality(videoQuality); + } catch (RemoteException ignored) { + } + } + } +} diff --git a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl index e6a18d027d62..f25b4b148605 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl @@ -16,12 +16,12 @@ package android.telephony.ims.aidl; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsConferenceState; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsConferenceState; import com.android.ims.internal.IImsCallSession; -import com.android.ims.ImsSuppServiceNotification; +import android.telephony.ims.ImsSuppServiceNotification; /** * A listener type for receiving notification on IMS call session events. diff --git a/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl index f9b15c0b1610..b9a6b3c38a92 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl @@ -22,7 +22,7 @@ import android.telephony.ims.aidl.IImsSmsListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.feature.CapabilityChangeRequest; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsMultiEndpoint; @@ -57,4 +57,5 @@ interface IImsMmTelFeature { oneway void acknowledgeSms(int token, int messageRef, int result); oneway void acknowledgeSmsReport(int token, int messageRef, int result); String getSmsFormat(); + oneway void onSmsReady(); } diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl index a745a3819f40..4f37caa33680 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl @@ -20,7 +20,7 @@ package android.telephony.ims.aidl; import android.net.Uri; import android.telephony.ims.stub.ImsFeatureConfiguration; -import com.android.ims.ImsReasonInfo; +import android.telephony.ims.ImsReasonInfo; /** * See ImsRegistrationImplBase.Callback for more information. diff --git a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java index f5c5857b7ab3..7a1b1b218fab 100644 --- a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java @@ -20,7 +20,7 @@ import android.app.PendingIntent; import android.os.Message; import android.os.RemoteException; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsConfig; import com.android.ims.internal.IImsEcbm; @@ -28,7 +28,7 @@ import com.android.ims.internal.IImsMMTelFeature; import com.android.ims.internal.IImsMultiEndpoint; import com.android.ims.internal.IImsRegistrationListener; import com.android.ims.internal.IImsUt; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallSession; /** * Base implementation for MMTel. diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java index 6725d2937a31..48a5a75ad035 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java @@ -19,14 +19,14 @@ package android.telephony.ims.compat.stub; import android.os.RemoteException; import android.telephony.ims.ImsCallSessionListener; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsConferenceState; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsSuppServiceNotification; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsConferenceState; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsSuppServiceNotification; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsCallSessionListener; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallSession; /** * Compat implementation of ImsCallSessionImplBase for older implementations. diff --git a/telephony/java/android/telephony/ims/stub/ImsUtListenerImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java index daa74c8f6f88..b2aa08015d10 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtListenerImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2018 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. @@ -14,15 +14,15 @@ * limitations under the License */ -package android.telephony.ims.stub; +package android.telephony.ims.compat.stub; import android.os.Bundle; import android.os.RemoteException; -import com.android.ims.ImsCallForwardInfo; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsSsData; -import com.android.ims.ImsSsInfo; +import android.telephony.ims.ImsCallForwardInfo; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsSsData; +import android.telephony.ims.ImsSsInfo; import com.android.ims.internal.IImsUt; import com.android.ims.internal.IImsUtListener; diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java index efb6ffe99049..7c793a5c18ac 100644 --- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java +++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java @@ -16,6 +16,7 @@ package android.telephony.ims.feature; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -30,17 +31,32 @@ import java.util.Set; * the request. * {@hide} */ -public class CapabilityChangeRequest implements Parcelable { +@SystemApi +public final class CapabilityChangeRequest implements Parcelable { + /** + * Contains a feature capability, defined as + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}, + * along with an associated technology, defined as + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN} + */ public static class CapabilityPair { private final int mCapability; private final int radioTech; - public CapabilityPair(int capability, int radioTech) { + public CapabilityPair(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability, + @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) { this.mCapability = capability; this.radioTech = radioTech; } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -52,6 +68,9 @@ public class CapabilityChangeRequest implements Parcelable { return getRadioTech() == that.getRadioTech(); } + /** + * @hide + */ @Override public int hashCode() { int result = getCapability(); @@ -59,10 +78,22 @@ public class CapabilityChangeRequest implements Parcelable { return result; } + /** + * @return The stored capability, defined as + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS} + */ public @MmTelFeature.MmTelCapabilities.MmTelCapability int getCapability() { return mCapability; } + /** + * @return the stored radio technology, defined as + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN} + */ public @ImsRegistrationImplBase.ImsRegistrationTech int getRadioTech() { return radioTech; } @@ -73,6 +104,7 @@ public class CapabilityChangeRequest implements Parcelable { // Pair contains <radio tech, mCapability> private final Set<CapabilityPair> mCapabilitiesToDisable; + /** @hide */ public CapabilityChangeRequest() { mCapabilitiesToEnable = new ArraySet<>(); mCapabilitiesToDisable = new ArraySet<>(); @@ -130,6 +162,9 @@ public class CapabilityChangeRequest implements Parcelable { } } + /** + * @hide + */ protected CapabilityChangeRequest(Parcel in) { int enableSize = in.readInt(); mCapabilitiesToEnable = new ArraySet<>(enableSize); @@ -177,6 +212,9 @@ public class CapabilityChangeRequest implements Parcelable { } } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -189,6 +227,9 @@ public class CapabilityChangeRequest implements Parcelable { return mCapabilitiesToDisable.equals(that.mCapabilitiesToDisable); } + /** + * @hide + */ @Override public int hashCode() { int result = mCapabilitiesToEnable.hashCode(); diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index 2cc0a8a22759..a23ce6316a94 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -18,6 +18,7 @@ package android.telephony.ims.feature; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.content.Context; import android.content.Intent; import android.os.IInterface; @@ -25,6 +26,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.telephony.SubscriptionManager; import android.telephony.ims.aidl.IImsCapabilityCallback; +import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; import com.android.ims.internal.IImsFeatureStatusCallback; @@ -38,10 +40,12 @@ import java.util.Set; import java.util.WeakHashMap; /** - * Base class for all IMS features that are supported by the framework. + * Base class for all IMS features that are supported by the framework. Use a concrete subclass + * of {@link ImsFeature}, such as {@link MmTelFeature} or {@link RcsFeature}. * * @hide */ +@SystemApi public abstract class ImsFeature { private static final String LOG_TAG = "ImsFeature"; @@ -75,17 +79,35 @@ public abstract class ImsFeature { */ public static final String EXTRA_PHONE_ID = "android:phone_id"; - // Invalid feature value + /** + * Invalid feature value\ + * @hide + */ public static final int FEATURE_INVALID = -1; // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously // defined values in ImsServiceClass for compatibility purposes. + /** + * This feature supports emergency calling over MMTEL. + */ public static final int FEATURE_EMERGENCY_MMTEL = 0; + /** + * This feature supports the MMTEL feature. + */ public static final int FEATURE_MMTEL = 1; + /** + * This feature supports the RCS feature. + */ public static final int FEATURE_RCS = 2; - // Total number of features defined + /** + * Total number of features defined + * @hide + */ public static final int FEATURE_MAX = 3; - // Integer values defining IMS features that are supported in ImsFeature. + /** + * Integer values defining IMS features that are supported in ImsFeature. + * @hide + */ @IntDef(flag = true, value = { FEATURE_EMERGENCY_MMTEL, @@ -95,7 +117,10 @@ public abstract class ImsFeature { @Retention(RetentionPolicy.SOURCE) public @interface FeatureType {} - // Integer values defining the state of the ImsFeature at any time. + /** + * Integer values defining the state of the ImsFeature at any time. + * @hide + */ @IntDef(flag = true, value = { STATE_UNAVAILABLE, @@ -105,12 +130,24 @@ public abstract class ImsFeature { @Retention(RetentionPolicy.SOURCE) public @interface ImsState {} + /** + * This {@link ImsFeature}'s state is unavailable and should not be communicated with. + */ public static final int STATE_UNAVAILABLE = 0; + /** + * This {@link ImsFeature} state is initializing and should not be communicated with. + */ public static final int STATE_INITIALIZING = 1; + /** + * This {@link ImsFeature} is ready for communication. + */ public static final int STATE_READY = 2; - // Integer values defining the result codes that should be returned from - // {@link changeEnabledCapabilities} when the framework tries to set a feature's capability. + /** + * Integer values defining the result codes that should be returned from + * {@link #changeEnabledCapabilities} when the framework tries to set a feature's capability. + * @hide + */ @IntDef(flag = true, value = { CAPABILITY_ERROR_GENERIC, @@ -119,7 +156,13 @@ public abstract class ImsFeature { @Retention(RetentionPolicy.SOURCE) public @interface ImsCapabilityError {} + /** + * The capability was unable to be changed. + */ public static final int CAPABILITY_ERROR_GENERIC = -1; + /** + * The capability was able to be changed. + */ public static final int CAPABILITY_SUCCESS = 0; @@ -129,6 +172,8 @@ public abstract class ImsFeature { * configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error * callbacks when the ImsService can not change the capability as requested, via * {@link #onChangeCapabilityConfigurationError}. + * + * @hide */ public static class CapabilityCallback extends IImsCapabilityCallback.Stub { @@ -159,7 +204,7 @@ public abstract class ImsFeature { */ @Override public void onChangeCapabilityConfigurationError(int capability, int radioTech, - int reason) { + @ImsCapabilityError int reason) { } /** @@ -180,6 +225,7 @@ public abstract class ImsFeature { protected static class CapabilityCallbackProxy { private final IImsCapabilityCallback mCallback; + /** @hide */ public CapabilityCallbackProxy(IImsCapabilityCallback c) { mCallback = c; } @@ -188,9 +234,16 @@ public abstract class ImsFeature { * This method notifies the provided framework callback that the request to change the * indicated capability has failed and has not changed. * - * @param capability The Capability that will be notified to the framework. - * @param radioTech The radio tech that this capability failed for. - * @param reason The reason this capability was unable to be changed. + * @param capability The Capability that will be notified to the framework, defined as + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}. + * @param radioTech The radio tech that this capability failed for, defined as + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}. + * @param reason The reason this capability was unable to be changed, defined as + * {@link #CAPABILITY_ERROR_GENERIC} or {@link #CAPABILITY_SUCCESS}. */ public void onChangeCapabilityConfigurationError(int capability, int radioTech, @ImsCapabilityError int reason) { @@ -203,22 +256,11 @@ public abstract class ImsFeature { Log.e(LOG_TAG, "onChangeCapabilityConfigurationError called on dead binder."); } } - - public void onQueryCapabilityConfiguration(int capability, int radioTech, - boolean isEnabled) { - if (mCallback == null) { - return; - } - try { - mCallback.onQueryCapabilityConfiguration(capability, radioTech, isEnabled); - } catch (RemoteException e) { - Log.e(LOG_TAG, "onQueryCapabilityConfiguration called on dead binder."); - } - } } /** * Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask. + * @hide */ public static class Capabilities { protected int mCapabilities = 0; @@ -253,6 +295,9 @@ public abstract class ImsFeature { return (mCapabilities & capabilities) == capabilities; } + /** + * @return a deep copy of the Capabilites. + */ public Capabilities copy() { return new Capabilities(mCapabilities); } @@ -264,6 +309,9 @@ public abstract class ImsFeature { return mCapabilities; } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -274,11 +322,17 @@ public abstract class ImsFeature { return mCapabilities == that.mCapabilities; } + /** + * @hide + */ @Override public int hashCode() { return mCapabilities; } + /** + * @hide + */ @Override public String toString() { return "Capabilities: " + Integer.toBinaryString(mCapabilities); @@ -289,24 +343,40 @@ public abstract class ImsFeature { new WeakHashMap<IImsFeatureStatusCallback, Boolean>()); private @ImsState int mState = STATE_UNAVAILABLE; private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; + /** + * @hide + */ protected Context mContext; private final Object mLock = new Object(); private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks = new RemoteCallbackList<>(); private Capabilities mCapabilityStatus = new Capabilities(); + /** + * @hide + */ public final void initialize(Context context, int slotId) { mContext = context; mSlotId = slotId; } + /** + * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE}, + * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}. + */ public final int getFeatureState() { synchronized (mLock) { return mState; } } - protected final void setFeatureState(@ImsState int state) { + /** + * Set the state of the ImsFeature. The state is used as a signal to the framework to start or + * stop communication, depending on the state sent. + * @param state The ImsFeature's state, defined as {@link #STATE_UNAVAILABLE}, + * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}. + */ + public final void setFeatureState(@ImsState int state) { synchronized (mLock) { if (mState != state) { mState = state; @@ -315,7 +385,10 @@ public abstract class ImsFeature { } } - // Not final for testing, but shouldn't be extended! + /** + * Not final for testing, but shouldn't be extended! + * @hide + */ @VisibleForTesting public void addImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) { try { @@ -330,8 +403,11 @@ public abstract class ImsFeature { } } + /** + * Not final for testing, but shouldn't be extended! + * @hide + */ @VisibleForTesting - // Not final for testing, but should not be extended! public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) { synchronized (mLock) { mStatusCallbacks.remove(c); @@ -382,16 +458,23 @@ public abstract class ImsFeature { mContext.sendBroadcast(intent); } + /** + * @hide + */ public final void addCapabilityCallback(IImsCapabilityCallback c) { mCapabilityCallbacks.register(c); } + /** + * @hide + */ public final void removeCapabilityCallback(IImsCapabilityCallback c) { mCapabilityCallbacks.unregister(c); } /** * @return the cached capabilities status for this feature. + * @hide */ @VisibleForTesting public Capabilities queryCapabilityStatus() { @@ -400,7 +483,10 @@ public abstract class ImsFeature { } } - // Called internally to request the change of enabled capabilities. + /** + * Called internally to request the change of enabled capabilities. + * @hide + */ @VisibleForTesting public final void requestChangeEnabledCapabilities(CapabilityChangeRequest request, IImsCapabilityCallback c) throws RemoteException { @@ -415,6 +501,8 @@ public abstract class ImsFeature { * Called by the ImsFeature when the capabilities status has changed. * * @param c A {@link Capabilities} containing the new Capabilities status. + * + * @hide */ protected final void notifyCapabilitiesStatusChanged(Capabilities c) { synchronized (mLock) { @@ -468,6 +556,7 @@ public abstract class ImsFeature { /** * @return Binder instance that the framework will use to communicate with this feature. + * @hide */ protected abstract IInterface getBinder(); } diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index 83214b32fc38..2baf076d391f 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -17,28 +17,30 @@ package android.telephony.ims.feature; import android.annotation.IntDef; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Bundle; import android.os.Message; import android.os.RemoteException; import android.telecom.TelecomManager; +import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.telephony.ims.stub.ImsCallSessionImplBase; +import android.telephony.ims.stub.ImsSmsImplBase; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsMmTelFeature; import android.telephony.ims.aidl.IImsMmTelListener; import android.telephony.ims.aidl.IImsSmsListener; -import android.telephony.ims.stub.ImsRegistrationImplBase; -import android.telephony.ims.stub.ImsSmsImplBase; import android.telephony.ims.stub.ImsEcbmImplBase; import android.telephony.ims.stub.ImsMultiEndpointImplBase; import android.telephony.ims.stub.ImsUtImplBase; import android.util.Log; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsMultiEndpoint; import com.android.ims.internal.IImsUt; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallSession; import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; @@ -51,7 +53,7 @@ import java.lang.annotation.RetentionPolicy; * service supports. * @hide */ - +@SystemApi public class MmTelFeature extends ImsFeature { private static final String LOG_TAG = "MmTelFeature"; @@ -84,8 +86,8 @@ public class MmTelFeature extends ImsFeature { @Override public IImsCallSession createCallSession(ImsCallProfile profile) throws RemoteException { synchronized (mLock) { - ImsCallSession s = MmTelFeature.this.createCallSession(profile); - return s != null ? s.getSession() : null; + ImsCallSessionImplBase s = MmTelFeature.this.createCallSession(profile); + return s != null ? s.getServiceImpl() : null; } } @@ -99,14 +101,15 @@ public class MmTelFeature extends ImsFeature { @Override public IImsUt getUtInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getUt(); + return MmTelFeature.this.getUt().getInterface(); } } @Override public IImsEcbm getEcbmInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getEcbm(); + ImsEcbmImplBase ecbm = MmTelFeature.this.getEcbm(); + return ecbm != null ? ecbm.getImsEcbm() : null; } } @@ -120,7 +123,8 @@ public class MmTelFeature extends ImsFeature { @Override public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getMultiEndpoint(); + ImsMultiEndpointImplBase multiEndPoint = MmTelFeature.this.getMultiEndpoint(); + return multiEndPoint != null ? multiEndPoint.getIImsMultiEndpoint() : null; } } @@ -184,11 +188,22 @@ public class MmTelFeature extends ImsFeature { return MmTelFeature.this.getSmsFormat(); } } + + @Override + public void onSmsReady() { + synchronized (mLock) { + MmTelFeature.this.onSmsReady(); + } + } }; /** * Contains the capabilities defined and supported by a MmTelFeature in the form of a Bitmask. - * The capabilities that are used in MmTelFeature are defined by {@link MmTelCapability}. + * The capabilities that are used in MmTelFeature are defined as + * {@link MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelCapabilities#CAPABILITY_TYPE_UT}, and + * {@link MmTelCapabilities#CAPABILITY_TYPE_SMS}. * * The capabilities of this MmTelFeature will be set by the framework and can be queried with * {@link #queryCapabilityStatus()}. @@ -199,6 +214,9 @@ public class MmTelFeature extends ImsFeature { */ public static class MmTelCapabilities extends Capabilities { + /** + * @hide + */ @VisibleForTesting public MmTelCapabilities() { super(); @@ -275,6 +293,7 @@ public class MmTelFeature extends ImsFeature { /** * Listener that the framework implements for communication from the MmTelFeature. + * @hide */ public static class Listener extends IImsMmTelListener.Stub { @@ -375,24 +394,27 @@ public class MmTelFeature extends ImsFeature { * support the capability that is enabled. A capability that is disabled by the framework (via * {@link #changeEnabledCapabilities}) should also show the status as disabled. */ - protected final void notifyCapabilitiesStatusChanged(MmTelCapabilities c) { + public final void notifyCapabilitiesStatusChanged(MmTelCapabilities c) { super.notifyCapabilitiesStatusChanged(c); } /** * Notify the framework of an incoming call. - * @param c The {@link ImsCallSession} of the new incoming call. + * @param c The {@link ImsCallSessionImplBase} of the new incoming call. * - * @throws RemoteException if the connection to the framework is not available. If this happens, - * the call should be no longer considered active and should be cleaned up. + * @throws RuntimeException if the connection to the framework is not available. If this + * happens, the call should be no longer considered active and should be cleaned up. * */ - protected final void notifyIncomingCall(ImsCallSession c, Bundle extras) - throws RemoteException { + public final void notifyIncomingCall(ImsCallSessionImplBase c, Bundle extras) { synchronized (mLock) { if (mListener == null) { throw new IllegalStateException("Session is not available."); } - mListener.onIncomingCall(c.getSession(), extras); + try { + mListener.onIncomingCall(c.getServiceImpl(), extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } } @@ -458,7 +480,7 @@ public class MmTelFeature extends ImsFeature { * * @param profile a call profile to make the call */ - public ImsCallSession createCallSession(ImsCallProfile profile) { + public ImsCallSessionImplBase createCallSession(ImsCallProfile profile) { // Base Implementation - Should be overridden return null; } @@ -477,7 +499,8 @@ public class MmTelFeature extends ImsFeature { } /** - * @return The Ut interface for the supplementary service configuration. + * @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service + * configuration. */ public ImsUtImplBase getUt() { // Base Implementation - Should be overridden @@ -485,7 +508,8 @@ public class MmTelFeature extends ImsFeature { } /** - * @return The Emergency call-back mode interface for emergency VoLTE calls that support it. + * @return The {@link ImsEcbmImplBase} Emergency call-back mode interface for emergency VoLTE + * calls that support it. */ public ImsEcbmImplBase getEcbm() { // Base Implementation - Should be overridden @@ -493,7 +517,8 @@ public class MmTelFeature extends ImsFeature { } /** - * @return The Emergency call-back mode interface for emergency VoLTE calls that support it. + * @return The {@link ImsMultiEndpointImplBase} implementation for implementing Dialog event + * package processing for multi-endpoint. */ public ImsMultiEndpointImplBase getMultiEndpoint() { // Base Implementation - Should be overridden @@ -532,6 +557,10 @@ public class MmTelFeature extends ImsFeature { getSmsImplementation().acknowledgeSmsReport(token, messageRef, result); } + private void onSmsReady() { + getSmsImplementation().onReady(); + } + /** * Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default * non-functional implementation is returned. @@ -539,7 +568,7 @@ public class MmTelFeature extends ImsFeature { * @return an instance of {@link ImsSmsImplBase} which should be implemented by the IMS * Provider. */ - protected ImsSmsImplBase getSmsImplementation() { + public ImsSmsImplBase getSmsImplementation() { return new ImsSmsImplBase(); } diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java index 3b6f7e0f1a89..a637e16d0a48 100644 --- a/telephony/java/android/telephony/ims/feature/RcsFeature.java +++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java @@ -16,6 +16,7 @@ package android.telephony.ims.feature; +import android.annotation.SystemApi; import android.telephony.ims.aidl.IImsRcsFeature; /** @@ -23,9 +24,10 @@ import android.telephony.ims.aidl.IImsRcsFeature; * this class and provide implementations of the RcsFeature methods that they support. * @hide */ - +@SystemApi public class RcsFeature extends ImsFeature { + /**{@inheritDoc}*/ private final IImsRcsFeature mImsRcsBinder = new IImsRcsFeature.Stub() { // Empty Default Implementation. }; @@ -35,12 +37,16 @@ public class RcsFeature extends ImsFeature { super(); } + /** + * {@inheritDoc} + */ @Override public void changeEnabledCapabilities(CapabilityChangeRequest request, CapabilityCallbackProxy c) { // Do nothing for base implementation. } + /**{@inheritDoc}*/ @Override public void onFeatureRemoved() { @@ -52,6 +58,9 @@ public class RcsFeature extends ImsFeature { } + /** + * @hide + */ @Override public final IImsRcsFeature getBinder() { return mImsRcsBinder; diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java index 95243fdc5f1b..c6ca6fdb0fd8 100644 --- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java @@ -16,30 +16,257 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.Message; import android.os.RemoteException; import android.telephony.ims.ImsCallSessionListener; import android.telephony.ims.aidl.IImsCallSessionListener; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsCallSession; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsVideoCallProvider; +import android.telephony.ims.ImsVideoCallProvider; + +import dalvik.system.CloseGuard; /** - * Base implementation of IImsCallSession, which implements stub versions of the methods in the - * IImsCallSession AIDL. Override the methods that your implementation of ImsCallSession supports. + * Base implementation of IImsCallSession, which implements stub versions of the methods available. * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsCallSession maintained by other ImsServices. + * Override the methods that your implementation of ImsCallSession supports. * * @hide */ +@SystemApi +// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you +// will break other implementations of ImsCallSession maintained by other ImsServices. +public class ImsCallSessionImplBase implements AutoCloseable { + /** + * Notify USSD Mode. + */ + public static final int USSD_MODE_NOTIFY = 0; + /** + * Request USSD Mode + */ + public static final int USSD_MODE_REQUEST = 1; -public class ImsCallSessionImplBase extends IImsCallSession.Stub { + /** + * Defines IMS call session state. + */ + public static class State { + public static final int IDLE = 0; + public static final int INITIATED = 1; + public static final int NEGOTIATING = 2; + public static final int ESTABLISHING = 3; + public static final int ESTABLISHED = 4; + + public static final int RENEGOTIATING = 5; + public static final int REESTABLISHING = 6; + + public static final int TERMINATING = 7; + public static final int TERMINATED = 8; + + public static final int INVALID = (-1); + + /** + * Converts the state to string. + */ + public static String toString(int state) { + switch (state) { + case IDLE: + return "IDLE"; + case INITIATED: + return "INITIATED"; + case NEGOTIATING: + return "NEGOTIATING"; + case ESTABLISHING: + return "ESTABLISHING"; + case ESTABLISHED: + return "ESTABLISHED"; + case RENEGOTIATING: + return "RENEGOTIATING"; + case REESTABLISHING: + return "REESTABLISHING"; + case TERMINATING: + return "TERMINATING"; + case TERMINATED: + return "TERMINATED"; + default: + return "UNKNOWN"; + } + } + + /** + * @hide + */ + private State() { + } + } + + // Non-final for injection by tests + private IImsCallSession mServiceImpl = new IImsCallSession.Stub() { + @Override + public void close() { + ImsCallSessionImplBase.this.close(); + } + + @Override + public String getCallId() { + return ImsCallSessionImplBase.this.getCallId(); + } + + @Override + public ImsCallProfile getCallProfile() { + return ImsCallSessionImplBase.this.getCallProfile(); + } + + @Override + public ImsCallProfile getLocalCallProfile() { + return ImsCallSessionImplBase.this.getLocalCallProfile(); + } + + @Override + public ImsCallProfile getRemoteCallProfile() { + return ImsCallSessionImplBase.this.getRemoteCallProfile(); + } + + @Override + public String getProperty(String name) { + return ImsCallSessionImplBase.this.getProperty(name); + } + + @Override + public int getState() { + return ImsCallSessionImplBase.this.getState(); + } + + @Override + public boolean isInCall() { + return ImsCallSessionImplBase.this.isInCall(); + } + + @Override + public void setListener(IImsCallSessionListener listener) { + ImsCallSessionImplBase.this.setListener(new ImsCallSessionListener(listener)); + } + + @Override + public void setMute(boolean muted) { + ImsCallSessionImplBase.this.setMute(muted); + } + + @Override + public void start(String callee, ImsCallProfile profile) { + ImsCallSessionImplBase.this.start(callee, profile); + } + + @Override + public void startConference(String[] participants, ImsCallProfile profile) throws + RemoteException { + ImsCallSessionImplBase.this.startConference(participants, profile); + } + + @Override + public void accept(int callType, ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.accept(callType, profile); + } + + @Override + public void reject(int reason) { + ImsCallSessionImplBase.this.reject(reason); + } + + @Override + public void terminate(int reason) { + ImsCallSessionImplBase.this.terminate(reason); + } + + @Override + public void hold(ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.hold(profile); + } + + @Override + public void resume(ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.resume(profile); + } + + @Override + public void merge() { + ImsCallSessionImplBase.this.merge(); + } + + @Override + public void update(int callType, ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.update(callType, profile); + } + + @Override + public void extendToConference(String[] participants) { + ImsCallSessionImplBase.this.extendToConference(participants); + } + + @Override + public void inviteParticipants(String[] participants) { + ImsCallSessionImplBase.this.inviteParticipants(participants); + } + + @Override + public void removeParticipants(String[] participants) { + ImsCallSessionImplBase.this.removeParticipants(participants); + } + + @Override + public void sendDtmf(char c, Message result) { + ImsCallSessionImplBase.this.sendDtmf(c, result); + } + + @Override + public void startDtmf(char c) { + ImsCallSessionImplBase.this.startDtmf(c); + } + + @Override + public void stopDtmf() { + ImsCallSessionImplBase.this.stopDtmf(); + } + + @Override + public void sendUssd(String ussdMessage) { + ImsCallSessionImplBase.this.sendUssd(ussdMessage); + } + + @Override + public IImsVideoCallProvider getVideoCallProvider() { + return ImsCallSessionImplBase.this.getVideoCallProvider(); + } + + @Override + public boolean isMultiparty() { + return ImsCallSessionImplBase.this.isMultiparty(); + } + + @Override + public void sendRttModifyRequest(ImsCallProfile toProfile) { + ImsCallSessionImplBase.this.sendRttModifyRequest(toProfile); + } + + @Override + public void sendRttModifyResponse(boolean status) { + ImsCallSessionImplBase.this.sendRttModifyResponse(status); + } + + @Override + public void sendRttMessage(String rttMessage) { + ImsCallSessionImplBase.this.sendRttMessage(rttMessage); + } + }; - @Override + /** + * @hide + */ public final void setListener(IImsCallSessionListener listener) throws RemoteException { setListener(new ImsCallSessionListener(listener)); } @@ -49,13 +276,14 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * can only hold one listener at a time. Subsequent calls to this method * override the previous listener. * - * @param listener to listen to the session events of this object + * @param listener {@link ImsCallSessionListener} used to notify the framework of updates + * to the ImsCallSession */ public void setListener(ImsCallSessionListener listener) { } /** - * Closes the object. This object is not usable after being closed. + * Closes the object. This {@link ImsCallSessionImplBase} is not usable after being closed. */ @Override public void close() { @@ -63,72 +291,55 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { } /** - * Gets the call ID of the session. - * - * @return the call ID + * @return A String containing the unique call ID of this {@link ImsCallSessionImplBase}. */ - @Override public String getCallId() { return null; } /** - * Gets the call profile that this session is associated with - * - * @return the {@link ImsCallProfile} that this session is associated with + * @return The {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is associated + * with. */ - @Override public ImsCallProfile getCallProfile() { return null; } /** - * Gets the local call profile that this session is associated with - * - * @return the local {@link ImsCallProfile} that this session is associated with + * @return The local {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is + * associated with. */ - @Override public ImsCallProfile getLocalCallProfile() { return null; } /** - * Gets the remote call profile that this session is associated with - * - * @return the remote {@link ImsCallProfile} that this session is associated with + * @return The remote {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is + * associated with. */ - @Override public ImsCallProfile getRemoteCallProfile() { return null; } /** - * Gets the value associated with the specified property of this session. - * - * @return the string value associated with the specified property + * @param name The String extra key. + * @return The string extra value associated with the specified property. */ - @Override public String getProperty(String name) { return null; } /** - * Gets the session state. - * The value returned must be one of the states in {@link ImsCallSession.State}. - * - * @return the session state + * @return The {@link ImsCallSessionImplBase} state, defined in + * {@link ImsCallSessionImplBase.State}. */ - @Override public int getState() { - return ImsCallSession.State.INVALID; + return ImsCallSessionImplBase.State.INVALID; } /** - * Checks if the session is in call. - * - * @return true if the session is in call, false otherwise + * @return true if the {@link ImsCallSessionImplBase} is in a call, false otherwise. */ - @Override public boolean isInCall() { return false; } @@ -136,16 +347,16 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { /** * Mutes or unmutes the mic for the active call. * - * @param muted true if the call is muted, false otherwise + * @param muted true if the call should be muted, false otherwise. */ - @Override public void setMute(boolean muted) { } /** - * Initiates an IMS call with the specified target and call profile. - * The session listener set in {@link #setListener} is called back upon defined session events. - * The method is only valid to call when the session state is in + * Initiates an IMS call with the specified number and call profile. + * The session listener set in {@link #setListener(ImsCallSessionListener)} is called back upon + * defined session events. + * Only valid to call when the session state is in * {@link ImsCallSession.State#IDLE}. * * @param callee dialed string to make the call to @@ -154,13 +365,13 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionStarted}, * {@link ImsCallSession.Listener#callSessionStartFailed} */ - @Override public void start(String callee, ImsCallProfile profile) { } /** * Initiates an IMS call with the specified participants and call profile. - * The session listener set in {@link #setListener} is called back upon defined session events. + * The session listener set in {@link #setListener(ImsCallSessionListener)} is called back upon + * defined session events. * The method is only valid to call when the session state is in * {@link ImsCallSession.State#IDLE}. * @@ -170,7 +381,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionStarted}, * {@link ImsCallSession.Listener#callSessionStartFailed} */ - @Override public void startConference(String[] participants, ImsCallProfile profile) { } @@ -181,30 +391,25 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered * @see {@link ImsCallSession.Listener#callSessionStarted} */ - @Override public void accept(int callType, ImsStreamMediaProfile profile) { } /** * Rejects an incoming call or session update. * - * @param reason reason code to reject an incoming call, defined in - * com.android.ims.ImsReasonInfo + * @param reason reason code to reject an incoming call, defined in {@link ImsReasonInfo}. * {@link ImsCallSession.Listener#callSessionStartFailed} */ - @Override public void reject(int reason) { } /** * Terminates a call. * - * @param reason reason code to terminate a call, defined in - * com.android.ims.ImsReasonInfo + * @param reason reason code to terminate a call, defined in {@link ImsReasonInfo}. * * @see {@link ImsCallSession.Listener#callSessionTerminated} */ - @Override public void terminate(int reason) { } @@ -216,7 +421,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionHeld}, * {@link ImsCallSession.Listener#callSessionHoldFailed} */ - @Override public void hold(ImsStreamMediaProfile profile) { } @@ -228,12 +432,11 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionResumed}, * {@link ImsCallSession.Listener#callSessionResumeFailed} */ - @Override public void resume(ImsStreamMediaProfile profile) { } /** - * Merges the active & hold call. When the merge starts, + * Merges the active and held call. When the merge starts, * {@link ImsCallSession.Listener#callSessionMergeStarted} is called. * {@link ImsCallSession.Listener#callSessionMergeComplete} is called if the merge is * successful, and {@link ImsCallSession.Listener#callSessionMergeFailed} is called if the merge @@ -243,7 +446,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * {@link ImsCallSession.Listener#callSessionMergeComplete}, * {@link ImsCallSession.Listener#callSessionMergeFailed} */ - @Override public void merge() { } @@ -255,7 +457,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionUpdated}, * {@link ImsCallSession.Listener#callSessionUpdateFailed} */ - @Override public void update(int callType, ImsStreamMediaProfile profile) { } @@ -267,7 +468,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionConferenceExtended}, * {@link ImsCallSession.Listener#callSessionConferenceExtendFailed} */ - @Override public void extendToConference(String[] participants) { } @@ -278,8 +478,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestDelivered}, * {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestFailed} */ - @Override - public void inviteParticipants(String[] participants) throws RemoteException { + public void inviteParticipants(String[] participants) { } /** @@ -289,7 +488,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestDelivered}, * {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestFailed} */ - @Override public void removeParticipants(String[] participants) { } @@ -300,7 +498,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. */ - @Override public void sendDtmf(char c, Message result) { } @@ -311,14 +508,12 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. */ - @Override public void startDtmf(char c) { } /** * Stop a DTMF code. */ - @Override public void stopDtmf() { } @@ -327,17 +522,23 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * * @param ussdMessage USSD message to send */ - @Override public void sendUssd(String ussdMessage) { } /** - * Returns a binder for the video call provider implementation contained within the IMS service - * process. This binder is used by the VideoCallProvider subclass in Telephony which - * intermediates between the propriety implementation and Telecomm/InCall. + * See {@link #getImsVideoCallProvider()}, used directly in older ImsService implementations. + * @hide */ - @Override public IImsVideoCallProvider getVideoCallProvider() { + ImsVideoCallProvider provider = getImsVideoCallProvider(); + return provider != null ? provider.getInterface() : null; + } + + /** + * @return The {@link ImsVideoCallProvider} implementation contained within the IMS service + * process. + */ + public ImsVideoCallProvider getImsVideoCallProvider() { return null; } @@ -345,7 +546,6 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * Determines if the current session is multiparty. * @return {@code True} if the session is multiparty. */ - @Override public boolean isMultiparty() { return false; } @@ -354,16 +554,13 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * Device issues RTT modify request * @param toProfile The profile with requested changes made */ - @Override public void sendRttModifyRequest(ImsCallProfile toProfile) { } /** * Device responds to Remote RTT modify request - * @param status true Accepted the request - * false Declined the request + * @param status true if the the request was accepted or false of the request is defined. */ - @Override public void sendRttModifyResponse(boolean status) { } @@ -371,7 +568,16 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * Device sends RTT message * @param rttMessage RTT message to be sent */ - @Override public void sendRttMessage(String rttMessage) { } + + /** @hide */ + public IImsCallSession getServiceImpl() { + return mServiceImpl; + } + + /** @hide */ + public void setServiceImpl(IImsCallSession serviceImpl) { + mServiceImpl = serviceImpl; + } } diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index ab249dac50f8..fa30ad3ba762 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -16,6 +16,7 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.content.Context; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -42,10 +43,10 @@ import java.util.HashMap; * performed every time. * @hide */ - +@SystemApi public class ImsConfigImplBase { - static final private String TAG = "ImsConfigImplBase"; + private static final String TAG = "ImsConfigImplBase"; /** * Implements the IImsConfig AIDL interface, which is called by potentially many processes @@ -89,11 +90,12 @@ public class ImsConfigImplBase { /** * Gets the value for ims service/capabilities parameters. It first checks its local cache, - * if missed, it will call ImsConfigImplBase.getProvisionedValue. + * if missed, it will call ImsConfigImplBase.getConfigInt. * Synchronous blocking call. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in Integer format. + * @param item integer key + * @return value in Integer format or {@link #CONFIG_RESULT_UNKNOWN} if + * unavailable. */ @Override public synchronized int getConfigInt(int item) throws RemoteException { @@ -110,10 +112,10 @@ public class ImsConfigImplBase { /** * Gets the value for ims service/capabilities parameters. It first checks its local cache, - * if missed, it will call #ImsConfigImplBase.getProvisionedValue. + * if missed, it will call #ImsConfigImplBase.getConfigString. * Synchronous blocking call. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param item integer key * @return value in String format. */ @Override @@ -135,9 +137,10 @@ public class ImsConfigImplBase { * from which the master value is derived, and write it into local cache. * Synchronous blocking call. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param item integer key * @param value in Integer format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @return the result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. */ @Override public synchronized int setConfigInt(int item, int value) throws RemoteException { @@ -161,7 +164,8 @@ public class ImsConfigImplBase { * * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. * @param value in String format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @return the result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. */ @Override public synchronized int setConfigString(int item, String value) @@ -244,12 +248,31 @@ public class ImsConfigImplBase { } } + /** + * The configuration requested resulted in an unknown result. This may happen if the + * IMS configurations are unavailable. + */ + public static final int CONFIG_RESULT_UNKNOWN = -1; + /** + * Setting the configuration value completed. + */ + public static final int CONFIG_RESULT_SUCCESS = 0; + /** + * Setting the configuration value failed. + */ + public static final int CONFIG_RESULT_FAILED = 1; + private final RemoteCallbackList<IImsConfigCallback> mCallbacks = new RemoteCallbackList<>(); ImsConfigStub mImsConfigStub; + /** + * Used for compatibility between older versions of the ImsService. + * @hide + */ public ImsConfigImplBase(Context context) { mImsConfigStub = new ImsConfigStub(this); } + public ImsConfigImplBase() { mImsConfigStub = new ImsConfigStub(this); } @@ -272,7 +295,11 @@ public class ImsConfigImplBase { mCallbacks.unregister(c); } - void notifyConfigChanged(int item, int value) { + /** + * @param item + * @param value + */ + private final void notifyConfigChanged(int item, int value) { // can be null in testing if (mCallbacks == null) { return; @@ -300,14 +327,17 @@ public class ImsConfigImplBase { }); } + /** + * @hide + */ public IImsConfig getIImsConfig() { return mImsConfigStub; } /** * Updates provisioning value and notifies the framework of the change. - * Doesn't call #setProvisionedValue and assumes the result succeeded. - * This should only be used by modem when they implicitly changed provisioned values. + * Doesn't call {@link #setConfig(int,int)} and assumes the result succeeded. + * This should only be used when the IMS implementer implicitly changed provisioned values. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param item an integer key. * @param value in Integer format. */ public final void notifyProvisionedValueChanged(int item, int value) { @@ -320,10 +350,10 @@ public class ImsConfigImplBase { /** * Updates provisioning value and notifies the framework of the change. - * Doesn't call #setProvisionedValue and assumes the result succeeded. - * This should only be used by modem when they implicitly changed provisioned values. + * Doesn't call {@link #setConfig(int,String)} and assumes the result succeeded. + * This should only be used when the IMS implementer implicitly changed provisioned values. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param item an integer key. * @param value in String format. */ public final void notifyProvisionedValueChanged(int item, String value) { @@ -335,51 +365,51 @@ public class ImsConfigImplBase { } /** - * Sets the value for IMS service/capabilities parameters by the operator device - * management entity. It sets the config item value in the provisioned storage - * from which the master value is derived. + * Sets the configuration value for this ImsService. * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in Integer format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @param item an integer key. + * @param value an integer containing the configuration value. + * @return the result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. */ public int setConfig(int item, int value) { // Base Implementation - To be overridden. - return ImsConfig.OperationStatusConstants.FAILED; + return CONFIG_RESULT_FAILED; } /** - * Sets the value for IMS service/capabilities parameters by the operator device - * management entity. It sets the config item value in the provisioned storage - * from which the master value is derived. + * Sets the configuration value for this ImsService. * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in String format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @param item an integer key. + * @param value a String containing the new configuration value. + * @return Result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. */ public int setConfig(int item, String value) { - return ImsConfig.OperationStatusConstants.FAILED; + // Base Implementation - To be overridden. + return CONFIG_RESULT_FAILED; } /** - * Gets the value for ims service/capabilities parameters from the provisioned - * value storage. + * Gets the currently stored value configuration value from the ImsService for {@code item}. * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in Integer format. + * @param item an integer key. + * @return configuration value, stored in integer format or {@link #CONFIG_RESULT_UNKNOWN} if + * unavailable. */ public int getConfigInt(int item) { - return ImsConfig.OperationStatusConstants.FAILED; + // Base Implementation - To be overridden. + return CONFIG_RESULT_UNKNOWN; } /** - * Gets the value for ims service/capabilities parameters from the provisioned - * value storage. + * Gets the currently stored value configuration value from the ImsService for {@code item}. * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in String format. + * @param item an integer key. + * @return configuration value, stored in String format or {@code null} if unavailable. */ public String getConfigString(int item) { + // Base Implementation - To be overridden. return null; } }
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java index 89f95ff0142d..06c35eaec6dd 100644 --- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java @@ -16,7 +16,9 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.RemoteException; +import android.util.Log; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsEcbmListener; @@ -30,22 +32,65 @@ import com.android.ims.internal.IImsEcbmListener; * * @hide */ +@SystemApi +public class ImsEcbmImplBase { + private static final String TAG = "ImsEcbmImplBase"; -public class ImsEcbmImplBase extends IImsEcbm.Stub { + private IImsEcbmListener mListener; + private IImsEcbm mImsEcbm = new IImsEcbm.Stub() { + @Override + public void setListener(IImsEcbmListener listener) { + mListener = listener; + } + + @Override + public void exitEmergencyCallbackMode() { + ImsEcbmImplBase.this.exitEmergencyCallbackMode(); + } + }; + + /** @hide */ + public IImsEcbm getImsEcbm() { + return mImsEcbm; + } /** - * Sets the listener. + * This method should be implemented by the IMS provider. Framework will trigger this method to + * request to come out of ECBM mode */ - @Override - public void setListener(IImsEcbmListener listener) throws RemoteException { - + public void exitEmergencyCallbackMode() { + Log.d(TAG, "exitEmergencyCallbackMode() not implemented"); } /** - * Requests Modem to come out of ECBM mode + * Notifies the framework when the device enters Emergency Callback Mode. + * + * @throws RuntimeException if the connection to the framework is not available. */ - @Override - public void exitEmergencyCallbackMode() throws RemoteException { + public final void enteredEcbm() { + Log.d(TAG, "Entered ECBM."); + if (mListener != null) { + try { + mListener.enteredECBM(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + /** + * Notifies the framework when the device exits Emergency Callback Mode. + * + * @throws RuntimeException if the connection to the framework is not available. + */ + public final void exitedEcbm() { + Log.d(TAG, "Exited ECBM."); + if (mListener != null) { + try { + mListener.exitedECBM(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } } } diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java index c8989e059ee5..98b67c3d3727 100644 --- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java +++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java @@ -16,6 +16,7 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.telephony.ims.feature.ImsFeature; @@ -25,17 +26,22 @@ import java.util.Set; /** * Container class for IMS Feature configuration. This class contains the features that the - * ImsService supports, which are defined in {@link ImsFeature.FeatureType}. + * ImsService supports, which are defined in {@link ImsFeature} as + * {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, {@link ImsFeature#FEATURE_MMTEL}, and + * {@link ImsFeature#FEATURE_RCS}. + * * @hide */ -public class ImsFeatureConfiguration implements Parcelable { +@SystemApi +public final class ImsFeatureConfiguration implements Parcelable { /** * Features that this ImsService supports. */ private final Set<Integer> mFeatures; /** - * Creates an ImsFeatureConfiguration with the features + * Builder for {@link ImsFeatureConfiguration} that makes adding supported {@link ImsFeature}s + * easier. */ public static class Builder { ImsFeatureConfiguration mConfig; @@ -71,7 +77,10 @@ public class ImsFeatureConfiguration implements Parcelable { * Configuration of the ImsService, which describes which features the ImsService supports * (for registration). * @param features an array of feature integers defined in {@link ImsFeature} that describe - * which features this ImsService supports. + * which features this ImsService supports. Supported values are + * {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, {@link ImsFeature#FEATURE_MMTEL}, and + * {@link ImsFeature#FEATURE_RCS}. + * @hide */ public ImsFeatureConfiguration(int[] features) { mFeatures = new ArraySet<>(); @@ -84,7 +93,9 @@ public class ImsFeatureConfiguration implements Parcelable { } /** - * @return an int[] containing the features that this ImsService supports. + * @return an int[] containing the features that this ImsService supports. Supported values are + * {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, {@link ImsFeature#FEATURE_MMTEL}, and + * {@link ImsFeature#FEATURE_RCS}. */ public int[] getServiceFeatures() { return mFeatures.stream().mapToInt(i->i).toArray(); @@ -94,6 +105,7 @@ public class ImsFeatureConfiguration implements Parcelable { mFeatures.add(feature); } + /** @hide */ protected ImsFeatureConfiguration(Parcel in) { int[] features = in.createIntArray(); if (features != null) { @@ -129,6 +141,9 @@ public class ImsFeatureConfiguration implements Parcelable { dest.writeIntArray(mFeatures.stream().mapToInt(i->i).toArray()); } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -140,6 +155,9 @@ public class ImsFeatureConfiguration implements Parcelable { return mFeatures.equals(that.mFeatures); } + /** + * @hide + */ @Override public int hashCode() { return mFeatures.hashCode(); diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java index 05da9da485a9..ce2d89a8d809 100644 --- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java @@ -16,11 +16,16 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.RemoteException; +import android.util.Log; +import android.telephony.ims.ImsExternalCallState; import com.android.ims.internal.IImsExternalCallStateListener; import com.android.ims.internal.IImsMultiEndpoint; +import java.util.List; + /** * Base implementation of ImsMultiEndpoint, which implements stub versions of the methods * in the IImsMultiEndpoint AIDL. Override the methods that your implementation of @@ -31,23 +36,49 @@ import com.android.ims.internal.IImsMultiEndpoint; * * @hide */ +@SystemApi +public class ImsMultiEndpointImplBase { + private static final String TAG = "MultiEndpointImplBase"; -public class ImsMultiEndpointImplBase extends IImsMultiEndpoint.Stub { + private IImsExternalCallStateListener mListener; + private IImsMultiEndpoint mImsMultiEndpoint = new IImsMultiEndpoint.Stub() { + @Override + public void setListener(IImsExternalCallStateListener listener) throws RemoteException { + mListener = listener; + } - /** - * Sets the listener. - */ - @Override - public void setListener(IImsExternalCallStateListener listener) throws RemoteException { + @Override + public void requestImsExternalCallStateInfo() throws RemoteException { + ImsMultiEndpointImplBase.this.requestImsExternalCallStateInfo(); + } + }; + /** @hide */ + public IImsMultiEndpoint getIImsMultiEndpoint() { + return mImsMultiEndpoint; } /** - * Query API to get the latest Dialog Event Package information - * Should be invoked only after setListener is done + * Notifies framework when Dialog Event Package update is received + * + * @throws RuntimeException if the connection to the framework is not available. */ - @Override - public void requestImsExternalCallStateInfo() throws RemoteException { + public final void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallDialogs) { + Log.d(TAG, "ims external call state update triggered."); + if (mListener != null) { + try { + mListener.onImsExternalCallStateUpdate(externalCallDialogs); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + /** + * This method should be implemented by the IMS provider. Framework will trigger this to get the + * latest Dialog Event Package information. Should + */ + public void requestImsExternalCallStateInfo() { + Log.d(TAG, "requestImsExternalCallStateInfo() not implemented"); } } diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index dfb9b63f7b14..4334d3aadab3 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -17,6 +17,7 @@ package android.telephony.ims.stub; import android.annotation.IntDef; +import android.annotation.SystemApi; import android.net.Uri; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -24,7 +25,8 @@ import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; -import com.android.ims.ImsReasonInfo; +import android.telephony.ims.ImsReasonInfo; + import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; @@ -35,11 +37,14 @@ import java.lang.annotation.RetentionPolicy; * registration for this ImsService has changed status. * @hide */ - +@SystemApi public class ImsRegistrationImplBase { private static final String LOG_TAG = "ImsRegistrationImplBase"; + /** + * @hide + */ // Defines the underlying radio technology type that we have registered for IMS over. @IntDef(flag = true, value = { @@ -154,6 +159,9 @@ public class ImsRegistrationImplBase { // Locked on mLock, create unspecified disconnect cause. private ImsReasonInfo mLastDisconnectCause = new ImsReasonInfo(); + /** + * @hide + */ public final IImsRegistration getBinder() { return mBinder; } @@ -170,8 +178,8 @@ public class ImsRegistrationImplBase { /** * Notify the framework that the device is connected to the IMS network. * - * @param imsRadioTech the radio access technology. Valid values are defined in - * {@link ImsRegistrationTech}. + * @param imsRadioTech the radio access technology. Valid values are defined as + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. */ public final void onRegistered(@ImsRegistrationTech int imsRadioTech) { updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERED); @@ -188,8 +196,8 @@ public class ImsRegistrationImplBase { /** * Notify the framework that the device is trying to connect the IMS network. * - * @param imsRadioTech the radio access technology. Valid values are defined in - * {@link ImsRegistrationTech}. + * @param imsRadioTech the radio access technology. Valid values are defined as + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. */ public final void onRegistering(@ImsRegistrationTech int imsRadioTech) { updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERING); @@ -220,6 +228,13 @@ public class ImsRegistrationImplBase { }); } + /** + * Notify the framework that the handover from the current radio technology to the technology + * defined in {@code imsRadioTech} has failed. + * @param imsRadioTech The technology that has failed to be changed. Valid values are + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. + * @param info The {@link ImsReasonInfo} for the failure to change technology. + */ public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech, ImsReasonInfo info) { mCallbacks.broadcast((c) -> { @@ -232,6 +247,11 @@ public class ImsRegistrationImplBase { }); } + /** + * The this device's subscriber associated {@link Uri}s have changed, which are used to filter + * out this device's {@link Uri}s during conference calling. + * @param uris + */ public final void onSubscriberAssociatedUriChanged(Uri[] uris) { mCallbacks.broadcast((c) -> { try { @@ -263,6 +283,11 @@ public class ImsRegistrationImplBase { } } + /** + * @return the current registration connection type. Valid values are + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN} + * @hide + */ @VisibleForTesting public final @ImsRegistrationTech int getConnectionType() { synchronized (mLock) { diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java index 9b9301193f1b..bf8953386e49 100644 --- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java @@ -157,7 +157,7 @@ public class ImsSmsImplBase { * @param token token provided in {@link #onSmsReceived(int, String, byte[])} * @param result result of delivering the message. Valid values are: * {@link #DELIVER_STATUS_OK}, - * {@link #DELIVER_STATUS_OK} + * {@link #DELIVER_STATUS_ERROR} * @param messageRef the message reference */ public void acknowledgeSms(int token, @DeliverStatusResult int messageRef, int result) { @@ -302,9 +302,9 @@ public class ImsSmsImplBase { } /** - * Called when SmsImpl has been initialized and communication with the framework is set up. + * Called when ImsSmsImpl has been initialized and communication with the framework is set up. * Any attempt by this class to access the framework before this method is called will return - * with an {@link RuntimeException}. + * with a {@link RuntimeException}. */ public void onReady() { // Base Implementation - Should be overridden diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java index 054a8b22d0f2..fcd7faf73bb8 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java @@ -16,177 +16,332 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.Bundle; import android.os.RemoteException; +import android.telephony.ims.ImsUtListener; import com.android.ims.internal.IImsUt; import com.android.ims.internal.IImsUtListener; /** - * Base implementation of ImsUt, which implements stub versions of the methods - * in the IImsUt AIDL. Override the methods that your implementation of ImsUt supports. - * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsUt maintained by other ImsServices. - * - * Provides the Ut interface interworking to get/set the supplementary service configuration. + * Base implementation of IMS UT interface, which implements stubs. Override these methods to + * implement functionality. * * @hide */ +// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you +// will break other implementations of ImsUt maintained by other ImsServices. +@SystemApi +public class ImsUtImplBase { + + private IImsUt.Stub mServiceImpl = new IImsUt.Stub() { + @Override + public void close() throws RemoteException { + ImsUtImplBase.this.close(); + } + + @Override + public int queryCallBarring(int cbType) throws RemoteException { + return ImsUtImplBase.this.queryCallBarring(cbType); + } + + @Override + public int queryCallForward(int condition, String number) throws RemoteException { + return ImsUtImplBase.this.queryCallForward(condition, number); + } + + @Override + public int queryCallWaiting() throws RemoteException { + return ImsUtImplBase.this.queryCallWaiting(); + } + + @Override + public int queryCLIR() throws RemoteException { + return ImsUtImplBase.this.queryCLIR(); + } + + @Override + public int queryCLIP() throws RemoteException { + return ImsUtImplBase.this.queryCLIP(); + } + + @Override + public int queryCOLR() throws RemoteException { + return ImsUtImplBase.this.queryCOLR(); + } + + @Override + public int queryCOLP() throws RemoteException { + return ImsUtImplBase.this.queryCOLP(); + } + + @Override + public int transact(Bundle ssInfo) throws RemoteException { + return ImsUtImplBase.this.transact(ssInfo); + } + + @Override + public int updateCallBarring(int cbType, int action, String[] barrList) throws + RemoteException { + return ImsUtImplBase.this.updateCallBarring(cbType, action, barrList); + } + + @Override + public int updateCallForward(int action, int condition, String number, int serviceClass, + int timeSeconds) throws RemoteException { + return ImsUtImplBase.this.updateCallForward(action, condition, number, serviceClass, + timeSeconds); + } + + @Override + public int updateCallWaiting(boolean enable, int serviceClass) throws RemoteException { + return ImsUtImplBase.this.updateCallWaiting(enable, serviceClass); + } + + @Override + public int updateCLIR(int clirMode) throws RemoteException { + return ImsUtImplBase.this.updateCLIR(clirMode); + } + + @Override + public int updateCLIP(boolean enable) throws RemoteException { + return ImsUtImplBase.this.updateCLIP(enable); + } -public class ImsUtImplBase extends IImsUt.Stub { + @Override + public int updateCOLR(int presentation) throws RemoteException { + return ImsUtImplBase.this.updateCOLR(presentation); + } + + @Override + public int updateCOLP(boolean enable) throws RemoteException { + return ImsUtImplBase.this.updateCOLP(enable); + } + + @Override + public void setListener(IImsUtListener listener) throws RemoteException { + ImsUtImplBase.this.setListener(new ImsUtListener(listener)); + } + + @Override + public int queryCallBarringForServiceClass(int cbType, int serviceClass) + throws RemoteException { + return ImsUtImplBase.this.queryCallBarringForServiceClass(cbType, serviceClass); + } + + @Override + public int updateCallBarringForServiceClass(int cbType, int action, + String[] barrList, int serviceClass) throws RemoteException { + return ImsUtImplBase.this.updateCallBarringForServiceClass( + cbType, action, barrList, serviceClass); + } + }; /** - * Closes the object. This object is not usable after being closed. + * Called when the framework no longer needs to interact with the IMS UT implementation any + * longer. */ - @Override - public void close() throws RemoteException { + public void close() { } /** - * Retrieves the configuration of the call barring. + * Retrieves the call barring configuration. + * @param cbType */ - @Override - public int queryCallBarring(int cbType) throws RemoteException { + public int queryCallBarring(int cbType) { return -1; } /** * Retrieves the configuration of the call barring for specified service class. */ - @Override - public int queryCallBarringForServiceClass(int cbType, int serviceClass) - throws RemoteException { + public int queryCallBarringForServiceClass(int cbType, int serviceClass) { return -1; } /** * Retrieves the configuration of the call forward. */ - @Override - public int queryCallForward(int condition, String number) throws RemoteException { + public int queryCallForward(int condition, String number) { return -1; } /** * Retrieves the configuration of the call waiting. */ - @Override - public int queryCallWaiting() throws RemoteException { + public int queryCallWaiting() { return -1; } /** * Retrieves the default CLIR setting. + * @hide + */ + public int queryCLIR() { + return queryClir(); + } + + /** + * Retrieves the CLIP call setting. + * @hide + */ + public int queryCLIP() { + return queryClip(); + } + + /** + * Retrieves the COLR call setting. + * @hide + */ + public int queryCOLR() { + return queryColr(); + } + + /** + * Retrieves the COLP call setting. + * @hide + */ + public int queryCOLP() { + return queryColp(); + } + + /** + * Retrieves the default CLIR setting. */ - @Override - public int queryCLIR() throws RemoteException { + public int queryClir() { return -1; } /** * Retrieves the CLIP call setting. */ - @Override - public int queryCLIP() throws RemoteException { + public int queryClip() { return -1; } /** * Retrieves the COLR call setting. */ - @Override - public int queryCOLR() throws RemoteException { + public int queryColr() { return -1; } /** * Retrieves the COLP call setting. */ - @Override - public int queryCOLP() throws RemoteException { + public int queryColp() { return -1; } /** * Updates or retrieves the supplementary service configuration. */ - @Override - public int transact(Bundle ssInfo) throws RemoteException { + public int transact(Bundle ssInfo) { return -1; } /** * Updates the configuration of the call barring. */ - @Override - public int updateCallBarring(int cbType, int action, String[] barrList) throws RemoteException { + public int updateCallBarring(int cbType, int action, String[] barrList) { return -1; } /** * Updates the configuration of the call barring for specified service class. */ - @Override public int updateCallBarringForServiceClass(int cbType, int action, String[] barrList, - int serviceClass) throws RemoteException { + int serviceClass) { return -1; } /** * Updates the configuration of the call forward. */ - @Override public int updateCallForward(int action, int condition, String number, int serviceClass, - int timeSeconds) throws RemoteException { + int timeSeconds) { return 0; } /** * Updates the configuration of the call waiting. */ - @Override - public int updateCallWaiting(boolean enable, int serviceClass) throws RemoteException { + public int updateCallWaiting(boolean enable, int serviceClass) { return -1; } /** * Updates the configuration of the CLIR supplementary service. + * @hide + */ + public int updateCLIR(int clirMode) { + return updateClir(clirMode); + } + + /** + * Updates the configuration of the CLIP supplementary service. + * @hide + */ + public int updateCLIP(boolean enable) { + return updateClip(enable); + } + + /** + * Updates the configuration of the COLR supplementary service. + * @hide + */ + public int updateCOLR(int presentation) { + return updateColr(presentation); + } + + /** + * Updates the configuration of the COLP supplementary service. + * @hide + */ + public int updateCOLP(boolean enable) { + return updateColp(enable); + } + + /** + * Updates the configuration of the CLIR supplementary service. */ - @Override - public int updateCLIR(int clirMode) throws RemoteException { + public int updateClir(int clirMode) { return -1; } /** * Updates the configuration of the CLIP supplementary service. */ - @Override - public int updateCLIP(boolean enable) throws RemoteException { + public int updateClip(boolean enable) { return -1; } /** * Updates the configuration of the COLR supplementary service. */ - @Override - public int updateCOLR(int presentation) throws RemoteException { + public int updateColr(int presentation) { return -1; } /** * Updates the configuration of the COLP supplementary service. */ - @Override - public int updateCOLP(boolean enable) throws RemoteException { + public int updateColp(boolean enable) { return -1; } /** * Sets the listener. */ - @Override - public void setListener(IImsUtListener listener) throws RemoteException { + public void setListener(ImsUtListener listener) { + } + + /** + * @hide + */ + public IImsUt getInterface() { + return mServiceImpl; } } |