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

Commit 1b80ffd6 authored by Ihab Awad's avatar Ihab Awad Committed by Natiq Ahmed
Browse files

Telecom API updates (4/6)

Bug: 18292176

Conflicts:
	src/com/android/server/telecom/BluetoothPhoneService.java
	src/com/android/server/telecom/Call.java
	src/com/android/server/telecom/CallAudioManager.java
	src/com/android/server/telecom/CallsManager.java
	src/com/android/server/telecom/InCallController.java
	src/com/android/server/telecom/PhoneAccountRegistrar.java
	tests/src/com/android/server/telecom/testapps/TestVideoProvider.java

Conflicts:
	src/com/android/server/telecom/CallsManager.java

Change-Id: I28e6aa4fec20aadd77f9a861b0bb8e1e9828cffb
parent 550b03b3
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -34,9 +34,9 @@ import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.telecom.CallState;
import android.telecom.Connection;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.PhoneCapabilities;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -635,7 +635,7 @@ public final class BluetoothPhoneService extends Service {
                return true;
            }
        } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
            if (activeCall != null && activeCall.can(PhoneCapabilities.SWAP_CONFERENCE)) {
            if (activeCall != null && activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
                activeCall.swapConference();
                Log.i(TAG, "CDMA calls in conference swapped, updating headset");
                updateHeadsetWithCallState(true /* force */, activeCall);
@@ -648,13 +648,13 @@ public final class BluetoothPhoneService extends Service {
                // currently-held call.
                callsManager.unholdCall(heldCall);
                return true;
            } else if (activeCall != null && activeCall.can(PhoneCapabilities.HOLD)) {
            } else if (activeCall != null && activeCall.can(Connection.CAPABILITY_HOLD)) {
                callsManager.holdCall(activeCall);
                return true;
            }
        } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
            if (activeCall != null) {
                if (activeCall.can(PhoneCapabilities.MERGE_CONFERENCE)) {
                if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
                    activeCall.mergeConference();
                    return true;
                } else {
@@ -734,8 +734,8 @@ public final class BluetoothPhoneService extends Service {

            // Run some alternative states for Conference-level merge/swap support.
            // Basically, if call supports swapping or merging at the conference-level, then we need
            // to expose the calls as having distinct states (ACTIVE vs HOLD) or the functionality
            // won't show up on the bluetooth device.
            // to expose the calls as having distinct states (ACTIVE vs CAPABILITY_HOLD) or the
            // functionality won't show up on the bluetooth device.

            // Before doing any special logic, ensure that we are dealing with an ACTIVE call and
            // that the conference itself has a notion of the current "active" child call.
@@ -744,8 +744,8 @@ public final class BluetoothPhoneService extends Service {
                // Reevaluate state if we can MERGE or if we can SWAP without previously having
                // MERGED.
                boolean shouldReevaluateState =
                        conferenceCall.can(PhoneCapabilities.MERGE_CONFERENCE) ||
                        (conferenceCall.can(PhoneCapabilities.SWAP_CONFERENCE) &&
                        conferenceCall.can(Connection.CAPABILITY_MERGE_CONFERENCE) ||
                        (conferenceCall.can(Connection.CAPABILITY_SWAP_CONFERENCE) &&
                         !conferenceCall.wasConferencePreviouslyMerged());

                if (shouldReevaluateState) {
@@ -1006,11 +1006,11 @@ public final class BluetoothPhoneService extends Service {
            // to show "swap" and "merge" functionality.
            boolean ignoreHeldCallChange = false;
            if (activeCall != null && activeCall.isConference()) {
                if (activeCall.can(PhoneCapabilities.SWAP_CONFERENCE)) {
                if (activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
                    // Indicate that BT device should show SWAP command by indicating that there
                    // is a call on hold, but only if the conference wasn't previously merged.
                    numHeldCalls = activeCall.wasConferencePreviouslyMerged() ? 0 : 1;
                } else if (activeCall.can(PhoneCapabilities.MERGE_CONFERENCE)) {
                } else if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
                    numHeldCalls = 1;  // Merge is available, so expose via numHeldCalls.
                }

+18 −17
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.telecom.GatewayInfo;
import android.telecom.ParcelableConnection;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.PhoneCapabilities;
import android.telecom.Response;
import android.telecom.StatusHints;
import android.telecom.TelecomManager;
@@ -74,7 +73,7 @@ final class Call implements CreateConnectionResponse {
        void onFailedUnknownCall(Call call);
        void onRingbackRequested(Call call, boolean ringbackRequested);
        void onPostDialWait(Call call, String remaining);
        void onCallCapabilitiesChanged(Call call);
        void onConnectionCapabilitiesChanged(Call call);
        void onCallPropertiesChanged(Call call);
        void onParentChanged(Call call);
        void onChildrenChanged(Call call);
@@ -111,7 +110,7 @@ final class Call implements CreateConnectionResponse {
        @Override
        public void onPostDialWait(Call call, String remaining) {}
        @Override
        public void onCallCapabilitiesChanged(Call call) {}
        public void onConnectionCapabilitiesChanged(Call call) {}
        @Override
        public void onCallPropertiesChanged(Call call) {}
        @Override
@@ -279,7 +278,7 @@ final class Call implements CreateConnectionResponse {
    /** Whether direct-to-voicemail query is pending. */
    private boolean mDirectToVoicemailQueryPending;

    private int mCallCapabilities;
    private int mConnectionCapabilities;
    private int mCallProperties;

    private boolean mIsConference = false;
@@ -406,6 +405,7 @@ final class Call implements CreateConnectionResponse {
                getVideoState(),
                getChildCalls().size(),
                getParentCall() != null,
                Connection.capabilitiesToString(getConnectionCapabilities()),
                PhoneCapabilities.toString(getCallCapabilities()),
                mIsActiveSub,
                mTargetPhoneAccountHandle,
@@ -619,20 +619,21 @@ final class Call implements CreateConnectionResponse {
        mConnectTimeMillis = connectTimeMillis;
    }

    int getCallCapabilities() {
        return mCallCapabilities;
    int getConnectionCapabilities() {
        return mConnectionCapabilities;
    }

    void setCallCapabilities(int callCapabilities) {
        setCallCapabilities(callCapabilities, false /* forceUpdate */);
    void setConnectionCapabilities(int connectionCapabilities) {
        setConnectionCapabilities(connectionCapabilities, false /* forceUpdate */);
    }

    void setCallCapabilities(int callCapabilities, boolean forceUpdate) {
        Log.v(this, "setCallCapabilities: %s", PhoneCapabilities.toString(callCapabilities));
        if (forceUpdate || mCallCapabilities != callCapabilities) {
           mCallCapabilities = callCapabilities;
    void setConnectionCapabilities(int connectionCapabilities, boolean forceUpdate) {
        Log.v(this, "setConnectionCapabilities: %s", Connection.capabilitiesToString(
                connectionCapabilities));
        if (forceUpdate || mConnectionCapabilities != connectionCapabilities) {
           mConnectionCapabilities = connectionCapabilities;
            for (Listener l : mListeners) {
                l.onCallCapabilitiesChanged(this);
                l.onConnectionCapabilitiesChanged(this);
            }
        }
    }
@@ -754,7 +755,7 @@ final class Call implements CreateConnectionResponse {
        setHandle(connection.getHandle(), connection.getHandlePresentation());
        setCallerDisplayName(
                connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation());
        setCallCapabilities(connection.getCapabilities());
        setConnectionCapabilities(connection.getConnectionCapabilities());
        setCallProperties(connection.getProperties());
        setVideoProvider(connection.getVideoProvider());
        setVideoState(connection.getVideoState());
@@ -1038,7 +1039,7 @@ final class Call implements CreateConnectionResponse {
    void mergeConference() {
        if (mConnectionService == null) {
            Log.w(this, "merging conference calls without a connection service.");
        } else if (can(PhoneCapabilities.MERGE_CONFERENCE)) {
        } else if (can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
            mConnectionService.mergeConference(this);
            mWasConferencePreviouslyMerged = true;
        }
@@ -1047,7 +1048,7 @@ final class Call implements CreateConnectionResponse {
    void swapConference() {
        if (mConnectionService == null) {
            Log.w(this, "swapping conference calls without a connection service.");
        } else if (can(PhoneCapabilities.SWAP_CONFERENCE)) {
        } else if (can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
            mConnectionService.swapConference(this);
            switch (mChildCalls.size()) {
                case 1:
@@ -1105,7 +1106,7 @@ final class Call implements CreateConnectionResponse {
    }

    boolean can(int capability) {
        return (mCallCapabilities & capability) == capability;
        return (mConnectionCapabilities & capability) == capability;
    }

    private void addChildCall(Call call) {
+28 −24
Original line number Diff line number Diff line
@@ -71,7 +71,8 @@ final class CallAudioManager extends CallsManagerListenerBase
        if (hasFocus() && getForegroundCall() == call) {
            if (!call.isIncoming()) {
                // Unmute new outgoing call.
                setSystemAudioState(false, mAudioState.route, mAudioState.supportedRouteMask);
                setSystemAudioState(false, mAudioState.getRoute(),
                        mAudioState.getSupportedRouteMask());
            }
        }
    }
@@ -96,12 +97,12 @@ final class CallAudioManager extends CallsManagerListenerBase

    @Override
    public void onIncomingCallAnswered(Call call) {
        int route = mAudioState.route;
        int route = mAudioState.getRoute();

        // BT stack will connect audio upon receiving active call state.
        // We unmute the audio for the new incoming call.

        setSystemAudioState(false /* isMute */, route, mAudioState.supportedRouteMask);
        setSystemAudioState(false /* isMute */, route, mAudioState.getSupportedRouteMask());

        if (mContext == null) {
            Log.d(this, "Speedup Audio Path enhancement: Context is null");
@@ -158,11 +159,11 @@ final class CallAudioManager extends CallsManagerListenerBase
        } else {
            newRoute = AudioState.ROUTE_BLUETOOTH;
        }
        setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
        setSystemAudioState(mAudioState.isMuted(), newRoute, calculateSupportedRoutes());
    }

    void toggleMute() {
        mute(!mAudioState.isMuted);
        mute(!mAudioState.isMuted());
    }

    void mute(boolean shouldMute) {
@@ -178,8 +179,9 @@ final class CallAudioManager extends CallsManagerListenerBase
            Log.v(this, "ignoring mute for emergency call");
        }

        if (mAudioState.isMuted != shouldMute) {
            setSystemAudioState(shouldMute, mAudioState.route, mAudioState.supportedRouteMask);
        if (mAudioState.isMuted() != shouldMute) {
            setSystemAudioState(shouldMute, mAudioState.getRoute(),
                    mAudioState.getSupportedRouteMask());
        }
    }

@@ -197,19 +199,20 @@ final class CallAudioManager extends CallsManagerListenerBase
        Log.v(this, "setAudioRoute, route: %s", AudioState.audioRouteToString(route));

        // Change ROUTE_WIRED_OR_EARPIECE to a single entry.
        int newRoute = selectWiredOrEarpiece(route, mAudioState.supportedRouteMask);
        int newRoute = selectWiredOrEarpiece(route, mAudioState.getSupportedRouteMask());

        // If route is unsupported, do nothing.
        if ((mAudioState.supportedRouteMask | newRoute) == 0) {
        if ((mAudioState.getSupportedRouteMask() | newRoute) == 0) {
            Log.wtf(this, "Asking to set to a route that is unsupported: %d", newRoute);
            return;
        }

        if (mAudioState.route != newRoute) {
        if (mAudioState.getRoute() != newRoute) {
            // Remember the new speaker state so it can be restored when the user plugs and unplugs
            // a headset.
            mWasSpeakerOn = newRoute == AudioState.ROUTE_SPEAKER;
            setSystemAudioState(mAudioState.isMuted, newRoute, mAudioState.supportedRouteMask);
            setSystemAudioState(mAudioState.isMuted(), newRoute,
                    mAudioState.getSupportedRouteMask());
        }
    }

@@ -248,16 +251,16 @@ final class CallAudioManager extends CallsManagerListenerBase
        }

        int supportedRoutes = calculateSupportedRoutes();
        int newRoute = mAudioState.route;
        int newRoute = mAudioState.getRoute();
        if (bluetoothManager.isBluetoothAudioConnectedOrPending()) {
            newRoute = AudioState.ROUTE_BLUETOOTH;
        } else if (mAudioState.route == AudioState.ROUTE_BLUETOOTH) {
        } else if (mAudioState.getRoute() == AudioState.ROUTE_BLUETOOTH) {
            newRoute = selectWiredOrEarpiece(AudioState.ROUTE_WIRED_OR_EARPIECE, supportedRoutes);
            // Do not switch to speaker when bluetooth disconnects.
            mWasSpeakerOn = false;
        }

        setSystemAudioState(mAudioState.isMuted, newRoute, supportedRoutes);
        setSystemAudioState(mAudioState.isMuted(), newRoute, supportedRoutes);
    }

    boolean isBluetoothAudioOn() {
@@ -270,8 +273,8 @@ final class CallAudioManager extends CallsManagerListenerBase

    private void saveAudioState(AudioState audioState) {
        mAudioState = audioState;
        mStatusBarNotifier.notifyMute(mAudioState.isMuted);
        mStatusBarNotifier.notifySpeakerphone(mAudioState.route == AudioState.ROUTE_SPEAKER);
        mStatusBarNotifier.notifyMute(mAudioState.isMuted());
        mStatusBarNotifier.notifySpeakerphone(mAudioState.getRoute() == AudioState.ROUTE_SPEAKER);
    }

    private void onCallUpdated(Call call) {
@@ -307,20 +310,20 @@ final class CallAudioManager extends CallsManagerListenerBase
        Log.i(this, "changing audio state from %s to %s", oldAudioState, mAudioState);

        // Mute.
        if (mAudioState.isMuted != mAudioManager.isMicrophoneMute()) {
            Log.i(this, "changing microphone mute state to: %b", mAudioState.isMuted);
            mAudioManager.setMicrophoneMute(mAudioState.isMuted);
        if (mAudioState.isMuted() != mAudioManager.isMicrophoneMute()) {
            Log.i(this, "changing microphone mute state to: %b", mAudioState.isMuted());
            mAudioManager.setMicrophoneMute(mAudioState.isMuted());
        }

        // Audio route.
        if (mAudioState.route == AudioState.ROUTE_BLUETOOTH) {
        if (mAudioState.getRoute() == AudioState.ROUTE_BLUETOOTH) {
            turnOnSpeaker(false);
            turnOnBluetooth(true);
        } else if (mAudioState.route == AudioState.ROUTE_SPEAKER) {
        } else if (mAudioState.getRoute() == AudioState.ROUTE_SPEAKER) {
            turnOnBluetooth(false);
            turnOnSpeaker(true);
        } else if (mAudioState.route == AudioState.ROUTE_EARPIECE ||
                mAudioState.route == AudioState.ROUTE_WIRED_HEADSET) {
        } else if (mAudioState.getRoute() == AudioState.ROUTE_EARPIECE ||
                mAudioState.getRoute() == AudioState.ROUTE_WIRED_HEADSET) {
            turnOnBluetooth(false);
            turnOnSpeaker(false);
        }
@@ -493,7 +496,8 @@ final class CallAudioManager extends CallsManagerListenerBase
        AudioState audioState = getInitialAudioState(call);
        Log.v(this, "setInitialAudioState %s, %s", audioState, call);
        setSystemAudioState(
                force, audioState.isMuted, audioState.route, audioState.supportedRouteMask);
                force, audioState.isMuted(), audioState.getRoute(),
                audioState.getSupportedRouteMask());
    }

    private void updateAudioForForegroundCall() {
+6 −9
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@
package com.android.server.telecom;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -29,6 +26,7 @@ import android.os.SystemProperties;
import android.provider.CallLog.Calls;
import android.telecom.AudioState;
import android.telecom.CallState;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
import android.telecom.GatewayInfo;
import android.telecom.Conference;
@@ -36,7 +34,6 @@ import android.telecom.ParcelableConference;
import android.telecom.ParcelableConnection;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.PhoneCapabilities;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;

@@ -662,7 +659,7 @@ public final class CallsManager extends Call.ListenerBase {
            if (activeCall != null && activeCall != call &&
                    (activeCall.isActive() ||
                    activeCall.getState() == CallState.DIALING)) {
                if (0 == (activeCall.getCallCapabilities() & PhoneCapabilities.HOLD)) {
                if (0 == (activeCall.getConnectionCapabilities() & Connection.HOLD)) {
                    // This call does not support hold.  If it is from a different connection
                    // service, then disconnect it, otherwise allow the connection service to
                    // figure out the right states.
@@ -1284,7 +1281,7 @@ public final class CallsManager extends Call.ListenerBase {
        if (oldConnectTime == 0 && call.getState() == CallState.ACTIVE) {
            call.setConnectTimeMillis(System.currentTimeMillis());
        }
        call.setCallCapabilities(parcelableConference.getCapabilities());
        call.setConnectionCapabilities(parcelableConference.getConnectionCapabilities());
        call.setVideoState(parcelableConference.getVideoState());
        call.setVideoProvider(parcelableConference.getVideoProvider());

@@ -1659,7 +1656,7 @@ public final class CallsManager extends Call.ListenerBase {
            }

            // Try to hold the live call before attempting the new outgoing call.
            if (liveCall.can(PhoneCapabilities.HOLD)) {
            if (liveCall.can(Connection.CAPABILITY_HOLD)) {
                liveCall.hold();
                return true;
            }
@@ -1740,7 +1737,7 @@ public final class CallsManager extends Call.ListenerBase {
        } else {
            call.setConnectTimeMillis(System.currentTimeMillis());
        }
        call.setCallCapabilities(connection.getCapabilities());
        call.setConnectionCapabilities(connection.getConnectionCapabilities());
        call.setCallerDisplayName(connection.getCallerDisplayName(),
                connection.getCallerDisplayNamePresentation());

+7 −7
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
    private static final int MSG_SET_DISCONNECTED = 5;
    private static final int MSG_SET_ON_HOLD = 6;
    private static final int MSG_SET_RINGBACK_REQUESTED = 7;
    private static final int MSG_SET_CALL_CAPABILITIES = 8;
    private static final int MSG_SET_CONNECTION_CAPABILITIES = 8;
    private static final int MSG_SET_IS_CONFERENCED = 9;
    private static final int MSG_ADD_CONFERENCE_CALL = 10;
    private static final int MSG_REMOVE_CALL = 11;
@@ -176,13 +176,13 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
                    }
                    break;
                }
                case MSG_SET_CALL_CAPABILITIES: {
                case MSG_SET_CONNECTION_CAPABILITIES: {
                    call = mCallIdMapper.getCall(msg.obj);
                    if (call != null) {
                        call.setCallCapabilities(msg.arg1);
                        call.setConnectionCapabilities(msg.arg1);
                    } else {
                        //Log.w(ConnectionServiceWrapper.this,
                        //      "setCallCapabilities, unknown call id: %s", msg.obj);
                        //      "setConnectionCapabilities, unknown call id: %s", msg.obj);
                    }
                    break;
                }
@@ -520,10 +520,10 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
        }

        @Override
        public void setCallCapabilities(String callId, int callCapabilities) {
            logIncoming("setCallCapabilities %s %d", callId, callCapabilities);
        public void setConnectionCapabilities(String callId, int connectionCapabilities) {
            logIncoming("setConnectionCapabilities %s %d", callId, connectionCapabilities);
            if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper.isValidConferenceId(callId)) {
                mHandler.obtainMessage(MSG_SET_CALL_CAPABILITIES, callCapabilities, 0, callId)
                mHandler.obtainMessage(MSG_SET_CONNECTION_CAPABILITIES, connectionCapabilities, 0, callId)
                        .sendToTarget();
            } else {
                Log.w(this, "ID not valid for setCallCapabilities");
Loading