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

Commit 782196a4 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Fix issue where >2 party conference connect time is wrong on child drop.

In the past, ParcelableCallUtils would report the connect time of the
conference to the incall UI by looking for the earliest connect time among
the children of the conference.  This is problematic as it means that if
the oldest participant in a conference disconnects, the UI will now show
the conference connect time of the next latest participant.

To fix this, as children are added to the conference we do the connect
time update on the conference itself and don't do the calculation in the
parcelable call utils.

Test: manual test with carrier calls to verify connect time on the parent
does not get reduced.
Test: Add unit test to verify behavior.
Fixes: 152611824

Change-Id: Ic5fd2dfef5e0e196fc5d83a216fc7fec469e37f8
parent 41dbedc8
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.telecom;

import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -1641,7 +1642,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        mCreationTimeMillis = time;
    }

    long getConnectTimeMillis() {
    public long getConnectTimeMillis() {
        return mConnectTimeMillis;
    }

@@ -2805,7 +2806,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
     * ensure the InCall UI is updated with the change in parent.
     * @param parentCall The new parent for this call.
     */
    void setChildOf(Call parentCall) {
    public void setChildOf(Call parentCall) {
        if (parentCall != null && !parentCall.getChildCalls().contains(this)) {
            parentCall.addChildCall(this);
        }
@@ -2843,6 +2844,11 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
            mConferenceLevelActiveCall = call;
            mChildCalls.add(call);

            // When adding a child, we will potentially adjust the various times from the calls
            // based on the children being added.  This ensures the parent of the conference has a
            // connect time reflective of all the children added.
            maybeAdjustConnectTime(call);

            Log.addEvent(this, LogUtils.Events.ADD_CHILD, call);

            for (Listener l : mListeners) {
@@ -2851,6 +2857,30 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        }
    }

    /**
     * Potentially adjust the connect and creation time of this call based on another one.
     * Ensures that if the other call has an earlier connect time that we adjust the connect time of
     * this call to match.
     * <p>
     * This is important for conference calls; as we add children to the conference we need to
     * ensure that earlier connect time is reflected on the conference.  In the past this
     * was just done in {@link ParcelableCallUtils} when parceling the calls to the UI, but that
     * approach would not reflect the right time on the parent as children disconnect.
     *
     * @param call the call to potentially use to adjust connect time.
     */
    private void maybeAdjustConnectTime(@NonNull Call call) {
        long childConnectTimeMillis = call.getConnectTimeMillis();
        long currentConnectTimeMillis = getConnectTimeMillis();
        // Conference calls typically have a 0 connect time, so we will replace the current connect
        // time if its zero also.
        if (childConnectTimeMillis != 0
                && (currentConnectTimeMillis == 0
                || childConnectTimeMillis < getConnectTimeMillis())) {
            setConnectTimeMillis(childConnectTimeMillis);
        }
    }

    private void removeChildCall(Call call) {
        if (mChildCalls.remove(call)) {
            Log.addEvent(this, LogUtils.Events.REMOVE_CHILD, call);
+1 −11
Original line number Diff line number Diff line
@@ -181,22 +181,12 @@ public class ParcelableCallUtils {
            parentCallId = parentCall.getId();
        }

        long connectTimeMillis = call.getConnectTimeMillis();
        List<Call> childCalls = call.getChildCalls();
        List<String> childCallIds = new ArrayList<>();
        if (!childCalls.isEmpty()) {
            long childConnectTimeMillis = Long.MAX_VALUE;
            for (Call child : childCalls) {
                if (child.getConnectTimeMillis() > 0) {
                    childConnectTimeMillis = Math.min(child.getConnectTimeMillis(),
                            childConnectTimeMillis);
                }
                childCallIds.add(child.getId());
            }

            if (childConnectTimeMillis != Long.MAX_VALUE) {
                connectTimeMillis = childConnectTimeMillis;
            }
        }

        Uri handle = call.getHandlePresentation() == TelecomManager.PRESENTATION_ALLOWED ?
@@ -240,7 +230,7 @@ public class ParcelableCallUtils {
                .setCapabilities(capabilities)
                .setProperties(properties)
                .setSupportedAudioRoutes(supportedAudioRoutes)
                .setConnectTimeMillis(connectTimeMillis)
                .setConnectTimeMillis(call.getConnectTimeMillis())
                .setHandle(handle)
                .setHandlePresentation(call.getHandlePresentation())
                .setCallerDisplayName(callerDisplayName)
+28 −0
Original line number Diff line number Diff line
@@ -1213,6 +1213,34 @@ public class CallsManagerTest extends TelecomTestCase {
        assertFalse(outgoingCall.getStartWithSpeakerphoneOn());
    }

    /**
     * Verify that a parent call will inherit the connect time of its children.
     * @throws Exception
     */
    @SmallTest
    @Test
    public void testParentInheritsChildConnectTime() throws Exception {
        Call callSim1 = createCall(SIM_1_HANDLE, null, CallState.ACTIVE);
        Call callSim2 = createCall(SIM_1_HANDLE, null, CallState.ACTIVE);
        callSim1.setConnectTimeMillis(100);

        // Pretend it is a conference made later.
        callSim2.setConnectTimeMillis(0);

        // Make the first call a child of the second (pretend conference).
        callSim1.setChildOf(callSim2);

        assertEquals(100, callSim2.getConnectTimeMillis());

        // Add another later call.
        Call callSim3 = createCall(SIM_1_HANDLE, null, CallState.ACTIVE);
        callSim3.setConnectTimeMillis(200);
        callSim3.setChildOf(callSim2);

        // Later call shouldn't impact parent.
        assertEquals(100, callSim2.getConnectTimeMillis());
    }

    /**
     * Make sure that CallsManager handles a screening result that has both
     * silence and screen-further set to true as a request to screen further.