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

Commit 18bc8a5b authored by Grace Jia's avatar Grace Jia
Browse files

Bind self-managed calls to InCallService that support these kind of

calls.

Bug: 161144815
Test: TelecomUnitTest, manually test with test apps.
Change-Id: Ifa3566d5e681b5ab41fb3123a25fc841fa96fe60
Merged-In: Ifa3566d5e681b5ab41fb3123a25fc841fa96fe60
parent 53e4d9d3
Loading
Loading
Loading
Loading
+32 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import android.telecom.Connection;
import android.telecom.ConnectionService;
import android.telecom.ConnectionService;
import android.telecom.DisconnectCause;
import android.telecom.DisconnectCause;
import android.telecom.GatewayInfo;
import android.telecom.GatewayInfo;
import android.telecom.InCallService;
import android.telecom.Log;
import android.telecom.Log;
import android.telecom.Logging.EventManager;
import android.telecom.Logging.EventManager;
import android.telecom.ParcelableConference;
import android.telecom.ParcelableConference;
@@ -58,6 +59,7 @@ import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.widget.Toast;
import android.widget.Toast;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -509,6 +511,15 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
     */
     */
    private boolean mIsSelfManaged = false;
    private boolean mIsSelfManaged = false;


    /**
     * Indicates whether the {@link PhoneAccount} associated with an self-managed call want to
     * expose the call to an {@link android.telecom.InCallService} which declares the metadata
     * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS},
     * For calls that {@link #mIsSelfManaged} is {@code false}, this value should be {@code false}
     * as well.
     */
    private boolean mVisibleToInCallService = false;

    /**
    /**
     * Indicates whether the {@link PhoneAccount} associated with this call supports video calling.
     * Indicates whether the {@link PhoneAccount} associated with this call supports video calling.
     * {@code True} if the phone account supports video calling, {@code false} otherwise.
     * {@code True} if the phone account supports video calling, {@code false} otherwise.
@@ -1628,6 +1639,14 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        setConnectionProperties(getConnectionProperties());
        setConnectionProperties(getConnectionProperties());
    }
    }


    public boolean visibleToInCallService() {
        return mVisibleToInCallService;
    }

    public void setVisibleToInCallService(boolean visibleToInCallService) {
        mVisibleToInCallService = visibleToInCallService;
    }

    public void markFinishedHandoverStateAndCleanup(int handoverState) {
    public void markFinishedHandoverStateAndCleanup(int handoverState) {
        if (mHandoverSourceCall != null) {
        if (mHandoverSourceCall != null) {
            mHandoverSourceCall.setHandoverState(handoverState);
            mHandoverSourceCall.setHandoverState(handoverState);
@@ -3945,4 +3964,17 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
    public void setCallScreeningComponentName(String callScreeningComponentName) {
    public void setCallScreeningComponentName(String callScreeningComponentName) {
        mCallScreeningComponentName = callScreeningComponentName;
        mCallScreeningComponentName = callScreeningComponentName;
    }
    }

    public void maybeOnInCallServiceTrackingChanged(boolean isTracking, boolean hasUi) {
        if (mConnectionService == null) {
            Log.w(this, "maybeOnInCallServiceTrackingChanged() request on a call"
                    + " without a connection service.");
        } else {
            if (hasUi) {
                mConnectionService.onUsingAlternativeUi(this, isTracking);
            } else if (isTracking) {
                mConnectionService.onTrackedByNonUiService(this, isTracking);
            }
        }
    }
}
}
+11 −1
Original line number Original line Diff line number Diff line
@@ -1237,10 +1237,14 @@ public class CallsManager extends Call.ListenerBase
        PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
        PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
                phoneAccountHandle);
                phoneAccountHandle);
        if (phoneAccount != null) {
        if (phoneAccount != null) {
            Bundle phoneAccountExtras = phoneAccount.getExtras();
            call.setIsSelfManaged(phoneAccount.isSelfManaged());
            call.setIsSelfManaged(phoneAccount.isSelfManaged());
            if (call.isSelfManaged()) {
            if (call.isSelfManaged()) {
                // Self managed calls will always be voip audio mode.
                // Self managed calls will always be voip audio mode.
                call.setIsVoipAudioMode(true);
                call.setIsVoipAudioMode(true);
                call.setVisibleToInCallService(phoneAccountExtras != null
                        && phoneAccountExtras.getBoolean(
                        PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, false));
            } else {
            } else {
                // Incoming call is managed, the active call is self-managed and can't be held.
                // Incoming call is managed, the active call is self-managed and can't be held.
                // We need to set extras on it to indicate whether answering will cause a 
                // We need to set extras on it to indicate whether answering will cause a 
@@ -1259,7 +1263,6 @@ public class CallsManager extends Call.ListenerBase
                }
                }
            }
            }


            Bundle phoneAccountExtras = phoneAccount.getExtras();
            if (phoneAccountExtras != null
            if (phoneAccountExtras != null
                    && phoneAccountExtras.getBoolean(
                    && phoneAccountExtras.getBoolean(
                            PhoneAccount.EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE)) {
                            PhoneAccount.EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE)) {
@@ -1474,6 +1477,7 @@ public class CallsManager extends Call.ListenerBase


        PhoneAccount account =
        PhoneAccount account =
                mPhoneAccountRegistrar.getPhoneAccount(requestedAccountHandle, initiatingUser);
                mPhoneAccountRegistrar.getPhoneAccount(requestedAccountHandle, initiatingUser);
        Bundle phoneAccountExtra = account != null ? account.getExtras() : null;
        boolean isSelfManaged = account != null && account.isSelfManaged();
        boolean isSelfManaged = account != null && account.isSelfManaged();


        // Create a call with original handle. The handle may be changed when the call is attached
        // Create a call with original handle. The handle may be changed when the call is attached
@@ -1504,6 +1508,9 @@ public class CallsManager extends Call.ListenerBase
            if (isSelfManaged) {
            if (isSelfManaged) {
                // Self-managed calls will ALWAYS use voip audio mode.
                // Self-managed calls will ALWAYS use voip audio mode.
                call.setIsVoipAudioMode(true);
                call.setIsVoipAudioMode(true);
                call.setVisibleToInCallService(phoneAccountExtra != null
                        && phoneAccountExtra.getBoolean(
                                PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, false));
            }
            }
            call.setInitiatingUser(initiatingUser);
            call.setInitiatingUser(initiatingUser);
            isReusedCall = false;
            isReusedCall = false;
@@ -4740,6 +4747,9 @@ public class CallsManager extends Call.ListenerBase
        extras.putLong(TelecomManager.EXTRA_CALL_TELECOM_ROUTING_START_TIME_MILLIS,
        extras.putLong(TelecomManager.EXTRA_CALL_TELECOM_ROUTING_START_TIME_MILLIS,
              SystemClock.elapsedRealtime());
              SystemClock.elapsedRealtime());


        if (call.visibleToInCallService()) {
            extras.putBoolean(PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
        }
        call.setIntentExtras(extras);
        call.setIntentExtras(extras);
    }
    }


+28 −0
Original line number Original line Diff line number Diff line
@@ -1573,6 +1573,34 @@ public class ConnectionServiceWrapper extends ServiceBinder implements
        }
        }
    }
    }


    /** @see IConnectionService#onUsingAlternativeUi(String, boolean, Session.Info) */
    @VisibleForTesting
    public void onUsingAlternativeUi(Call activeCall, boolean isUsingAlternativeUi) {
        final String callId = mCallIdMapper.getCallId(activeCall);
        if (callId != null && isServiceValid("onUsingAlternativeUi")) {
            try {
                logOutgoing("onUsingAlternativeUi %s", isUsingAlternativeUi);
                mServiceInterface.onUsingAlternativeUi(callId, isUsingAlternativeUi,
                        Log.getExternalSession(TELECOM_ABBREVIATION));
            } catch (RemoteException e) {
            }
        }
    }

    /** @see IConnectionService#onTrackedByNonUiService(String, boolean, Session.Info) */
    @VisibleForTesting
    public void onTrackedByNonUiService(Call activeCall, boolean isTracked) {
        final String callId = mCallIdMapper.getCallId(activeCall);
        if (callId != null && isServiceValid("onTrackedByNonUiService")) {
            try {
                logOutgoing("onTrackedByNonUiService %s", isTracked);
                mServiceInterface.onTrackedByNonUiService(callId, isTracked,
                        Log.getExternalSession(TELECOM_ABBREVIATION));
            } catch (RemoteException e) {
            }
        }
    }

    /** @see IConnectionService#disconnect(String, Session.Info) */
    /** @see IConnectionService#disconnect(String, Session.Info) */
    void disconnect(Call call) {
    void disconnect(Call call) {
        final String callId = mCallIdMapper.getCallId(call);
        final String callId = mCallIdMapper.getCallId(call);
+70 −32
Original line number Original line Diff line number Diff line
@@ -113,7 +113,7 @@ public class InCallController extends CallsManagerListenerBase {
        public Call mCall;
        public Call mCall;
    }
    }


    private class InCallServiceInfo {
    public static class InCallServiceInfo {
        private final ComponentName mComponentName;
        private final ComponentName mComponentName;
        private boolean mIsExternalCallsSupported;
        private boolean mIsExternalCallsSupported;
        private boolean mIsSelfManagedCallsSupported;
        private boolean mIsSelfManagedCallsSupported;
@@ -279,7 +279,8 @@ public class InCallController extends CallsManagerListenerBase {
            }
            }


            if (call != null && call.isSelfManaged() &&
            if (call != null && call.isSelfManaged() &&
                    !mInCallServiceInfo.isSelfManagedCallsSupported()) {
                    (!mInCallServiceInfo.isSelfManagedCallsSupported()
                            || !call.visibleToInCallService())) {
                Log.i(this, "Skipping binding to %s - doesn't support self-mgd calls",
                Log.i(this, "Skipping binding to %s - doesn't support self-mgd calls",
                        mInCallServiceInfo);
                        mInCallServiceInfo);
                mIsConnected = false;
                mIsConnected = false;
@@ -342,6 +343,7 @@ public class InCallController extends CallsManagerListenerBase {
                            mInCallServiceInfo.getType(),
                            mInCallServiceInfo.getType(),
                            mInCallServiceInfo.getDisconnectTime()
                            mInCallServiceInfo.getDisconnectTime()
                                    - mInCallServiceInfo.getBindingStartTime(), mIsNullBinding);
                                    - mInCallServiceInfo.getBindingStartTime(), mIsNullBinding);
                    updateCallTracking(mCall, mInCallServiceInfo, false /* isAdd */);
                }
                }


                InCallController.this.onDisconnected(mInCallServiceInfo);
                InCallController.this.onDisconnected(mInCallServiceInfo);
@@ -748,6 +750,10 @@ public class InCallController extends CallsManagerListenerBase {
                newConnection.connect(callToConnectWith);
                newConnection.connect(callToConnectWith);
            }
            }
        }
        }

        public List<InCallServiceBindingConnection> getSubConnections() {
            return mSubConnections;
        }
    }
    }


    private final Call.Listener mCallListener = new Call.ListenerBase() {
    private final Call.Listener mCallListener = new Call.ListenerBase() {
@@ -915,12 +921,12 @@ public class InCallController extends CallsManagerListenerBase {
        @Override
        @Override
        public void onPackageUninstalled(String packageName) {
        public void onPackageUninstalled(String packageName) {
            mCarModeTracker.forceExitCarMode(packageName);
            mCarModeTracker.forceExitCarMode(packageName);
            updateCarModeForSwitchingConnection();
            updateCarModeForConnections();
        }
        }
    };
    };


    private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
    private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
    private static final int IN_CALL_SERVICE_TYPE_DIALER_UI = 1;
    private static final int IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI = 1;
    private static final int IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
    private static final int IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
    private static final int IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
    private static final int IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
    private static final int IN_CALL_SERVICE_TYPE_NON_UI = 4;
    private static final int IN_CALL_SERVICE_TYPE_NON_UI = 4;
@@ -967,10 +973,9 @@ public class InCallController extends CallsManagerListenerBase {
    private boolean mIsCallUsingMicrophone = false;
    private boolean mIsCallUsingMicrophone = false;


    public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager,
    public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager,
            SystemStateHelper systemStateHelper,
            SystemStateHelper systemStateHelper, DefaultDialerCache defaultDialerCache,
            DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
            Timeouts.Adapter timeoutsAdapter, EmergencyCallHelper emergencyCallHelper,
            EmergencyCallHelper emergencyCallHelper, CarModeTracker carModeTracker,
            CarModeTracker carModeTracker, ClockProxy clockProxy) {
            ClockProxy clockProxy) {
        mContext = context;
        mContext = context;
        mAppOpsManager = context.getSystemService(AppOpsManager.class);
        mAppOpsManager = context.getSystemService(AppOpsManager.class);
        mLock = lock;
        mLock = lock;
@@ -1013,12 +1018,16 @@ public class InCallController extends CallsManagerListenerBase {
                    continue;
                    continue;
                }
                }


                if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
                if (call.isSelfManaged() && (!call.visibleToInCallService()
                        || !info.isSelfManagedCallsSupported())) {
                    continue;
                    continue;
                }
                }


                // Only send the RTT call if it's a UI in-call service
                // Only send the RTT call if it's a UI in-call service
                boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
                boolean includeRttCall = false;
                if (mInCallServiceConnection != null) {
                    includeRttCall = info.equals(mInCallServiceConnection.getInfo());
                }


                componentsUpdated.add(info.getComponentName());
                componentsUpdated.add(info.getComponentName());
                IInCallService inCallService = entry.getValue();
                IInCallService inCallService = entry.getValue();
