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

Commit 8d4b741e authored by Tyler Gunn's avatar Tyler Gunn Committed by Automerger Merge Worker
Browse files

Merge "Fix holding behavior across self-manged ConnectionServices." into udc-dev am: 390a9d13

parents 66559628 390a9d13
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -3430,10 +3430,11 @@ public class CallsManager extends Call.ListenerBase
     */
    boolean holdActiveCallForNewCall(Call call) {
        Call activeCall = (Call) mConnectionSvrFocusMgr.getCurrentFocusCall();
        Log.i(this, "holdActiveCallForNewCall, newCall: %s, activeCall: %s", call, activeCall);
        Log.i(this, "holdActiveCallForNewCall, newCall: %s, activeCall: %s", call.getId(),
                (activeCall == null ? "<none>" : activeCall.getId()));
        if (activeCall != null && activeCall != call) {
            if (canHold(activeCall)) {
                activeCall.hold();
                activeCall.hold("swap to " + call.getId());
                return true;
            } else if (supportsHold(activeCall)
                    && areFromSameSource(activeCall, call)) {
@@ -4918,12 +4919,25 @@ public class CallsManager extends Call.ListenerBase
                    liveCallPhoneAccount);
        }

        // First thing, if we are trying to make a call with the same phone account as the live
        // call, then allow it so that the connection service can make its own decision about
        // how to handle the new call relative to the current one.
        // First thing, for managed calls, if we are trying to make a call with the same phone
        // account as the live call, then allow it so that the connection service can make its own
        // decision about how to handle the new call relative to the current one.
        // Note: This behavior is primarily in place because Telephony historically manages the
        // state of the calls it tracks by itself, holding and unholding as needed.  Self-managed
        // calls, even though from the same package are normally held/unheld automatically by
        // Telecom.  Calls within a single ConnectionService get held/unheld automatically during
        // "swap" operations by CallsManager#holdActiveCallForNewCall.  There is, however, a quirk
        // in that if an app declares TWO different ConnectionServices, holdActiveCallForNewCall
        // would not work correctly because focus switches between ConnectionServices, yet we
        // tended to assume that if the calls are from the same package that the hold/unhold should
        // be done by the app.  That was a bad assumption as it meant that we could have two active
        // calls.
        // TODO(b/280826075): We need to come back and revisit all this logic in a holistic manner.
        if (PhoneAccountHandle.areFromSamePackage(liveCallPhoneAccount,
                call.getTargetPhoneAccount())) {
            Log.i(this, "makeRoomForOutgoingCall: phoneAccount matches.");
                call.getTargetPhoneAccount())
                && !call.isSelfManaged()
                && !liveCall.isSelfManaged()) {
            Log.i(this, "makeRoomForOutgoingCall: managed phoneAccount matches");
            call.getAnalytics().setCallIsAdditional(true);
            liveCall.getAnalytics().setCallIsInterrupted(true);
            return true;
@@ -5503,6 +5517,13 @@ public class CallsManager extends Call.ListenerBase
            impl.dump(pw);
            pw.decreaseIndent();
        }

        if (mConnectionSvrFocusMgr != null) {
            pw.println("mConnectionSvrFocusMgr:");
            pw.increaseIndent();
            mConnectionSvrFocusMgr.dump(pw);
            pw.decreaseIndent();
        }
    }

    /**
+21 −2
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ import android.os.Message;
import android.telecom.Log;
import android.telecom.Logging.Session;
import android.text.TextUtils;
import android.util.LocalLog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;

import java.util.ArrayList;
import java.util.List;
@@ -41,6 +43,7 @@ import java.util.stream.Collectors;
public class ConnectionServiceFocusManager {
    private static final String TAG = "ConnectionSvrFocusMgr";
    private static final int GET_CURRENT_FOCUS_TIMEOUT_MILLIS = 1000;
    private final LocalLog mLocalLog = new LocalLog(20);

    /** Factory interface used to create the {@link ConnectionServiceFocusManager} instance. */
    public interface ConnectionServiceFocusManagerFactory {
@@ -124,6 +127,11 @@ public class ConnectionServiceFocusManager {
         * @return {@code True} if this call can receive focus, {@code false} otherwise.
         */
        boolean isFocusable();

        /**
         * @return the ID of the focusable for debug purposes.
         */
        String getId();
    }

    /** Interface define a call back for focus request event. */
@@ -361,10 +369,11 @@ public class ConnectionServiceFocusManager {
    }

    private void updateCurrentFocusCall() {
        CallFocus previousFocus = mCurrentFocusCall;
        mCurrentFocusCall = null;

        if (mCurrentFocus == null) {
            Log.d(this, "updateCurrentFocusCall: mCurrentFocus is null");
            Log.i(this, "updateCurrentFocusCall: mCurrentFocus is null");
            return;
        }

@@ -377,11 +386,16 @@ public class ConnectionServiceFocusManager {
        for (CallFocus call : calls) {
            if (PRIORITY_FOCUS_CALL_STATE.contains(call.getState())) {
                mCurrentFocusCall = call;
                if (previousFocus != call) {
                    mLocalLog.log(call.getId());
                }
                Log.i(this, "updateCurrentFocusCall %s", mCurrentFocusCall);
                return;
            }
        }

        if (previousFocus != null) {
            mLocalLog.log("<none>");
        }
        Log.i(this, "updateCurrentFocusCall = null");
    }

@@ -477,6 +491,11 @@ public class ConnectionServiceFocusManager {
        }
    }

    public void dump(IndentingPrintWriter pw) {
        pw.println("Call Focus History:");
        mLocalLog.dump(pw);
    }

    private final class FocusManagerHandler extends Handler {
        FocusManagerHandler(Looper looper) {
            super(looper);
+9 −0
Original line number Diff line number Diff line
@@ -259,6 +259,15 @@
          </intent-filter>
        </service>

        <service android:name="com.android.server.telecom.testapps.OtherSelfManagedConnectionService"
                 android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
                 android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
                 android:exported="true">
            <intent-filter>
                <action android:name="android.telecom.ConnectionService"/>
            </intent-filter>
        </service>

        <receiver android:exported="false"
             android:process="com.android.server.telecom.testapps.SelfMangingCallingApp"
             android:name="com.android.server.telecom.testapps.SelfManagedCallNotificationReceiver"/>
+6 −0
Original line number Diff line number Diff line
@@ -55,6 +55,12 @@
                android:layout_height="wrap_content"
                android:background="@color/test_call_b_color"
                android:text="2"/>
            <RadioButton
                android:id="@+id/useAcct3Button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@color/test_call_c_color"
                android:text="3"/>
        </RadioGroup>
        <TextView
            android:id="@+id/hasFocus"
+1 −0
Original line number Diff line number Diff line
@@ -17,4 +17,5 @@
<resources>
    <color name="test_call_a_color">#f2eebf</color>
    <color name="test_call_b_color">#afc5e6</color>
    <color name="test_call_c_color">#c5afe6</color>
</resources>
Loading