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

Commit 6fb37c87 authored by Ihab Awad's avatar Ihab Awad
Browse files

Final structural tweaks to Telecomm API (4/8)

Bug: 16416927
Bug: 16494880
Change-Id: Ic3def04d1cd14ec3c7c5e4eeb3bbd6ac62147421
parent 9646ed98
Loading
Loading
Loading
Loading
+42 −53
Original line number Diff line number Diff line
@@ -22,23 +22,23 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.telecomm.CallCapabilities;
import android.telecomm.CallPropertyPresentation;
import android.telecomm.CallState;
import android.telecomm.Connection;
import android.telecomm.PhoneCapabilities;
import android.telecomm.PropertyPresentation;
import android.telecomm.CallState;
import android.telecomm.ConnectionRequest;
import android.telecomm.ConnectionService.VideoCallProvider;
import android.telecomm.GatewayInfo;
import android.telecomm.ParcelableConnection;
import android.telecomm.PhoneAccount;
import android.telecomm.PhoneAccountHandle;
import android.telecomm.Response;
import android.telecomm.StatusHints;
import android.telecomm.VideoProfile;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;

import com.android.internal.telecomm.IVideoCallProvider;
import com.android.internal.telecomm.IVideoProvider;
import com.android.internal.telephony.CallerInfo;
import com.android.internal.telephony.CallerInfoAsyncQuery;
import com.android.internal.telephony.CallerInfoAsyncQuery.OnQueryCompleteListener;
@@ -65,7 +65,7 @@ final class Call implements CreateConnectionResponse {
     * Listener for events on the call.
     */
    interface Listener {
        void onSuccessfulOutgoingCall(Call call, CallState callState);
        void onSuccessfulOutgoingCall(Call call, int callState);
        void onFailedOutgoingCall(Call call, int errorCode, String errorMsg);
        void onCancelledOutgoingCall(Call call);
        void onSuccessfulIncomingCall(Call call);
@@ -94,7 +94,7 @@ final class Call implements CreateConnectionResponse {

    abstract static class ListenerBase implements Listener {
        @Override
        public void onSuccessfulOutgoingCall(Call call, CallState callState) {}
        public void onSuccessfulOutgoingCall(Call call, int callState) {}
        @Override
        public void onFailedOutgoingCall(Call call, int errorCode, String errorMsg) {}
        @Override
@@ -203,18 +203,18 @@ final class Call implements CreateConnectionResponse {
    private long mConnectTimeMillis;

    /** The state of the call. */
    private CallState mState;
    private int mState;

    /** The handle with which to establish this call. */
    private Uri mHandle;

    /** The {@link CallPropertyPresentation} that controls how the handle is shown. */
    /** The {@link PropertyPresentation} that controls how the handle is shown. */
    private int mHandlePresentation;

    /** The caller display name (CNAP) set by the connection service. */
    private String mCallerDisplayName;

    /** The {@link CallPropertyPresentation} that controls how the caller display name is shown. */
    /** The {@link PropertyPresentation} that controls how the caller display name is shown. */
    private int mCallerDisplayNamePresentation;

    /**
@@ -228,14 +228,14 @@ final class Call implements CreateConnectionResponse {

    /**
     * Tracks the video states which were applicable over the duration of a call.
     * See {@link android.telecomm.VideoCallProfile} for a list of valid video states.
     * See {@link VideoProfile} for a list of valid video states.
     */
    private int mVideoStateHistory;

    private int mVideoState;

    /**
     * Disconnect cause for the call. Only valid if the state of the call is DISCONNECTED.
     * Disconnect cause for the call. Only valid if the state of the call is STATE_DISCONNECTED.
     * See {@link android.telephony.DisconnectCause}.
     */
    private int mDisconnectCause = DisconnectCause.NOT_VALID;
@@ -279,7 +279,7 @@ final class Call implements CreateConnectionResponse {
    /** Whether an attempt has been made to load the text message responses. */
    private boolean mCannedSmsResponsesLoadingStarted = false;

    private IVideoCallProvider mVideoCallProvider;
    private IVideoProvider mVideoProvider;

    private boolean mAudioModeIsVoip;
    private StatusHints mStatusHints;
@@ -308,6 +308,7 @@ final class Call implements CreateConnectionResponse {
        mState = isConference ? CallState.ACTIVE : CallState.NEW;
        mRepository = repository;
        setHandle(handle);
        setHandle(handle, PropertyPresentation.ALLOWED);
        mGatewayInfo = gatewayInfo;
        mConnectionManagerPhoneAccountHandle = connectionManagerPhoneAccountHandle;
        mTargetPhoneAccountHandle = targetPhoneAccountHandle;
@@ -336,7 +337,7 @@ final class Call implements CreateConnectionResponse {
                Log.piiHandle(mHandle), getVideoState());
    }

    CallState getState() {
    int getState() {
        if (mIsConference) {
            if (!mChildCalls.isEmpty()) {
                // If we have child calls, just return the child call.
@@ -354,7 +355,7 @@ final class Call implements CreateConnectionResponse {
     * misbehave and they do this very often. The result is that we do not enforce state transitions
     * and instead keep the code resilient to unexpected state changes.
     */
    void setState(CallState newState) {
    void setState(int newState) {
        Preconditions.checkState(newState != CallState.DISCONNECTED ||
                mDisconnectCause != DisconnectCause.NOT_VALID);
        if (mState != newState) {
@@ -385,7 +386,7 @@ final class Call implements CreateConnectionResponse {


    void setHandle(Uri handle) {
        setHandle(handle, CallPropertyPresentation.ALLOWED);
        setHandle(handle, PropertyPresentation.ALLOWED);
    }

    void setHandle(Uri handle, int presentation) {
@@ -536,7 +537,7 @@ final class Call implements CreateConnectionResponse {
    }

    void setCallCapabilities(int callCapabilities) {
        Log.v(this, "setCallCapabilities: %s", CallCapabilities.toString(callCapabilities));
        Log.v(this, "setCallCapabilities: %s", PhoneCapabilities.toString(callCapabilities));
        if (mCallCapabilities != callCapabilities) {
           mCallCapabilities = callCapabilities;
            for (Listener l : mListeners) {
@@ -591,14 +592,14 @@ final class Call implements CreateConnectionResponse {
            if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) {
                Log.i(this, "Directing call to voicemail: %s.", this);
                // TODO: Once we move State handling from CallsManager to Call, we
                // will not need to set RINGING state prior to calling reject.
                // will not need to set STATE_RINGING state prior to calling reject.
                setState(CallState.RINGING);
                reject(false, null);
            } else {
                // TODO: Make this class (not CallsManager) responsible for changing
                // the call state to RINGING.
                // the call state to STATE_RINGING.

                // TODO: Replace this with state transition to RINGING.
                // TODO: Replace this with state transition to STATE_RINGING.
                for (Listener l : mListeners) {
                    l.onSuccessfulIncomingCall(this);
                }
@@ -628,7 +629,7 @@ final class Call implements CreateConnectionResponse {
        setCallerDisplayName(
                connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation());

        setVideoCallProvider(connection.getVideoCallProvider());
        setVideoProvider(connection.getVideoProvider());
        setVideoState(connection.getVideoState());

        if (mIsIncoming) {
@@ -753,7 +754,7 @@ final class Call implements CreateConnectionResponse {
        if (isRinging("answer")) {
            // At this point, we are asking the connection service to answer but we don't assume
            // that it will work. Instead, we wait until confirmation from the connectino service
            // that the call is in a non-RINGING state before changing the UI. See
            // that the call is in a non-STATE_RINGING state before changing the UI. See
            // {@link ConnectionServiceAdapter#setActive} and other set* methods.
            mConnectionService.answer(this, videoState);
        }
@@ -800,10 +801,10 @@ final class Call implements CreateConnectionResponse {
    /** Checks if this is a live call or not. */
    boolean isAlive() {
        switch (mState) {
            case NEW:
            case RINGING:
            case DISCONNECTED:
            case ABORTED:
            case CallState.NEW:
            case CallState.RINGING:
            case CallState.DISCONNECTED:
            case CallState.ABORTED:
                return false;
            default:
                return true;
@@ -868,10 +869,6 @@ final class Call implements CreateConnectionResponse {
        // TODO: todo
    }

    void swapWithBackgroundCall() {
        mConnectionService.swapWithBackgroundCall(this);
    }

    void setParentCall(Call parentCall) {
        if (parentCall == this) {
            Log.e(this, new Exception(), "setting the parent to self");
@@ -1122,28 +1119,23 @@ final class Call implements CreateConnectionResponse {
    /**
     * Sets a video call provider for the call.
     */
    public void setVideoCallProvider(IVideoCallProvider videoCallProvider) {
        mVideoCallProvider = videoCallProvider;
    public void setVideoProvider(IVideoProvider videoProvider) {
        mVideoProvider = videoProvider;
        for (Listener l : mListeners) {
            l.onVideoCallProviderChanged(Call.this);
        }
    }

    /**
     * @return Return the {@link VideoCallProvider} binder.
     * @return Return the {@link Connection.VideoProvider} binder.
     */
    public IVideoCallProvider getVideoCallProvider() {
        return mVideoCallProvider;
    public IVideoProvider getVideoProvider() {
        return mVideoProvider;
    }

    /**
     * The current video state for the call.
     * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
     * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL},
     * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_TX_ENABLED},
     * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_RX_ENABLED}.
     *
     * @return True if video is enabled.
     * Valid values: see {@link VideoProfile.VideoState}.
     */
    public int getVideoState() {
        return mVideoState;
@@ -1151,7 +1143,7 @@ final class Call implements CreateConnectionResponse {

    /**
     * Returns the video states which were applicable over the duration of a call.
     * See {@link android.telecomm.VideoCallProfile} for a list of valid video states.
     * See {@link VideoProfile} for a list of valid video states.
     *
     * @return The video states applicable over the duration of the call.
     */
@@ -1162,10 +1154,7 @@ final class Call implements CreateConnectionResponse {
    /**
     * Determines the current video state for the call.
     * For an outgoing call determines the desired video state for the call.
     * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
     * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL},
     * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_TX_ENABLED},
     * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_RX_ENABLED}.
     * Valid values: see {@link VideoProfile.VideoState}
     *
     * @param videoState The video state for the call.
     */
@@ -1211,19 +1200,19 @@ final class Call implements CreateConnectionResponse {
        }
    }

    private CallState getStateFromConnectionState(int state) {
    private int getStateFromConnectionState(int state) {
        switch (state) {
            case Connection.State.ACTIVE:
            case Connection.STATE_ACTIVE:
                return CallState.ACTIVE;
            case Connection.State.DIALING:
            case Connection.STATE_DIALING:
                return CallState.DIALING;
            case Connection.State.DISCONNECTED:
            case Connection.STATE_DISCONNECTED:
                return CallState.DISCONNECTED;
            case Connection.State.HOLDING:
            case Connection.STATE_HOLDING:
                return CallState.ON_HOLD;
            case Connection.State.NEW:
            case Connection.STATE_NEW:
                return CallState.NEW;
            case Connection.State.RINGING:
            case Connection.STATE_RINGING:
                return CallState.RINGING;
        }
        return CallState.DISCONNECTED;
+38 −38
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.telecomm;

import android.content.Context;
import android.media.AudioManager;
import android.telecomm.CallAudioState;
import android.telecomm.AudioState;
import android.telecomm.CallState;

import com.google.common.base.Preconditions;
@@ -37,7 +37,7 @@ final class CallAudioManager extends CallsManagerListenerBase
    private final BluetoothManager mBluetoothManager;
    private final WiredHeadsetManager mWiredHeadsetManager;

    private CallAudioState mAudioState;
    private AudioState mAudioState;
    private int mAudioFocusStreamType;
    private boolean mIsRinging;
    private boolean mIsTonePlaying;
@@ -56,7 +56,7 @@ final class CallAudioManager extends CallsManagerListenerBase
        mAudioFocusStreamType = STREAM_NONE;
    }

    CallAudioState getAudioState() {
    AudioState getAudioState() {
        return mAudioState;
    }

@@ -86,7 +86,7 @@ final class CallAudioManager extends CallsManagerListenerBase
    }

    @Override
    public void onCallStateChanged(Call call, CallState oldState, CallState newState) {
    public void onCallStateChanged(Call call, int oldState, int newState) {
        onCallUpdated(call);
    }

@@ -100,7 +100,7 @@ final class CallAudioManager extends CallsManagerListenerBase
        boolean isOnlyCall = CallsManager.getInstance().getCalls().size() == 1;
        if (isOnlyCall && mBluetoothManager.isBluetoothAvailable()) {
            mBluetoothManager.connectBluetoothAudio();
            route = CallAudioState.ROUTE_BLUETOOTH;
            route = AudioState.ROUTE_BLUETOOTH;
        }

        setSystemAudioState(false /* isMute */, route, mAudioState.supportedRouteMask);
@@ -129,14 +129,14 @@ final class CallAudioManager extends CallsManagerListenerBase
            return;
        }

        int newRoute = CallAudioState.ROUTE_EARPIECE;
        int newRoute = AudioState.ROUTE_EARPIECE;
        if (newIsPluggedIn) {
            newRoute = CallAudioState.ROUTE_WIRED_HEADSET;
            newRoute = AudioState.ROUTE_WIRED_HEADSET;
        } else if (mWasSpeakerOn) {
            Call call = getForegroundCall();
            if (call != null && call.isAlive()) {
                // Restore the speaker state.
                newRoute = CallAudioState.ROUTE_SPEAKER;
                newRoute = AudioState.ROUTE_SPEAKER;
            }
        }
        setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
@@ -167,7 +167,7 @@ final class CallAudioManager extends CallsManagerListenerBase
    /**
     * Changed the audio route, for example from earpiece to speaker phone.
     *
     * @param route The new audio route to use. See {@link CallAudioState}.
     * @param route The new audio route to use. See {@link AudioState}.
     */
    void setAudioRoute(int route) {
        // This can happen even when there are no calls and we don't have focus.
@@ -175,7 +175,7 @@ final class CallAudioManager extends CallsManagerListenerBase
            return;
        }

        Log.v(this, "setAudioRoute, route: %s", CallAudioState.audioRouteToString(route));
        Log.v(this, "setAudioRoute, route: %s", AudioState.audioRouteToString(route));

        // Change ROUTE_WIRED_OR_EARPIECE to a single entry.
        int newRoute = selectWiredOrEarpiece(route, mAudioState.supportedRouteMask);
@@ -189,7 +189,7 @@ final class CallAudioManager extends CallsManagerListenerBase
        if (mAudioState.route != newRoute) {
            // Remember the new speaker state so it can be restored when the user plugs and unplugs
            // a headset.
            mWasSpeakerOn = newRoute == CallAudioState.ROUTE_SPEAKER;
            mWasSpeakerOn = newRoute == AudioState.ROUTE_SPEAKER;
            setSystemAudioState(mAudioState.isMuted, newRoute, mAudioState.supportedRouteMask);
        }
    }
@@ -230,9 +230,9 @@ final class CallAudioManager extends CallsManagerListenerBase

        int newRoute = mAudioState.route;
        if (bluetoothManager.isBluetoothAudioConnectedOrPending()) {
            newRoute = CallAudioState.ROUTE_BLUETOOTH;
        } else if (mAudioState.route == CallAudioState.ROUTE_BLUETOOTH) {
            newRoute = CallAudioState.ROUTE_WIRED_OR_EARPIECE;
            newRoute = AudioState.ROUTE_BLUETOOTH;
        } else if (mAudioState.route == AudioState.ROUTE_BLUETOOTH) {
            newRoute = AudioState.ROUTE_WIRED_OR_EARPIECE;
            // Do not switch to speaker when bluetooth disconnects.
            mWasSpeakerOn = false;
        }
@@ -248,10 +248,10 @@ final class CallAudioManager extends CallsManagerListenerBase
        return mBluetoothManager.isBluetoothAvailable();
    }

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

    private void onCallUpdated(Call call) {
@@ -269,8 +269,8 @@ final class CallAudioManager extends CallsManagerListenerBase
            return;
        }

        CallAudioState oldAudioState = mAudioState;
        saveAudioState(new CallAudioState(isMuted, route, supportedRouteMask));
        AudioState oldAudioState = mAudioState;
        saveAudioState(new AudioState(isMuted, route, supportedRouteMask));
        if (Objects.equals(oldAudioState, mAudioState)) {
            return;
        }
@@ -283,14 +283,14 @@ final class CallAudioManager extends CallsManagerListenerBase
        }

        // Audio route.
        if (mAudioState.route == CallAudioState.ROUTE_BLUETOOTH) {
        if (mAudioState.route == AudioState.ROUTE_BLUETOOTH) {
            turnOnSpeaker(false);
            turnOnBluetooth(true);
        } else if (mAudioState.route == CallAudioState.ROUTE_SPEAKER) {
        } else if (mAudioState.route == AudioState.ROUTE_SPEAKER) {
            turnOnBluetooth(false);
            turnOnSpeaker(true);
        } else if (mAudioState.route == CallAudioState.ROUTE_EARPIECE ||
                mAudioState.route == CallAudioState.ROUTE_WIRED_HEADSET) {
        } else if (mAudioState.route == AudioState.ROUTE_EARPIECE ||
                mAudioState.route == AudioState.ROUTE_WIRED_HEADSET) {
            turnOnBluetooth(false);
            turnOnSpeaker(false);
        }
@@ -390,37 +390,37 @@ final class CallAudioManager extends CallsManagerListenerBase
        // Since they are mutually exclusive and one is ALWAYS valid, we allow a special input of
        // ROUTE_WIRED_OR_EARPIECE so that callers dont have to make a call to check which is
        // supported before calling setAudioRoute.
        if (route == CallAudioState.ROUTE_WIRED_OR_EARPIECE) {
            route = CallAudioState.ROUTE_WIRED_OR_EARPIECE & supportedRouteMask;
        if (route == AudioState.ROUTE_WIRED_OR_EARPIECE) {
            route = AudioState.ROUTE_WIRED_OR_EARPIECE & supportedRouteMask;
            if (route == 0) {
                Log.wtf(this, "One of wired headset or earpiece should always be valid.");
                // assume earpiece in this case.
                route = CallAudioState.ROUTE_EARPIECE;
                route = AudioState.ROUTE_EARPIECE;
            }
        }
        return route;
    }

    private int calculateSupportedRoutes() {
        int routeMask = CallAudioState.ROUTE_SPEAKER;
        int routeMask = AudioState.ROUTE_SPEAKER;

        if (mWiredHeadsetManager.isPluggedIn()) {
            routeMask |= CallAudioState.ROUTE_WIRED_HEADSET;
            routeMask |= AudioState.ROUTE_WIRED_HEADSET;
        } else {
            routeMask |= CallAudioState.ROUTE_EARPIECE;
            routeMask |= AudioState.ROUTE_EARPIECE;
        }

        if (mBluetoothManager.isBluetoothAvailable()) {
            routeMask |=  CallAudioState.ROUTE_BLUETOOTH;
            routeMask |=  AudioState.ROUTE_BLUETOOTH;
        }

        return routeMask;
    }

    private CallAudioState getInitialAudioState(Call call) {
    private AudioState getInitialAudioState(Call call) {
        int supportedRouteMask = calculateSupportedRoutes();
        int route = selectWiredOrEarpiece(
                CallAudioState.ROUTE_WIRED_OR_EARPIECE, supportedRouteMask);
                AudioState.ROUTE_WIRED_OR_EARPIECE, supportedRouteMask);

        // We want the UI to indicate that "bluetooth is in use" in two slightly different cases:
        // (a) The obvious case: if a bluetooth headset is currently in use for an ongoing call.
@@ -430,22 +430,22 @@ final class CallAudioManager extends CallsManagerListenerBase
        //     the first call.
        if (call != null && mBluetoothManager.isBluetoothAvailable()) {
            switch(call.getState()) {
                case ACTIVE:
                case ON_HOLD:
                case DIALING:
                case RINGING:
                    route = CallAudioState.ROUTE_BLUETOOTH;
                case CallState.ACTIVE:
                case CallState.ON_HOLD:
                case CallState.DIALING:
                case CallState.RINGING:
                    route = AudioState.ROUTE_BLUETOOTH;
                    break;
                default:
                    break;
            }
        }

        return new CallAudioState(false, route, supportedRouteMask);
        return new AudioState(false, route, supportedRouteMask);
    }

    private void setInitialAudioState(Call call) {
        CallAudioState audioState = getInitialAudioState(call);
        AudioState audioState = getInitialAudioState(call);
        Log.v(this, "setInitialAudioState %s, %s", audioState, call);
        setSystemAudioState(audioState.isMuted, audioState.route, audioState.supportedRouteMask);
    }
+4 −4
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import android.os.AsyncTask;
import android.provider.CallLog.Calls;
import android.telecomm.CallState;
import android.telecomm.PhoneAccountHandle;
import android.telecomm.VideoCallProfile;
import android.telecomm.VideoProfile;
import android.telephony.PhoneNumberUtils;

import com.android.internal.telephony.CallerInfo;
@@ -87,7 +87,7 @@ final class CallLogManager extends CallsManagerListenerBase {
    }

    @Override
    public void onCallStateChanged(Call call, CallState oldState, CallState newState) {
    public void onCallStateChanged(Call call, int oldState, int newState) {
        if ((newState == CallState.DISCONNECTED || newState == CallState.ABORTED) &&
                oldState != CallState.PRE_DIAL_WAIT) {
            int type;
@@ -180,8 +180,8 @@ final class CallLogManager extends CallsManagerListenerBase {
     * @return The call features.
     */
    private static int getCallFeatures(int videoState) {
        if ((videoState & VideoCallProfile.VideoState.TX_ENABLED)
                == VideoCallProfile.VideoState.TX_ENABLED) {
        if ((videoState & VideoProfile.VideoState.TX_ENABLED)
                == VideoProfile.VideoState.TX_ENABLED) {
            return Calls.FEATURES_VIDEO;
        }
        return Calls.FEATURES_NONE;
+15 −15

File changed.

Preview size limit exceeded, changes collapsed.

+3 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.telecomm;

import android.telecomm.CallAudioState;
import android.telecomm.AudioState;
import android.telecomm.CallState;

/**
@@ -32,7 +32,7 @@ class CallsManagerListenerBase implements CallsManager.CallsManagerListener {
    }

    @Override
    public void onCallStateChanged(Call call, CallState oldState, CallState newState) {
    public void onCallStateChanged(Call call, int oldState, int newState) {
    }

    @Override
@@ -55,7 +55,7 @@ class CallsManagerListenerBase implements CallsManager.CallsManagerListener {
    }

    @Override
    public void onAudioStateChanged(CallAudioState oldAudioState, CallAudioState newAudioState) {
    public void onAudioStateChanged(AudioState oldAudioState, AudioState newAudioState) {
    }

    @Override
Loading