@@ -1030,6 +1039,7 @@ public class InCallController extends CallsManagerListenerBase {
                        info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
                        info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
                try {
                try {
                    inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
                    inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
                    updateCallTracking(call, info, true /* isAdd */);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
@@ -1079,7 +1089,8 @@ public class InCallController extends CallsManagerListenerBase {
                    continue;
                    continue;
                }
                }


                if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
                if (call.isSelfManaged() && !call.visibleToInCallService()
                        && !info.isSelfManagedCallsSupported()) {
                    continue;
                    continue;
                }
                }


@@ -1096,6 +1107,7 @@ public class InCallController extends CallsManagerListenerBase {
                        info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
                        info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
                try {
                try {
                    inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
                    inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
                    updateCallTracking(call, info, true /* isAdd */);
                } catch (RemoteException ignored) {
                } catch (RemoteException ignored) {
                }
                }
            }
            }
@@ -1356,7 +1368,8 @@ public class InCallController extends CallsManagerListenerBase {


    /**
    /**
     * Binds to all the UI-providing InCallService as well as system-implemented non-UI
     * Binds to all the UI-providing InCallService as well as system-implemented non-UI
     * InCallServices. Method-invoker must check {@link #isBoundAndConnectedToServices()} before invoking.
     * InCallServices. Method-invoker must check {@link #isBoundAndConnectedToServices()}
     * before invoking.
     *
     *
     * @param call The newly added call that triggered the binding to the in-call services.
     * @param call The newly added call that triggered the binding to the in-call services.
     */
     */
@@ -1409,7 +1422,7 @@ public class InCallController extends CallsManagerListenerBase {
        }
        }
    }
    }


    private void connectToNonUiInCallServices(Call call) {
    private void updateNonUiInCallServices() {
        List<InCallServiceInfo> nonUIInCallComponents =
        List<InCallServiceInfo> nonUIInCallComponents =
                getInCallServiceComponents(IN_CALL_SERVICE_TYPE_NON_UI);
                getInCallServiceComponents(IN_CALL_SERVICE_TYPE_NON_UI);
        List<InCallServiceBindingConnection> nonUIInCalls = new LinkedList<>();
        List<InCallServiceBindingConnection> nonUIInCalls = new LinkedList<>();
@@ -1427,7 +1440,14 @@ public class InCallController extends CallsManagerListenerBase {
                }
                }
            }
            }
        }
        }
        mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
        mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(
                nonUIInCalls);
    }

    private void connectToNonUiInCallServices(Call call) {
        if (mNonUIInCallServiceConnections == null) {
            updateNonUiInCallServices();
        }
        mNonUIInCallServiceConnections.connect(call);
        mNonUIInCallServiceConnections.connect(call);


        IntentFilter packageChangedFilter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
        IntentFilter packageChangedFilter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
@@ -1444,7 +1464,7 @@ public class InCallController extends CallsManagerListenerBase {
        InCallServiceInfo defaultDialerComponent =
        InCallServiceInfo defaultDialerComponent =
                (systemPackageName != null && systemPackageName.equals(packageName))
                (systemPackageName != null && systemPackageName.equals(packageName))
                ? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI)
                ? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI)
                : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_DIALER_UI);
                : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI);
        /* TODO: in Android 12 re-enable this an InCallService is required by the dialer role.
        /* TODO: in Android 12 re-enable this an InCallService is required by the dialer role.
            if (packageName != null && defaultDialerComponent == null) {
            if (packageName != null && defaultDialerComponent == null) {
                // The in call service of default phone app is disabled, send notification.
                // The in call service of default phone app is disabled, send notification.
@@ -1494,7 +1514,6 @@ public class InCallController extends CallsManagerListenerBase {


    private List<InCallServiceInfo> getInCallServiceComponents(String packageName,
    private List<InCallServiceInfo> getInCallServiceComponents(String packageName,
            ComponentName componentName, int requestedType) {
            ComponentName componentName, int requestedType) {

        List<InCallServiceInfo> retval = new LinkedList<>();
        List<InCallServiceInfo> retval = new LinkedList<>();


        Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
        Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
@@ -1526,13 +1545,19 @@ public class InCallController extends CallsManagerListenerBase {
                if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
                if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
                    mKnownNonUiInCallServices.add(foundComponentName);
                    mKnownNonUiInCallServices.add(foundComponentName);
                }
                }
                if (serviceInfo.enabled && (requestedType == 0 || requestedType == currentType)) {

                    retval.add(new InCallServiceInfo(foundComponentName,
                boolean isRequestedType;
                            isExternalCallsSupported, isSelfManageCallsSupported, requestedType));
                if (requestedType == IN_CALL_SERVICE_TYPE_INVALID) {
                    isRequestedType = true;
                } else {
                    isRequestedType = requestedType == currentType;
                }
                if (serviceInfo.enabled && isRequestedType) {
                    retval.add(new InCallServiceInfo(foundComponentName, isExternalCallsSupported,
                            isSelfManageCallsSupported, requestedType));
                }
                }
            }
            }
        }
        }

        return retval;
        return retval;
    }
    }


@@ -1598,7 +1623,7 @@ public class InCallController extends CallsManagerListenerBase {
                mDefaultDialerCache.getDefaultDialerApplication(
                mDefaultDialerCache.getDefaultDialerApplication(
                    mCallsManager.getCurrentUserHandle().getIdentifier()));
                    mCallsManager.getCurrentUserHandle().getIdentifier()));
        if (isDefaultDialerPackage && isUIService) {
        if (isDefaultDialerPackage && isUIService) {
            return IN_CALL_SERVICE_TYPE_DIALER_UI;
            return IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
        }
        }


        // Also allow any in-call service that has the control-experience permission (to ensure
        // Also allow any in-call service that has the control-experience permission (to ensure
@@ -1637,7 +1662,7 @@ public class InCallController extends CallsManagerListenerBase {


        if (info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
        if (info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
                || info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
                || info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
                || info.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
                || info.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
            trackCallingUserInterfaceStarted(info);
            trackCallingUserInterfaceStarted(info);
        }
        }
        IInCallService inCallService = IInCallService.Stub.asInterface(service);
        IInCallService inCallService = IInCallService.Stub.asInterface(service);
@@ -1663,13 +1688,17 @@ public class InCallController extends CallsManagerListenerBase {
        int numCallsSent = 0;
        int numCallsSent = 0;
        for (Call call : calls) {
        for (Call call : calls) {
            try {
            try {
                if ((call.isSelfManaged() && !info.isSelfManagedCallsSupported()) ||
                if ((call.isSelfManaged() && (!info.isSelfManagedCallsSupported()
                        || !call.visibleToInCallService())) ||
                        (call.isExternalCall() && !info.isExternalCallsSupported())) {
                        (call.isExternalCall() && !info.isExternalCallsSupported())) {
                    continue;
                    continue;
                }
                }


                // Only send the RTT call if it's a UI in-call service
                // Only send the RTT call if it's a UI in-call service
                boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
                boolean includeRttCall = false;
                if (mInCallServiceConnection != null) {
                    includeRttCall = info.equals(mInCallServiceConnection.getInfo());
                }


                // Track the call if we don't already know about it.
                // Track the call if we don't already know about it.
                addCall(call);
                addCall(call);
@@ -1683,6 +1712,7 @@ public class InCallController extends CallsManagerListenerBase {
                        info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
                        info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
                        info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
                        info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
                inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
                inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
                updateCallTracking(call, info, true /* isAdd */);
            } catch (RemoteException ignored) {
            } catch (RemoteException ignored) {
            }
            }
        }
        }
