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

Commit dee00245 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix potential race condition in Call." into rvc-dev

parents a33d5799 3d4b8e78
Loading
Loading
Loading
Loading
+62 −7
Original line number Diff line number Diff line
@@ -85,7 +85,9 @@ public abstract class Call {
    public State mState = State.IDLE;

    @UnsupportedAppUsage
    public ArrayList<Connection> mConnections = new ArrayList<Connection>();
    public ArrayList<Connection> mConnections = new ArrayList<>();

    private Object mLock = new Object();

    /* Instance Methods */

@@ -94,7 +96,30 @@ public abstract class Call {
     */

    @UnsupportedAppUsage
    public abstract List<Connection> getConnections();
    public ArrayList<Connection> getConnections() {
        synchronized (mLock) {
            return (ArrayList<Connection>) mConnections.clone();
        }
    }

    /**
     * Get mConnections field from another Call instance.
     * @param other
     */
    public void copyConnectionFrom(Call other) {
        mConnections = other.getConnections();
    }

    /**
     * Get connections count of this instance.
     * @return the count to return
     */
    public int getConnectionsCount() {
        synchronized (mLock) {
            return mConnections.size();
        }
    }

    @UnsupportedAppUsage
    public abstract Phone getPhone();
    @UnsupportedAppUsage
@@ -129,6 +154,37 @@ public abstract class Call {
        return connections.size() > 0;
    }

    /**
     * removeConnection
     *
     * @param conn the connection to be removed
     */
    public void removeConnection(Connection conn) {
        synchronized (mLock) {
            mConnections.remove(conn);
        }
    }

    /**
     * addConnection
     *
     * @param conn the connection to be added
     */
    public void addConnection(Connection conn) {
        synchronized (mLock) {
            mConnections.add(conn);
        }
    }

    /**
     * clearConnection
     */
    public void clearConnections() {
        synchronized (mLock) {
            mConnections.clear();
        }
    }

    /**
     * getState
     * @return state of class call
@@ -289,14 +345,13 @@ public abstract class Call {
     * Called when it's time to clean up disconnected Connection objects
     */
    public void clearDisconnected() {
        for (int i = mConnections.size() - 1 ; i >= 0 ; i--) {
            Connection c = mConnections.get(i);
            if (c.getState() == State.DISCONNECTED) {
                mConnections.remove(i);
        for (Connection conn : getConnections()) {
            if (conn.getState() == State.DISCONNECTED) {
                removeConnection(conn);
            }
        }

        if (mConnections.size() == 0) {
        if (getConnectionsCount() == 0) {
            setState(State.IDLE);
        }
    }
+10 −20
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.internal.telephony;

import android.compat.annotation.UnsupportedAppUsage;

import java.util.List;

/**
 * {@hide}
 */
@@ -36,12 +34,6 @@ public class GsmCdmaCall extends Call {

    /************************** Overridden from Call *************************/

    @Override
    public List<Connection> getConnections() {
        // FIXME should return Collections.unmodifiableList();
        return mConnections;
    }

    @Override
    public Phone getPhone() {
        return mOwner.getPhone();
@@ -49,7 +41,7 @@ public class GsmCdmaCall extends Call {

    @Override
    public boolean isMultiparty() {
        return mConnections.size() > 1;
        return getConnectionsCount() > 1;
    }

    /** Please note: if this is the foreground call and a
@@ -79,14 +71,14 @@ public class GsmCdmaCall extends Call {
    //***** Called from GsmCdmaConnection

    public void attach(Connection conn, DriverCall dc) {
        mConnections.add(conn);
        addConnection(conn);

        mState = stateFromDCState (dc.state);
    }

    @UnsupportedAppUsage
    public void attachFake(Connection conn, State state) {
        mConnections.add(conn);
        addConnection(conn);

        mState = state;
    }
@@ -100,8 +92,8 @@ public class GsmCdmaCall extends Call {

            boolean hasOnlyDisconnectedConnections = true;

            for (int i = 0, s = mConnections.size(); i < s; i ++) {
                if (mConnections.get(i).getState() != State.DISCONNECTED) {
            for (Connection c : getConnections()) {
                if (c.getState() != State.DISCONNECTED) {
                    hasOnlyDisconnectedConnections = false;
                    break;
                }
@@ -117,9 +109,9 @@ public class GsmCdmaCall extends Call {
    }

    public void detach(GsmCdmaConnection conn) {
        mConnections.remove(conn);
        removeConnection(conn);

        if (mConnections.size() == 0) {
        if (getConnectionsCount() == 0) {
            mState = State.IDLE;
        }
    }
@@ -143,7 +135,7 @@ public class GsmCdmaCall extends Call {
     * connections to be added via "conference"
     */
    /*package*/ boolean isFull() {
        return mConnections.size() == mOwner.getMaxConnectionsPerCall();
        return getConnectionsCount() == mOwner.getMaxConnectionsPerCall();
    }

    //***** Called from GsmCdmaCallTracker
@@ -155,10 +147,8 @@ public class GsmCdmaCall extends Call {
     * but no response has yet been received so update() has not yet been called
     */
    void onHangupLocal() {
        for (int i = 0, s = mConnections.size(); i < s; i++) {
            GsmCdmaConnection cn = (GsmCdmaConnection)mConnections.get(i);

            cn.onHangupLocal();
        for (Connection conn : getConnections()) {
            ((GsmCdmaConnection) conn).onHangupLocal();
        }
        mState = State.DISCONNECTING;
    }
+33 −38
Original line number Diff line number Diff line
@@ -260,16 +260,13 @@ public class GsmCdmaCallTracker extends CallTracker {

    @UnsupportedAppUsage
    private void fakeHoldForegroundBeforeDial() {
        List<Connection> connCopy;

        // We need to make a copy here, since fakeHoldBeforeDial()
        // modifies the lists, and we don't want to reverse the order
        connCopy = (List<Connection>) mForegroundCall.mConnections.clone();

        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
            GsmCdmaConnection conn = (GsmCdmaConnection)connCopy.get(i);
        ArrayList<Connection> connCopy = mForegroundCall.getConnections();

            conn.fakeHoldBeforeDial();
        for (Connection conn : connCopy) {
            GsmCdmaConnection gsmCdmaConn = (GsmCdmaConnection) conn;
            gsmCdmaConn.fakeHoldBeforeDial();
        }
    }

@@ -602,7 +599,7 @@ public class GsmCdmaCallTracker extends CallTracker {
                mCi.switchWaitingOrHoldingAndActive(
                        obtainCompleteMessage(EVENT_SWITCH_RESULT));
            } else {
                if (mForegroundCall.getConnections().size() > 1) {
                if (mForegroundCall.getConnectionsCount() > 1) {
                    flashAndSetGenericTrue();
                } else {
                    // Send a flash command to CDMA network for putting the other party on hold.
@@ -931,18 +928,19 @@ public class GsmCdmaCallTracker extends CallTracker {
                    // we need to clean up the foregroundCall and ringingCall.
                    // Loop through foreground call connections as
                    // it contains the known logical connections.
                    int count = mForegroundCall.mConnections.size();
                    ArrayList<Connection> connections = mForegroundCall.getConnections();
                    int count = connections.size();
                    for (int n = 0; n < count; n++) {
                        if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
                        GsmCdmaConnection cn = (GsmCdmaConnection)mForegroundCall.mConnections.get(n);
                        GsmCdmaConnection cn = (GsmCdmaConnection) connections.get(n);
                        mDroppedDuringPoll.add(cn);
                    }
                    count = mRingingCall.mConnections.size();
                    count = mRingingCall.getConnectionsCount();
                    // Loop through ringing call connections as
                    // it may contain the known logical connections.
                    for (int n = 0; n < count; n++) {
                        if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
                        GsmCdmaConnection cn = (GsmCdmaConnection)mRingingCall.mConnections.get(n);
                        GsmCdmaConnection cn = (GsmCdmaConnection) connections.get(n);
                        mDroppedDuringPoll.add(cn);
                    }

@@ -1274,7 +1272,7 @@ public class GsmCdmaCallTracker extends CallTracker {
    //***** Called from GsmCdmaCall

    public void hangup(GsmCdmaCall call) throws CallStateException {
        if (call.getConnections().size() == 0) {
        if (call.getConnectionsCount() == 0) {
            throw new CallStateException("no connections in call");
        }

@@ -1316,18 +1314,20 @@ public class GsmCdmaCallTracker extends CallTracker {
    }

    private void logHangupEvent(GsmCdmaCall call) {
        int count = call.mConnections.size();
        for (int i = 0; i < count; i++) {
            GsmCdmaConnection cn = (GsmCdmaConnection) call.mConnections.get(i);
        for (Connection conn : call.getConnections()) {
            GsmCdmaConnection c = (GsmCdmaConnection) conn;
            int call_index;
            try {
                call_index = cn.getGsmCdmaIndex();
            } catch (CallStateException ex) {
                call_index = c.getGsmCdmaIndex();
            } catch (CallStateException e) {
                call_index = -1;
            }
            mMetrics.writeRilHangup(mPhone.getPhoneId(), cn, call_index, getNetworkCountryIso());
            mMetrics.writeRilHangup(mPhone.getPhoneId(), c, call_index, getNetworkCountryIso());
        }
        if (VDBG) {
            Rlog.v(LOG_TAG, "logHangupEvent logged " + call.getConnectionsCount()
                    + " Connections ");
        }
        if (VDBG) Rlog.v(LOG_TAG, "logHangupEvent logged " + count + " Connections ");
    }

    public void hangupWaitingOrBackground() {
@@ -1343,29 +1343,26 @@ public class GsmCdmaCallTracker extends CallTracker {

    public void hangupConnectionByIndex(GsmCdmaCall call, int index)
            throws CallStateException {
        int count = call.mConnections.size();
        for (int i = 0; i < count; i++) {
            GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
            if (!cn.mDisconnected && cn.getGsmCdmaIndex() == index) {
                mMetrics.writeRilHangup(mPhone.getPhoneId(), cn, cn.getGsmCdmaIndex(),
        for (Connection conn : call.getConnections()) {
            GsmCdmaConnection c = (GsmCdmaConnection) conn;
            if (!c.mDisconnected && c.getGsmCdmaIndex() == index) {
                mMetrics.writeRilHangup(mPhone.getPhoneId(), c, c.getGsmCdmaIndex(),
                        getNetworkCountryIso());
                mCi.hangupConnection(index, obtainCompleteMessage());
                return;
            }
        }

        throw new CallStateException("no GsmCdma index found");
    }

    public void hangupAllConnections(GsmCdmaCall call) {
        try {
            int count = call.mConnections.size();
            for (int i = 0; i < count; i++) {
                GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
                if (!cn.mDisconnected) {
                    mMetrics.writeRilHangup(mPhone.getPhoneId(), cn, cn.getGsmCdmaIndex(),
            for (Connection conn : call.getConnections()) {
                GsmCdmaConnection c = (GsmCdmaConnection) conn;
                if (!c.mDisconnected) {
                    mMetrics.writeRilHangup(mPhone.getPhoneId(), c, c.getGsmCdmaIndex(),
                            getNetworkCountryIso());
                    mCi.hangupConnection(cn.getGsmCdmaIndex(), obtainCompleteMessage());
                    mCi.hangupConnection(c.getGsmCdmaIndex(), obtainCompleteMessage());
                }
            }
        } catch (CallStateException ex) {
@@ -1375,14 +1372,12 @@ public class GsmCdmaCallTracker extends CallTracker {

    public GsmCdmaConnection getConnectionByIndex(GsmCdmaCall call, int index)
            throws CallStateException {
        int count = call.mConnections.size();
        for (int i = 0; i < count; i++) {
            GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
            if (!cn.mDisconnected && cn.getGsmCdmaIndex() == index) {
                return cn;
        for (Connection conn : call.getConnections()) {
            GsmCdmaConnection c = (GsmCdmaConnection) conn;
            if (!c.mDisconnected && c.getGsmCdmaIndex() == index) {
                return c;
            }
        }

        return null;
    }

+1 −9
Original line number Diff line number Diff line
@@ -21,11 +21,8 @@ import android.telephony.ims.ImsExternalCallState;

import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;

import java.util.List;

/**
 * Companion class for {@link ImsExternalConnection}; represents an external call which was
 * received via {@link ImsExternalCallState} info.
@@ -37,12 +34,7 @@ public class ImsExternalCall extends Call {
    @UnsupportedAppUsage
    public ImsExternalCall(Phone phone, ImsExternalConnection connection) {
        mPhone = phone;
        mConnections.add(connection);
    }

    @Override
    public List<Connection> getConnections() {
        return mConnections;
        addConnection(connection);
    }

    @Override
+3 −3
Original line number Diff line number Diff line
@@ -1402,11 +1402,11 @@ public class ImsPhone extends ImsPhoneBase {
    public ArrayList<Connection> getHandoverConnection() {
        ArrayList<Connection> connList = new ArrayList<Connection>();
        // Add all foreground call connections
        connList.addAll(getForegroundCall().mConnections);
        connList.addAll(getForegroundCall().getConnections());
        // Add all background call connections
        connList.addAll(getBackgroundCall().mConnections);
        connList.addAll(getBackgroundCall().getConnections());
        // Add all background call connections
        connList.addAll(getRingingCall().mConnections);
        connList.addAll(getRingingCall().getConnections());
        if (connList.size() > 0) {
            return connList;
        } else {
Loading