Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fddca1d3 authored by Sewook Seo's avatar Sewook Seo
Browse files

Notify IMS Call info via CallAttributesListener

Notify IMS call type & IMS call ID through CallAttributes.
List of CallAttributes mapped to whole calls will be passed to the
listener.

Bug: 242928210
Test: atest FrameworksTelephonyTests
Change-Id: I1584524cec49af0694f691efdcbec4210f06e092
parent 14e6daea
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -12499,14 +12499,14 @@ package android.telephony {
    method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
  }
  public final class CallAttributes implements android.os.Parcelable {
    ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
    method public int describeContents();
    method @NonNull public android.telephony.CallQuality getCallQuality();
    method public int getNetworkType();
    method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
  @Deprecated public final class CallAttributes implements android.os.Parcelable {
    ctor @Deprecated public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
    method @Deprecated public int describeContents();
    method @Deprecated @NonNull public android.telephony.CallQuality getCallQuality();
    method @Deprecated public int getNetworkType();
    method @Deprecated @NonNull public android.telephony.PreciseCallState getPreciseCallState();
    method @Deprecated public void writeToParcel(android.os.Parcel, int);
    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
  }
  public final class CallForwardingInfo implements android.os.Parcelable {
@@ -12586,6 +12586,28 @@ package android.telephony {
    method @NonNull public android.telephony.CallQuality.Builder setUplinkCallQualityLevel(int);
  }
  public final class CallState implements android.os.Parcelable {
    method public int describeContents();
    method @Nullable public android.telephony.CallQuality getCallQuality();
    method public int getCallState();
    method public int getImsCallServiceType();
    method @Nullable public String getImsCallSessionId();
    method public int getImsCallType();
    method public int getNetworkType();
    method public void writeToParcel(@Nullable android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallState> CREATOR;
  }
  public static final class CallState.Builder {
    ctor public CallState.Builder(int);
    method @NonNull public android.telephony.CallState build();
    method @NonNull public android.telephony.CallState.Builder setCallQuality(@Nullable android.telephony.CallQuality);
    method @NonNull public android.telephony.CallState.Builder setImsCallServiceType(int);
    method @NonNull public android.telephony.CallState.Builder setImsCallSessionId(@Nullable String);
    method @NonNull public android.telephony.CallState.Builder setImsCallType(int);
    method @NonNull public android.telephony.CallState.Builder setNetworkType(int);
  }
  public class CarrierConfigManager {
    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
    method @NonNull public static android.os.PersistableBundle getDefaultConfig();
@@ -13333,7 +13355,8 @@ package android.telephony {
  }
  public static interface TelephonyCallback.CallAttributesListener {
    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public default void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public default void onCallStatesChanged(@NonNull java.util.List<android.telephony.CallState>);
  }
  public static interface TelephonyCallback.DataEnabledListener {
@@ -14423,6 +14446,7 @@ package android.telephony.ims {
    field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
    field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
    field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
    field public static final int CALL_TYPE_NONE = 0; // 0x0
    field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
    field public static final int CALL_TYPE_VOICE = 2; // 0x2
    field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
+39 −4
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.os.Build;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DisconnectCauses;
import android.telephony.Annotation.PreciseDisconnectCauses;
import android.telephony.Annotation.RadioPowerState;
@@ -726,7 +725,7 @@ public class PhoneStateListener {
     */
    @Deprecated
    @RequiresPermission(value = android.Manifest.permission.READ_PHONE_STATE, conditional = true)
    public void onCallStateChanged(@CallState int state, String phoneNumber) {
    public void onCallStateChanged(@Annotation.CallState int state, String phoneNumber) {
        // default implementation empty
    }

@@ -1569,12 +1568,48 @@ public class PhoneStateListener {
                    () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state)));
        }

        public void onCallAttributesChanged(CallAttributes callAttributes) {
        public void onCallStatesChanged(List<CallState> callStateList) {
            PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
            if (psl == null) return;

            if (callStateList == null) return;
            CallAttributes ca;
            if (callStateList.isEmpty()) {
                ca = new CallAttributes(
                        new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_IDLE,
                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
                        TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality());
            } else {
                int foregroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
                int backgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
                int ringingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
                for (CallState cs : callStateList) {
                    switch (cs.getCallClassification()) {
                        case CallState.CALL_CLASSIFICATION_FOREGROUND:
                            foregroundCallState = cs.getCallState();
                            break;
                        case CallState.CALL_CLASSIFICATION_BACKGROUND:
                            backgroundCallState = cs.getCallState();
                            break;
                        case CallState.CALL_CLASSIFICATION_RINGING:
                            ringingCallState = cs.getCallState();
                            break;
                        default:
                            break;
                    }
                }
                ca = new CallAttributes(
                        new PreciseCallState(
                                foregroundCallState, backgroundCallState, ringingCallState,
                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
                        callStateList.get(0).getNetworkType(),
                        callStateList.get(0).getCallQuality());
            }
            Binder.withCleanCallingIdentity(
                    () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes)));
                    () -> mExecutor.execute(
                            () -> psl.onCallAttributesChanged(ca)));
        }

        public void onActiveDataSubIdChanged(int subId) {
+76 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.Binder;
import android.os.Build;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IPhoneStateListener;
@@ -62,7 +63,7 @@ import java.util.concurrent.Executor;
 * appropriate sub-interfaces.
 */
public class TelephonyCallback {

    private static final String LOG_TAG = "TelephonyCallback";
    /**
     * Experiment flag to set the per-pid registration limit for TelephonyCallback
     *
@@ -1332,7 +1333,9 @@ public class TelephonyCallback {
    @SystemApi
    public interface CallAttributesListener {
        /**
         * Callback invoked when the call attributes changes on the registered subscription.
         * Callback invoked when the call attributes changes on the active call on the registered
         * subscription. If the user swaps between a foreground and background call the call
         * attributes will be reported for the active call only.
         * Note, the registration subscription ID comes from {@link TelephonyManager} object
         * which registers TelephonyCallback by
         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
@@ -1346,9 +1349,77 @@ public class TelephonyCallback {
         * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}.
         *
         * @param callAttributes the call attributes
         * @deprecated Use onCallStatesChanged({@link List<CallState>}) to get each of call
         *          state for all ongoing calls on the subscription.
         */
        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
        @Deprecated
        default void onCallAttributesChanged(@NonNull CallAttributes callAttributes) {
            Log.w(LOG_TAG, "onCallAttributesChanged(List<CallAttributes>) should be "
                    + "overridden.");
        }

        /**
         * Callback invoked when the call attributes changes on the ongoing calls on the registered
         * subscription. If there are 1 foreground and 1 background call, Two {@link CallState}
         * will be passed.
         * Note, the registration subscription ID comes from {@link TelephonyManager} object
         * which registers TelephonyCallback by
         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}.
         * If this TelephonyManager object was created with
         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
         * subscription ID. Otherwise, this callback applies to
         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
         * In the event that there are no active(state is not
         * {@link PreciseCallState#PRECISE_CALL_STATE_IDLE}) calls, this API will report empty list.
         *
         * The calling app should have carrier privileges
         * (see {@link TelephonyManager#hasCarrierPrivileges}) if it does not have the
         * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}.
         *
         * @param callStateList the list of call states for each ongoing call. If there are
         *                           a active call and a holding call, 1 call attributes for
         *                           {@link PreciseCallState#PRECISE_CALL_STATE_ACTIVE}  and another
         *                           for {@link PreciseCallState#PRECISE_CALL_STATE_HOLDING}
         *                           will be in this list.
         */
        // Added as default for backward compatibility
        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
        void onCallAttributesChanged(@NonNull CallAttributes callAttributes);
        default void onCallStatesChanged(@NonNull List<CallState> callStateList) {
            if (callStateList.size() > 0) {
                int foregroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
                int backgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
                int ringingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
                for (CallState cs : callStateList) {
                    switch (cs.getCallClassification()) {
                        case CallState.CALL_CLASSIFICATION_FOREGROUND:
                            foregroundCallState = cs.getCallState();
                            break;
                        case CallState.CALL_CLASSIFICATION_BACKGROUND:
                            backgroundCallState = cs.getCallState();
                            break;
                        case CallState.CALL_CLASSIFICATION_RINGING:
                            ringingCallState = cs.getCallState();
                            break;
                        default:
                            break;
                    }
                }
                onCallAttributesChanged(new CallAttributes(
                        new PreciseCallState(
                                ringingCallState, foregroundCallState, backgroundCallState,
                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
                        callStateList.get(0).getNetworkType(),
                        callStateList.get(0).getCallQuality()));
            } else {
                onCallAttributesChanged(new CallAttributes(
                        new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_IDLE,
                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
                                PreciseCallState.PRECISE_CALL_STATE_IDLE,
                                DisconnectCause.NOT_VALID, PreciseDisconnectCause.NOT_VALID),
                        TelephonyManager.NETWORK_TYPE_UNKNOWN, new CallQuality()));
            }
        }
    }

    /**
@@ -1702,14 +1773,13 @@ public class TelephonyCallback {
                    () -> mExecutor.execute(() -> listener.onRadioPowerStateChanged(state)));
        }

        public void onCallAttributesChanged(CallAttributes callAttributes) {
        public void onCallStatesChanged(List<CallState> callStateList) {
            CallAttributesListener listener =
                    (CallAttributesListener) mTelephonyCallbackWeakRef.get();
            if (listener == null) return;

            Binder.withCleanCallingIdentity(
                    () -> mExecutor.execute(() -> listener.onCallAttributesChanged(
                            callAttributes)));
                    () -> mExecutor.execute(() -> listener.onCallStatesChanged(callStateList)));
        }

        public void onActiveDataSubIdChanged(int subId) {
+12 −9
Original line number Diff line number Diff line
@@ -32,13 +32,13 @@ import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.DisconnectCauses;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.PreciseCallStates;
import android.telephony.Annotation.PreciseDisconnectCauses;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsCallSession;
import android.telephony.ims.ImsReasonInfo;
import android.util.ArraySet;
import android.util.Log;
@@ -741,17 +741,20 @@ public class TelephonyRegistryManager {
     * @param slotIndex for which precise call state changed. Can be derived from subId except when
     * subId is invalid.
     * @param subId for which precise call state changed.
     * @param ringCallPreciseState ringCall state.
     * @param foregroundCallPreciseState foreground call state.
     * @param backgroundCallPreciseState background call state.
     * @param callStates Array of PreciseCallState of foreground, background & ringing calls.
     * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId} for
     *                   ringing, foreground & background calls.
     * @param imsServiceTypes Array of IMS call service type for ringing, foreground &
     *                        background calls.
     * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls.
     */
    public void notifyPreciseCallState(int slotIndex, int subId,
            @PreciseCallStates int ringCallPreciseState,
            @PreciseCallStates int foregroundCallPreciseState,
            @PreciseCallStates int backgroundCallPreciseState) {
            @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds,
            @Annotation.ImsCallServiceType int[] imsServiceTypes,
            @Annotation.ImsCallType int[] imsCallTypes) {
        try {
            sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
                foregroundCallPreciseState, backgroundCallPreciseState);
            sRegistry.notifyPreciseCallState(slotIndex, subId, callStates,
                    imsCallIds, imsServiceTypes, imsCallTypes);
        } catch (RemoteException ex) {
            // system process is dead
            throw ex.rethrowFromSystemServer();
+2 −2
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.internal.telephony;

import android.telephony.BarringInfo;
import android.telephony.CallAttributes;
import android.telephony.CallState;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.DataConnectionRealTimeInfo;
@@ -62,7 +62,7 @@ oneway interface IPhoneStateListener {
    void onPhoneCapabilityChanged(in PhoneCapability capability);
    void onActiveDataSubIdChanged(in int subId);
    void onRadioPowerStateChanged(in int state);
    void onCallAttributesChanged(in CallAttributes callAttributes);
    void onCallStatesChanged(in List<CallState> callStateList);
    @SuppressWarnings(value={"untyped-collection"})
    void onEmergencyNumberListChanged(in Map emergencyNumberList);
    void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber, int subscriptionId);
Loading