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

Commit c7173237 authored by Grace Jia's avatar Grace Jia
Browse files

Add a lock for call read/write operations to avoid

ConcurrentModificationException.

Bug: 189816293
Test: InCallService cts tests
Change-Id: I123b2de55b856d12ee2a5e6d2fa49c15a74592fc
parent 001ec603
Loading
Loading
Loading
Loading
+31 −14
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.os.Build;
import android.os.Bundle;
import android.util.ArrayMap;

import com.android.internal.annotations.GuardedBy;

import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -115,6 +117,7 @@ public final class Phone {
    public static final int SDK_VERSION_R = 30;

    // A Map allows us to track each Call by its Telecom-specified call ID
    @GuardedBy("mLock")
    private final Map<String, Call> mCallByTelecomCallId = new ArrayMap<>();

    // A List allows us to keep the Calls in a stable iteration order so that casually developed
@@ -139,6 +142,8 @@ public final class Phone {
     */
    private final int mTargetSdkVersion;

    private final Object mLock = new Object();

    Phone(InCallAdapter adapter, String callingPackage, int targetSdkVersion) {
        mInCallAdapter = adapter;
        mCallingPackage = callingPackage;
@@ -152,12 +157,16 @@ public final class Phone {
            return;
        }

        Call call = mCallByTelecomCallId.get(parcelableCall.getId());
        Call call = getCallById(parcelableCall.getId());
        if (call == null) {
            call = new Call(this, parcelableCall.getId(), mInCallAdapter,
                    parcelableCall.getState(), mCallingPackage, mTargetSdkVersion);

            synchronized (mLock) {
                mCallByTelecomCallId.put(parcelableCall.getId(), call);
                mCalls.add(call);
            }

            checkCallTree(parcelableCall);
            call.internalUpdate(parcelableCall, mCallByTelecomCallId);
            fireCallAdded(call);
@@ -169,8 +178,10 @@ public final class Phone {
    }

    final void internalRemoveCall(Call call) {
        synchronized (mLock) {
            mCallByTelecomCallId.remove(call.internalGetCallId());
            mCalls.remove(call);
        }

        InCallService.VideoCall videoCall = call.getVideoCall();
        if (videoCall != null) {
@@ -183,14 +194,14 @@ public final class Phone {
        if (mTargetSdkVersion < SDK_VERSION_R
                && parcelableCall.getState() == Call.STATE_AUDIO_PROCESSING) {
            Log.i(this, "removing audio processing call during update for sdk compatibility");
            Call call = mCallByTelecomCallId.get(parcelableCall.getId());
            Call call = getCallById(parcelableCall.getId());
            if (call != null) {
                internalRemoveCall(call);
            }
            return;
        }

        Call call = mCallByTelecomCallId.get(parcelableCall.getId());
        Call call = getCallById(parcelableCall.getId());
        if (call != null) {
            checkCallTree(parcelableCall);
            call.internalUpdate(parcelableCall, mCallByTelecomCallId);
@@ -207,8 +218,14 @@ public final class Phone {
        }
    }

    Call getCallById(String callId) {
        synchronized (mLock) {
            return mCallByTelecomCallId.get(callId);
        }
    }

    final void internalSetPostDialWait(String telecomId, String remaining) {
        Call call = mCallByTelecomCallId.get(telecomId);
        Call call = getCallById(telecomId);
        if (call != null) {
            call.internalSetPostDialWait(remaining);
        }
@@ -222,7 +239,7 @@ public final class Phone {
    }

    final Call internalGetCallByTelecomId(String telecomId) {
        return mCallByTelecomCallId.get(telecomId);
        return getCallById(telecomId);
    }

    final void internalBringToForeground(boolean showDialpad) {
@@ -241,35 +258,35 @@ public final class Phone {
    }

    final void internalOnConnectionEvent(String telecomId, String event, Bundle extras) {
        Call call = mCallByTelecomCallId.get(telecomId);
        Call call = getCallById(telecomId);
        if (call != null) {
            call.internalOnConnectionEvent(event, extras);
        }
    }

    final void internalOnRttUpgradeRequest(String callId, int requestId) {
        Call call = mCallByTelecomCallId.get(callId);
        Call call = getCallById(callId);
        if (call != null) {
            call.internalOnRttUpgradeRequest(requestId);
        }
    }

    final void internalOnRttInitiationFailure(String callId, int reason) {
        Call call = mCallByTelecomCallId.get(callId);
        Call call = getCallById(callId);
        if (call != null) {
            call.internalOnRttInitiationFailure(reason);
        }
    }

    final void internalOnHandoverFailed(String callId, int error) {
        Call call = mCallByTelecomCallId.get(callId);
        Call call = getCallById(callId);
        if (call != null) {
            call.internalOnHandoverFailed(error);
        }
    }

    final void internalOnHandoverComplete(String callId) {
        Call call = mCallByTelecomCallId.get(callId);
        Call call = getCallById(callId);
        if (call != null) {
            call.internalOnHandoverComplete();
        }