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

Commit 07bc5ee8 authored by Ihab Awad's avatar Ihab Awad
Browse files

Telecom API updates (4/6)

Bug: 18292176

Change-Id: I28e6aa4fec20aadd77f9a861b0bb8e1e9828cffb
parent ebdb7803
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ 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.PhoneCapabilities;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -498,7 +498,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();
                return true;
            } else if (ringingCall != null) {
@@ -509,13 +509,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 {
@@ -587,8 +587,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.
@@ -597,8 +597,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) {
@@ -698,11 +698,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 −18
Original line number Diff line number Diff line
@@ -31,7 +31,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 onParentChanged(Call call);
        void onChildrenChanged(Call call);
        void onCannedSmsResponsesLoaded(Call call);
@@ -110,7 +109,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 onParentChanged(Call call) {}
        @Override
@@ -277,7 +276,7 @@ final class Call implements CreateConnectionResponse {
    /** Whether direct-to-voicemail query is pending. */
    private boolean mDirectToVoicemailQueryPending;

    private int mCallCapabilities;
    private int mConnectionCapabilities;

    private boolean mIsConference = false;

@@ -370,7 +369,7 @@ final class Call implements CreateConnectionResponse {
                getVideoState(),
                getChildCalls().size(),
                getParentCall() != null,
                PhoneCapabilities.toString(getCallCapabilities()));
                Connection.capabilitiesToString(getConnectionCapabilities()));
    }

    int getState() {
@@ -607,20 +606,21 @@ final class Call implements CreateConnectionResponse {
        return mConnectTimeMillis;
    }

    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);
            }
        }
    }
@@ -727,7 +727,7 @@ final class Call implements CreateConnectionResponse {
        setHandle(connection.getHandle(), connection.getHandlePresentation());
        setCallerDisplayName(
                connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation());
        setCallCapabilities(connection.getCapabilities());
        setConnectionCapabilities(connection.getConnectionCapabilities());
        setVideoProvider(connection.getVideoProvider());
        setVideoState(connection.getVideoState());
        setRingbackRequested(connection.isRingbackRequested());
@@ -993,7 +993,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;
        }
@@ -1002,7 +1002,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:
@@ -1060,7 +1060,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
@@ -68,7 +68,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());
            }
        }
    }
@@ -93,7 +94,7 @@ final class CallAudioManager extends CallsManagerListenerBase

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

        // We do two things:
        // (1) If this is the first call, then we can to turn on bluetooth if available.
@@ -104,7 +105,7 @@ final class CallAudioManager extends CallsManagerListenerBase
            route = AudioState.ROUTE_BLUETOOTH;
        }

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

    @Override
@@ -140,11 +141,11 @@ final class CallAudioManager extends CallsManagerListenerBase
                newRoute = AudioState.ROUTE_SPEAKER;
            }
        }
        setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
        setSystemAudioState(mAudioState.isMuted(), newRoute, calculateSupportedRoutes());
    }

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

    void mute(boolean shouldMute) {
@@ -160,8 +161,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());
        }
    }

@@ -179,19 +181,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());
        }
    }

@@ -230,16 +233,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() {
@@ -252,8 +255,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) {
@@ -284,20 +287,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);
        }
@@ -467,7 +470,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 −8
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;
@@ -27,13 +24,13 @@ import android.os.Trace;
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.ParcelableConference;
import android.telecom.ParcelableConnection;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.PhoneCapabilities;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.TelephonyManager;
@@ -592,7 +589,8 @@ public final class CallsManager extends Call.ListenerBase {
            if (mForegroundCall != null && mForegroundCall != call &&
                    (mForegroundCall.isActive() ||
                     mForegroundCall.getState() == CallState.DIALING)) {
                if (0 == (mForegroundCall.getCallCapabilities() & PhoneCapabilities.HOLD)) {
                if (0 == (mForegroundCall.getConnectionCapabilities()
                        & Connection.CAPABILITY_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.
@@ -994,7 +992,7 @@ public final class CallsManager extends Call.ListenerBase {
                true /* isConference */);

        setCallState(call, Call.getStateFromConnectionState(parcelableConference.getState()));
        call.setCallCapabilities(parcelableConference.getCapabilities());
        call.setConnectionCapabilities(parcelableConference.getConnectionCapabilities());

        // TODO: Move this to be a part of addCall()
        call.addListener(this);
@@ -1307,7 +1305,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;
            }
@@ -1337,7 +1335,7 @@ public final class CallsManager extends Call.ListenerBase {
                false /* isConference */);

        setCallState(call, Call.getStateFromConnectionState(connection.getState()));
        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;
@@ -156,13 +156,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;
                }
@@ -445,10 +445,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