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

Commit 7dd50276 authored by Hunsuk Choi's avatar Hunsuk Choi
Browse files

Notifies IMS call information to the modem

Bug: 255450284
Test: atest ImsCallInfoNotifierTest
Change-Id: I320d39421824c6dc69450a976129392149dd7284
parent 1c3a1f5d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.telephony.ims.stub.ImsRegistrationImplBase;
import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
import com.android.internal.telephony.emergency.EmergencyConstants;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.imsphone.ImsCallInfo;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.SimPhonebookRecord;
@@ -2964,4 +2965,12 @@ public interface CommandsInterface {
     * @param result Callback message containing the success or failure status.
     */
    default void setNullCipherAndIntegrityEnabled(boolean enabled, Message result) {}

    /**
     * Notifies the IMS call status to the modem.
     *
     * @param imsCallInfo The list of {@link ImsCallInfo}.
     * @param result A callback to receive the response.
     */
    default void updateImsCallStatus(@NonNull List<ImsCallInfo> imsCallInfo, Message result) {}
}
+11 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.emergency.EmergencyConstants;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsCallInfo;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
import com.android.internal.telephony.metrics.SmsStats;
@@ -5080,6 +5081,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    public void handleNullCipherEnabledChange() {
    }

    /**
     * Notifies the IMS call status to the modem.
     *
     * @param imsCallInfo The list of {@link ImsCallInfo}.
     * @param response A callback to receive the response.
     */
    public void updateImsCallStatus(@NonNull List<ImsCallInfo> imsCallInfo, Message response) {
        mCi.updateImsCallStatus(imsCallInfo, response);
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("Phone: subId=" + getSubId());
        pw.println(" mPhoneId=" + mPhoneId);
+33 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ import com.android.internal.telephony.cdma.CdmaInformationRecords;
import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
import com.android.internal.telephony.emergency.EmergencyConstants;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.imsphone.ImsCallInfo;
import com.android.internal.telephony.metrics.ModemRestartStats;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
@@ -5594,6 +5595,38 @@ public class RIL extends BaseCommands implements CommandsInterface {
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateImsCallStatus(@NonNull List<ImsCallInfo> imsCallInfo, Message result) {
        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
        if (imsProxy.isEmpty()) return;
        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
            RILRequest rr = obtainRequest(RIL_REQUEST_UPDATE_IMS_CALL_STATUS, result,
                    mRILDefaultWorkSource);

            if (RILJ_LOGD) {
                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
                        + " " + imsCallInfo);
            }
            try {
                imsProxy.updateImsCallStatus(rr.mSerial, RILUtils.convertImsCallInfo(imsCallInfo));
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "updateImsCallStatus", e);
            }
        } else {
            if (RILJ_LOGD) {
                Rlog.d(RILJ_LOG_TAG, "updateImsCallStatus: REQUEST_NOT_SUPPORTED");
            }
            if (result != null) {
                AsyncResult.forMessage(result, null,
                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                result.sendToTarget();
            }
        }
    }

    //***** Private Methods
    /**
     * This is a helper function to be called when an indication callback is called for any radio
+63 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SWITCH_WAI
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_TRIGGER_EMERGENCY_NETWORK_SCAN;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_TRIGGER_EPS_FALLBACK;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UDUB;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UPDATE_IMS_CALL_STATUS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UPDATE_IMS_REGISTRATION_INFO;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_VOICE_RADIO_TECH;
@@ -361,6 +362,7 @@ import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.telephony.data.KeepaliveStatus;
import com.android.internal.telephony.data.KeepaliveStatus.KeepaliveStatusCode;
import com.android.internal.telephony.imsphone.ImsCallInfo;
import com.android.internal.telephony.uicc.AdnCapacity;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
import com.android.internal.telephony.uicc.IccCardStatus;
@@ -5197,6 +5199,8 @@ public class RILUtils {
                return "TRIGGER_EPS_FALLBACK";
            case RIL_REQUEST_SET_NULL_CIPHER_AND_INTEGRITY_ENABLED:
                return "SET_NULL_CIPHER_AND_INTEGRITY_ENABLED";
            case RIL_REQUEST_UPDATE_IMS_CALL_STATUS:
                return "UPDATE_IMS_CALL_STATUS";
            default:
                return "<unknown request " + request + ">";
        }
@@ -5681,6 +5685,65 @@ public class RILUtils {
        return halCapabilities;
    }

    /** Converts the ImsCallInfo instances to HAL ImsCall instances. */
    public static android.hardware.radio.ims.ImsCall[] convertImsCallInfo(
            List<ImsCallInfo> imsCallInfos) {
        if (imsCallInfos == null) {
            return new android.hardware.radio.ims.ImsCall[0];
        }

        int length = 0;
        for (int i = 0; i < imsCallInfos.size(); i++) {
            if (imsCallInfos.get(i) != null) length++;
        }
        if (length == 0) {
            return new android.hardware.radio.ims.ImsCall[0];
        }

        android.hardware.radio.ims.ImsCall[] halInfos =
                new android.hardware.radio.ims.ImsCall[length];

        int index = 0;
        for (int i = 0; i < imsCallInfos.size(); i++) {
            ImsCallInfo info = imsCallInfos.get(i);
            if (info == null) continue;

            halInfos[index] = new android.hardware.radio.ims.ImsCall();
            halInfos[index].index = info.getIndex();
            halInfos[index].callState = convertToHalImsCallState(info.getCallState());
            halInfos[index].callType = info.isEmergencyCall()
                    ? android.hardware.radio.ims.ImsCall.CallType.EMERGENCY
                    : android.hardware.radio.ims.ImsCall.CallType.NORMAL;
            halInfos[index].accessNetwork = convertToHalAccessNetworkAidl(info.getCallRadioTech());
            halInfos[index].direction = info.isIncoming()
                    ? android.hardware.radio.ims.ImsCall.Direction.INCOMING
                    : android.hardware.radio.ims.ImsCall.Direction.OUTGOING;
            halInfos[index].isHeldByRemote = info.isHeldByRemote();
            index++;
        }

        return halInfos;
    }

    /**
     * Converts the call state to HAL IMS call state.
     *
     * @param state The {@link Call.State}.
     * @return The converted {@link android.hardware.radio.ims.ImsCall.CallState}.
     */
    private static int convertToHalImsCallState(Call.State state) {
        switch (state) {
            case ACTIVE: return android.hardware.radio.ims.ImsCall.CallState.ACTIVE;
            case HOLDING: return android.hardware.radio.ims.ImsCall.CallState.HOLDING;
            case DIALING: return android.hardware.radio.ims.ImsCall.CallState.DIALING;
            case ALERTING: return android.hardware.radio.ims.ImsCall.CallState.ALERTING;
            case INCOMING: return android.hardware.radio.ims.ImsCall.CallState.INCOMING;
            case WAITING: return android.hardware.radio.ims.ImsCall.CallState.WAITING;
            case DISCONNECTING: return android.hardware.radio.ims.ImsCall.CallState.DISCONNECTING;
            default: return android.hardware.radio.ims.ImsCall.CallState.DISCONNECTED;
        }
    }

    private static void logd(String log) {
        Rlog.d("RILUtils", log);
    }