@@ -1709,7 +1739,7 @@ public class InCallController extends CallsManagerListenerBase {
        Log.i(this, "onDisconnected from %s", disconnectedInfo.getComponentName());
        Log.i(this, "onDisconnected from %s", disconnectedInfo.getComponentName());
        if (disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
        if (disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
                || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
                || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
                || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
                || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
            trackCallingUserInterfaceStopped(disconnectedInfo);
            trackCallingUserInterfaceStopped(disconnectedInfo);
        }
        }
        mInCallServices.remove(disconnectedInfo);
        mInCallServices.remove(disconnectedInfo);
@@ -1743,7 +1773,8 @@ public class InCallController extends CallsManagerListenerBase {
                    continue;
                    continue;
                }
                }


                if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
                if (call.isSelfManaged() && (!call.visibleToInCallService()
                        || !info.isSelfManagedCallsSupported())) {
                    continue;
                    continue;
                }
                }


@@ -1824,7 +1855,7 @@ public class InCallController extends CallsManagerListenerBase {
     */
     */
    private ComponentName getConnectedUi() {
    private ComponentName getConnectedUi() {
        InCallServiceInfo connectedUi = mInCallServices.keySet().stream().filter(
        InCallServiceInfo connectedUi = mInCallServices.keySet().stream().filter(
                i -> i.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI
                i -> i.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI
                        || i.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI)
                        || i.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI)
                .findAny()
                .findAny()
                .orElse(null);
                .orElse(null);
@@ -1942,13 +1973,13 @@ public class InCallController extends CallsManagerListenerBase {
            mCarModeTracker.handleExitCarMode(priority, packageName);
            mCarModeTracker.handleExitCarMode(priority, packageName);
        }
        }


        updateCarModeForSwitchingConnection();
        updateCarModeForConnections();
    }
    }


    public void updateCarModeForSwitchingConnection() {
    public void updateCarModeForConnections() {
        if (mInCallServiceConnection != null) {
        Log.i(this, "updateCarModeForConnections: car mode apps: %s",
            Log.i(this, "updateCarModeForSwitchingConnection: car mode apps: %s",
                mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
                mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
        if (mInCallServiceConnection != null) {
            if (shouldUseCarModeUI()) {
            if (shouldUseCarModeUI()) {
                mInCallServiceConnection.changeCarModeApp(
                mInCallServiceConnection.changeCarModeApp(
                        mCarModeTracker.getCurrentCarModePackage());
                        mCarModeTracker.getCurrentCarModePackage());
@@ -2058,4 +2089,11 @@ public class InCallController extends CallsManagerListenerBase {
        notificationManager.notify(NOTIFICATION_TAG, IN_CALL_SERVICE_NOTIFICATION_ID,
        notificationManager.notify(NOTIFICATION_TAG, IN_CALL_SERVICE_NOTIFICATION_ID,
                builder.build());
                builder.build());
    }
    }

    private void updateCallTracking(Call call, InCallServiceInfo info, boolean isAdd) {
        int type = info.getType();
        boolean hasUi = type == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
                || type == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
        call.maybeOnInCallServiceTrackingChanged(isAdd, hasUi);
    }
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,8 @@
             android:exported="true">
             android:exported="true">
            <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI"
            <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI"
                 android:value="true"/>
                 android:value="true"/>
            <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
                 android:value="true" />
            <intent-filter>
            <intent-filter>
                <action android:name="android.telecom.InCallService"/>
                <action android:name="android.telecom.InCallService"/>
            </intent-filter>
            </intent-filter>
Loading