diff options
| author | 2022-11-04 17:39:15 +0000 | |
|---|---|---|
| committer | 2022-11-04 17:39:15 +0000 | |
| commit | c4622bdf01d01446f6fb84bd3319e74efa26748c (patch) | |
| tree | 6ccac1cfe0dde37aabbb7f00d475993912662099 | |
| parent | eae57aba3fea163c70b9a675e9e6fa56e30e6f60 (diff) | |
| parent | b389c9270001edde4ca9b4383fff3398cea88d64 (diff) | |
Merge changes from topic "sync-call-info-for-srvcc"
* changes:
Fix javadoc description of notifySrvccStarted
Add system apis to support SRVCC
7 files changed, 329 insertions, 0 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 70b89b8af044..1b732cc8c8b0 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -13125,6 +13125,7 @@ package android.telephony { field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2 field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0 field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5 + field public static final int PRECISE_CALL_STATE_INCOMING_SETUP = 9; // 0x9 field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6 } @@ -15380,6 +15381,16 @@ package android.telephony.ims { field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.SipMessage> CREATOR; } + public final class SrvccCall implements android.os.Parcelable { + ctor public SrvccCall(@NonNull String, int, @NonNull android.telephony.ims.ImsCallProfile); + method public int describeContents(); + method @NonNull public String getCallId(); + method @NonNull public android.telephony.ims.ImsCallProfile getImsCallProfile(); + method public int getPreciseCallState(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.SrvccCall> CREATOR; + } + } package android.telephony.ims.feature { @@ -15440,6 +15451,10 @@ package android.telephony.ims.feature { method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle); method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo); + method public void notifySrvccCanceled(); + method public void notifySrvccCompleted(); + method public void notifySrvccFailed(); + method public void notifySrvccStarted(@NonNull java.util.function.Consumer<java.util.List<android.telephony.ims.SrvccCall>>); method public final void notifyVoiceMessageCountUpdate(int); method public void onFeatureReady(); method public void onFeatureRemoved(); diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java index 98eeacf1a416..d4b912e76b2d 100644 --- a/telephony/java/android/telephony/PreciseCallState.java +++ b/telephony/java/android/telephony/PreciseCallState.java @@ -66,6 +66,11 @@ public final class PreciseCallState implements Parcelable { public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; /** Call state: Disconnecting. */ public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; + /** + * Call state: Incoming in pre-alerting state. + * A call will be in this state prior to entering {@link #PRECISE_CALL_STATE_ALERTING}. + */ + public static final int PRECISE_CALL_STATE_INCOMING_SETUP = 9; private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID; private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID; diff --git a/telephony/java/android/telephony/ims/SrvccCall.aidl b/telephony/java/android/telephony/ims/SrvccCall.aidl new file mode 100644 index 000000000000..0f0a0795cb2e --- /dev/null +++ b/telephony/java/android/telephony/ims/SrvccCall.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022 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 SrvccCall; diff --git a/telephony/java/android/telephony/ims/SrvccCall.java b/telephony/java/android/telephony/ims/SrvccCall.java new file mode 100644 index 000000000000..cdc271ec8070 --- /dev/null +++ b/telephony/java/android/telephony/ims/SrvccCall.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2022 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.Parcel; +import android.os.Parcelable; +import android.telephony.Annotation.PreciseCallStates; + +import java.util.Objects; + +/** + * A Parcelable object to represent the current state of an IMS call that is being tracked + * in the ImsService when an SRVCC begins. This information will be delivered to modem. + * @see SrvccStartedCallback + * + * @hide + */ +@SystemApi +public final class SrvccCall implements Parcelable { + private static final String TAG = "SrvccCall"; + + /** The IMS call profile */ + private ImsCallProfile mImsCallProfile; + + /** The IMS call id */ + private String mCallId; + + /** The call state */ + private @PreciseCallStates int mCallState; + + private SrvccCall(Parcel in) { + readFromParcel(in); + } + + /** + * Constructs an instance of SrvccCall. + * + * @param callId the call ID associated with the IMS call + * @param callState the state of this IMS call + * @param imsCallProfile the profile associated with this IMS call + * @throws IllegalArgumentException if the callId or the imsCallProfile is null + */ + public SrvccCall(@NonNull String callId, @PreciseCallStates int callState, + @NonNull ImsCallProfile imsCallProfile) { + if (callId == null) throw new IllegalArgumentException("callId is null"); + if (imsCallProfile == null) throw new IllegalArgumentException("imsCallProfile is null"); + + mCallId = callId; + mCallState = callState; + mImsCallProfile = imsCallProfile; + } + + /** + * @return the {@link ImsCallProfile} associated with this IMS call, + * which will be used to get the address, the name, and the audio direction + * including the call in pre-alerting state. + */ + @NonNull + public ImsCallProfile getImsCallProfile() { + return mImsCallProfile; + } + + /** + * @return the call ID associated with this IMS call. + * + * @see android.telephony.ims.stub.ImsCallSessionImplBase#getCallId(). + */ + @NonNull + public String getCallId() { + return mCallId; + } + + /** + * @return the call state of the associated IMS call. + */ + public @PreciseCallStates int getPreciseCallState() { + return mCallState; + } + + @NonNull + @Override + public String toString() { + return "{ callId=" + mCallId + + ", callState=" + mCallState + + ", imsCallProfile=" + mImsCallProfile + + " }"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SrvccCall that = (SrvccCall) o; + return mImsCallProfile.equals(that.mImsCallProfile) + && mCallId.equals(that.mCallId) + && mCallState == that.mCallState; + } + + @Override + public int hashCode() { + int result = Objects.hash(mImsCallProfile, mCallId); + result = 31 * result + mCallState; + return result; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeString(mCallId); + out.writeInt(mCallState); + out.writeParcelable(mImsCallProfile, 0); + } + + private void readFromParcel(Parcel in) { + mCallId = in.readString(); + mCallState = in.readInt(); + mImsCallProfile = in.readParcelable(ImsCallProfile.class.getClassLoader(), + android.telephony.ims.ImsCallProfile.class); + } + + public static final @android.annotation.NonNull Creator<SrvccCall> CREATOR = + new Creator<SrvccCall>() { + @Override + public SrvccCall createFromParcel(Parcel in) { + return new SrvccCall(in); + } + + @Override + public SrvccCall[] newArray(int size) { + return new SrvccCall[size]; + } + }; +} diff --git a/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl index 801b81c0e498..85191734872a 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl @@ -20,6 +20,7 @@ import android.os.Message; import android.telephony.ims.aidl.IImsMmTelListener; import android.telephony.ims.aidl.IImsSmsListener; import android.telephony.ims.aidl.IImsCapabilityCallback; +import android.telephony.ims.aidl.ISrvccStartedCallback; import android.telephony.ims.feature.CapabilityChangeRequest; import android.telephony.ims.RtpHeaderExtensionType; @@ -55,6 +56,10 @@ interface IImsMmTelFeature { IImsCapabilityCallback c); oneway void queryCapabilityConfiguration(int capability, int radioTech, IImsCapabilityCallback c); + oneway void notifySrvccStarted(in ISrvccStartedCallback cb); + oneway void notifySrvccCompleted(); + oneway void notifySrvccFailed(); + oneway void notifySrvccCanceled(); // SMS APIs void setSmsListener(IImsSmsListener l); oneway void sendSms(in int token, int messageRef, String format, String smsc, boolean retry, diff --git a/telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl b/telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl new file mode 100644 index 000000000000..a173abffbb8f --- /dev/null +++ b/telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 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.aidl; + +import android.telephony.ims.SrvccCall; + +import java.util.List; + +/** + * {@hide} + */ +oneway interface ISrvccStartedCallback { + void onSrvccCallNotified(in List<SrvccCall> profiles); +} diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index c0ff12efb3c2..8147759769e6 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -31,10 +31,12 @@ import android.telephony.ims.ImsException; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsService; import android.telephony.ims.RtpHeaderExtensionType; +import android.telephony.ims.SrvccCall; 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.aidl.ISrvccStartedCallback; import android.telephony.ims.stub.ImsCallSessionImplBase; import android.telephony.ims.stub.ImsEcbmImplBase; import android.telephony.ims.stub.ImsMultiEndpointImplBase; @@ -60,6 +62,7 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; import java.util.function.Supplier; /** @@ -289,6 +292,38 @@ public class MmTelFeature extends ImsFeature { "onSmsReady"); } + @Override + public void notifySrvccStarted(final ISrvccStartedCallback cb) { + executeMethodAsyncNoException( + () -> MmTelFeature.this.notifySrvccStarted( + (profiles) -> { + try { + cb.onSrvccCallNotified(profiles); + } catch (Exception e) { + Log.e(LOG_TAG, "onSrvccCallNotified e=" + e); + } + }), + "notifySrvccStarted"); + } + + @Override + public void notifySrvccCompleted() { + executeMethodAsyncNoException( + () -> MmTelFeature.this.notifySrvccCompleted(), "notifySrvccCompleted"); + } + + @Override + public void notifySrvccFailed() { + executeMethodAsyncNoException( + () -> MmTelFeature.this.notifySrvccFailed(), "notifySrvccFailed"); + } + + @Override + public void notifySrvccCanceled() { + executeMethodAsyncNoException( + () -> MmTelFeature.this.notifySrvccCanceled(), "notifySrvccCanceled"); + } + // Call the methods with a clean calling identity on the executor and wait indefinitely for // the future to return. private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException { @@ -969,6 +1004,75 @@ public class MmTelFeature extends ImsFeature { "Not implemented on device."); } + /** + * Notifies the MmTelFeature that the network has initiated an SRVCC (Single radio voice + * call continuity) for all IMS calls. When the network initiates an SRVCC, calls from + * the LTE domain are handed over to the legacy circuit switched domain. The modem requires + * knowledge of ongoing calls in the IMS domain in order to complete the SRVCC operation. + * <p> + * @param consumer The callback used to notify the framework of the list of IMS calls and their + * state at the time of the SRVCC. + * + * @hide + */ + @SystemApi + public void notifySrvccStarted(@NonNull Consumer<List<SrvccCall>> consumer) { + // Base Implementation - Should be overridden by IMS service + } + + /** + * Notifies the MmTelFeature that the SRVCC is completed and the calls have been moved + * over to the circuit-switched domain. + * {@link android.telephony.CarrierConfigManager.ImsVoice#KEY_SRVCC_TYPE_INT_ARRAY} + * specifies the calls can be moved. Other calls will be disconnected. + * <p> + * The MmTelFeature may now release all resources related to the IMS calls. + * + * @hide + */ + @SystemApi + public void notifySrvccCompleted() { + // Base Implementation - Should be overridden by IMS service + } + + /** + * Notifies the MmTelFeature that the SRVCC has failed. + * + * The handover can fail by encountering a failure at the radio level + * or temporary MSC server internal errors in handover procedure. + * Refer to 3GPP TS 23.216 section 8 Handover Failure. + * <p> + * IMS service will recover and continue calls over IMS. + * Per TS 24.237 12.2.4.2, UE shall send SIP UPDATE request containing the reason-text + * set to "failure to transition to CS domain". + * + * @hide + */ + @SystemApi + public void notifySrvccFailed() { + // Base Implementation - Should be overridden by IMS service + } + + /** + * Notifies the MmTelFeature that the SRVCC has been canceled. + * + * Since the state of network can be changed, the network can decide to terminate + * the handover procedure before its completion and to return to its state before the handover + * procedure was triggered. + * Refer to 3GPP TS 23.216 section 8.1.3 Handover Cancellation. + * + * <p> + * IMS service will recover and continue calls over IMS. + * Per TS 24.237 12.2.4.2, UE shall send SIP UPDATE request containing the reason-text + * set to "handover canceled". + * + * @hide + */ + @SystemApi + public void notifySrvccCanceled() { + // Base Implementation - Should be overridden by IMS service + } + private void setSmsListener(IImsSmsListener listener) { getSmsImplementation().registerSmsListener(listener); } |