+116 −0
Original line number Diff line number Diff line
/*
 * 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 com.android.internal.telephony.imsphone;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.telephony.AccessNetworkConstants;
import android.telephony.ServiceState;

import com.android.internal.telephony.Call;

/**
 * Contains call state to be notified to modem.
 */
public class ImsCallInfo {

    private final int mIndex;
    private @Nullable ImsPhoneConnection mConnection = null;
    private Call.State mState = Call.State.IDLE;
    private boolean mIsHeldByRemote = false;

    public ImsCallInfo(int index) {
        mIndex = index;
    }

    /** Clears the call state. */
    public void reset() {
        mConnection = null;
        mState = Call.State.IDLE;
        mIsHeldByRemote = false;
    }

    /**
     * Updates the state of the IMS call.
     *
     * @param c The instance of {@link ImsPhoneConnection}.
     */
    public void update(@NonNull ImsPhoneConnection c) {
        mConnection = c;
        mState = c.getState();
    }

    /**
     * Updates the state of the IMS call.
     *
     * @param c The instance of {@link ImsPhoneConnection}.
     * @param holdReceived {@code true} if the remote party held the call.
     * @param resumeReceived {@code true} if the remote party resumed the call.
     */
    public boolean update(@NonNull ImsPhoneConnection c,
            boolean holdReceived, boolean resumeReceived) {
        Call.State state = c.getState();
        boolean changed = mState != state;
        mState = state;

        if (holdReceived && !mIsHeldByRemote) {
            changed = true;
            mIsHeldByRemote = true;
        } else if (resumeReceived && mIsHeldByRemote) {
            changed = true;
            mIsHeldByRemote = false;
        }

        return changed;
    }

    /** @return the call index. */
    public int getIndex() {
        return mIndex;
    }

    /** @return the call state. */
    public Call.State getCallState() {
        return mState;
    }

    /** @return whether the remote party is holding the call. */
    public boolean isHeldByRemote() {
        return mIsHeldByRemote;
    }

    /** @return {@code true} if the call is an incoming call. */
    public boolean isIncoming() {
        return mConnection.isIncoming();
    }

    /** @return {@code true} if the call is an emergency call. */
    public boolean isEmergencyCall() {
        return mConnection.isEmergencyCall();
    }

    /** @return the radio technology used for current connection. */
    public @AccessNetworkConstants.RadioAccessNetworkType int getCallRadioTech() {
        return ServiceState.rilRadioTechnologyToAccessNetworkType(mConnection.getCallRadioTech());
    }

    @Override
    public String toString() {
        return "[ id=" + mIndex + ", state=" + mState
                + ", isMT=" + isIncoming() + ", heldByRemote=" + mIsHeldByRemote + " ]";
    }
}
Loading