summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt15
-rw-r--r--telephony/java/android/telephony/PreciseCallState.java5
-rw-r--r--telephony/java/android/telephony/ims/SrvccCall.aidl19
-rw-r--r--telephony/java/android/telephony/ims/SrvccCall.java153
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl5
-rw-r--r--telephony/java/android/telephony/ims/aidl/ISrvccStartedCallback.aidl28
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java104
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);
}