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

Commit 980acb9b authored by Santos Cordon's avatar Santos Cordon
Browse files

Add necessary APIs to support conference calling.

All APIs added as @hide to start.

Bug: 15326865
Change-Id: Iee5ce555696f48f57f925e4bd37209ace1355dfd
parent 4732af88
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.telecomm.ICallService;
import com.android.internal.telecomm.ICallServiceAdapter;

import java.util.List;

/**
 * Base implementation of CallService which can be used to provide calls for the system
 * in-call UI. CallService is a one-way service from the framework's CallsManager to any app
@@ -59,6 +61,8 @@ public abstract class CallService extends Service {
    private static final int MSG_ON_AUDIO_STATE_CHANGED = 11;
    private static final int MSG_PLAY_DTMF_TONE = 12;
    private static final int MSG_STOP_DTMF_TONE = 13;
    private static final int MSG_ADD_TO_CONFERENCE = 14;
    private static final int MSG_SPLIT_FROM_CONFERENCE = 15;

    /**
     * Default Handler used to consolidate binder method calls onto a single thread.
@@ -123,6 +127,29 @@ public abstract class CallService extends Service {
                case MSG_STOP_DTMF_TONE:
                    stopDtmfTone((String) msg.obj);
                    break;
                case MSG_ADD_TO_CONFERENCE: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    try {
                        @SuppressWarnings("unchecked")
                        List<String> callIds = (List<String>) args.arg2;
                        String conferenceCallId = (String) args.arg1;
                        addToConference(conferenceCallId, callIds);
                    } finally {
                        args.recycle();
                    }
                    break;
                }
                case MSG_SPLIT_FROM_CONFERENCE: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    try {
                        String conferenceCallId = (String) args.arg1;
                        String callId = (String) args.arg2;
                        splitFromConference(conferenceCallId, callId);
                    } finally {
                        args.recycle();
                    }
                    break;
                }
                default:
                    break;
            }
@@ -204,6 +231,22 @@ public abstract class CallService extends Service {
            args.arg2 = audioState;
            mMessageHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget();
        }

        @Override
        public void addToConference(String conferenceCallId, List<String> callsToConference) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = conferenceCallId;
            args.arg2 = callsToConference;
            mMessageHandler.obtainMessage(MSG_ADD_TO_CONFERENCE, args).sendToTarget();
        }

        @Override
        public void splitFromConference(String conferenceCallId, String callId) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = conferenceCallId;
            args.arg2 = callId;
            mMessageHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
        }
    }

    /**
@@ -359,4 +402,24 @@ public abstract class CallService extends Service {
     * @param audioState The new {@link CallAudioState}.
     */
    public abstract void onAudioStateChanged(String activeCallId, CallAudioState audioState);

    /**
     * Adds the specified calls to the specified conference call.
     *
     * @param conferenceCallId The unique ID of the conference call onto which the specified calls
     *         should be added.
     * @param callIds The calls to add to the conference call.
     * @hide
     */
    public abstract void addToConference(String conferenceCallId, List<String> callIds);

    /**
     * Removes the specified call from the specified conference call. This is a no-op if the call
     * is not already part of the conference call.
     *
     * @param conferenceCallId The conference call.
     * @param callId The call to remove from the conference call
     * @hide
     */
    public abstract void splitFromConference(String conferenceCallId, String callId);
}
+44 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.os.RemoteException;

import com.android.internal.telecomm.ICallServiceAdapter;

import java.util.List;

/**
 * Provides methods for ICallService implementations to interact with the system phone app.
 * TODO(santoscordon): Need final public-facing comments in this file.
@@ -169,4 +171,46 @@ public final class CallServiceAdapter {
        }
    }

    /**
     * Indicates that the specified call can conference with any of the specified list of calls.
     *
     * @param callId The unique ID of the call.
     * @param conferenceCapableCallIds The unique IDs of the calls which can be conferenced.
     * @hide
     */
    public void setCanConferenceWith(String callId, List<String> conferenceCapableCallIds) {
        try {
            mAdapter.setCanConferenceWith(callId, conferenceCapableCallIds);
        } catch (RemoteException ignored) {
        }
    }

    /**
     * Indicates whether or not the specified call is currently conferenced into the specified
     * conference call.
     *
     * @param conferenceCallId The unique ID of the conference call.
     * @param callId The unique ID of the call being conferenced.
     * @hide
     */
    public void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced) {
        try {
            mAdapter.setIsConferenced(conferenceCallId, callId, isConferenced);
        } catch (RemoteException ignored) {
        }
    }

    /**
     * Indicates that the call no longer exists. Can be used with either a call or a conference
     * call.
     *
     * @param callId The unique ID of the call.
     * @hide
     */
    public void removeCall(String callId) {
        try {
            mAdapter.removeCall(callId);
        } catch (RemoteException ignored) {
        }
    }
}
+36 −1
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.net.Uri;
import android.os.Bundle;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
@@ -248,6 +250,39 @@ public abstract class ConnectionService extends CallService {
        findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState);
    }

    /** @hide */
    @Override
    public final void addToConference(String conferenceCallId, List<String> callIds) {
        Log.d(this, "addToConference %s, %s", conferenceCallId, callIds);

        List<Connection> connections = new LinkedList<>();
        for (String id : callIds) {
            Connection connection = findConnectionForAction(id, "addToConference");
            if (connection == NULL_CONNECTION) {
                Log.w(this, "Connection missing in conference request %s.", id);
                return;
            }
            connections.add(connection);
        }

        // TODO(santoscordon): Find an existing conference call or create a new one. Then call
        // conferenceWith on it.
    }

    /** @hide */
    @Override
    public final void splitFromConference(String conferenceCallId, String callId) {
        Log.d(this, "splitFromConference(%s, %s)", conferenceCallId, callId);

        Connection connection = findConnectionForAction(callId, "splitFromConference");
        if (connection == NULL_CONNECTION) {
            Log.w(this, "Connection missing in conference request %s.", callId);
            return;
        }

        // TODO(santoscordon): Find existing conference call and invoke split(connection).
    }

    /**
     * Find a set of Subscriptions matching a given handle (e.g. phone number).
     *
+28 −0
Original line number Diff line number Diff line
@@ -196,4 +196,32 @@ public final class InCallAdapter {
        } catch (RemoteException e) {
        }
    }

    /**
     * Instructs Telecomm to conference the specified calls together.
     *
     * @param callId The unique ID of the call.
     * @param callIdToConference The unique ID of the call to conference with.
     * @hide
     */
    void conferenceWith(String callId, String callIdToConference) {
        try {
            mAdapter.conferenceWith(callId, callIdToConference);
        } catch (RemoteException ignored) {
        }
    }

    /**
     * Instructs Telecomm to split the specified call from any conference call with which it may be
     * connected.
     *
     * @param callId The unique ID of the call.
     * @hide
     */
    void splitFromConference(String callId) {
        try {
            mAdapter.splitFromConference(callId);
        } catch (RemoteException ignored) {
        }
    }
}
+64 −4
Original line number Diff line number Diff line
@@ -17,13 +17,13 @@
package android.telecomm;

import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.DisconnectCause;

import java.util.Date;
import java.util.UUID;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Information about a call that is used between InCallService and Telecomm.
@@ -38,8 +38,12 @@ public final class InCallCall implements Parcelable {
    private final GatewayInfo mGatewayInfo;
    private final CallServiceDescriptor mCurrentCallServiceDescriptor;
    private final CallServiceDescriptor mHandoffCallServiceDescriptor;
    private final List<String> mConferenceCapableCallIds;
    private final String mParentCallId;
    private final List<String> mChildCallIds;

    /** @hide */
    @SuppressWarnings("unchecked")
    public InCallCall(
            String id,
            CallState state,
@@ -50,6 +54,25 @@ public final class InCallCall implements Parcelable {
            GatewayInfo gatewayInfo,
            CallServiceDescriptor descriptor,
            CallServiceDescriptor handoffDescriptor) {
        this(id, state, disconnectCause, capabilities, connectTimeMillis, handle, gatewayInfo,
                descriptor, handoffDescriptor, Collections.EMPTY_LIST, null,
                Collections.EMPTY_LIST);
    }

    /** @hide */
    public InCallCall(
            String id,
            CallState state,
            int disconnectCause,
            int capabilities,
            long connectTimeMillis,
            Uri handle,
            GatewayInfo gatewayInfo,
            CallServiceDescriptor descriptor,
            CallServiceDescriptor handoffDescriptor,
            List<String> conferenceCapableCallIds,
            String parentCallId,
            List<String> childCallIds) {
        mId = id;
        mState = state;
        mDisconnectCause = disconnectCause;
@@ -59,6 +82,9 @@ public final class InCallCall implements Parcelable {
        mGatewayInfo = gatewayInfo;
        mCurrentCallServiceDescriptor = descriptor;
        mHandoffCallServiceDescriptor = handoffDescriptor;
        mConferenceCapableCallIds = conferenceCapableCallIds;
        mParentCallId = parentCallId;
        mChildCallIds = childCallIds;
    }

    /** The unique ID of the call. */
@@ -112,6 +138,31 @@ public final class InCallCall implements Parcelable {
        return mHandoffCallServiceDescriptor;
    }

    /**
     * The calls with which this call can conference.
     * @hide
     */
    public List<String> getConferenceCapableCallIds() {
        return mConferenceCapableCallIds;
    }

    /**
     * The conference call to which this call is conferenced. Null if not conferenced.
     * @hide
     */
    public String getParentCallId() {
        return mParentCallId;
    }

    /**
     * The child call-IDs if this call is a conference call. Returns an empty list if this is not
     * a conference call or if the conference call contains no children.
     * @hide
     */
    public List<String> getChildCallIds() {
        return mChildCallIds;
    }

    /** Responsible for creating InCallCall objects for deserialized Parcels. */
    public static final Parcelable.Creator<InCallCall> CREATOR =
            new Parcelable.Creator<InCallCall> () {
@@ -127,8 +178,14 @@ public final class InCallCall implements Parcelable {
            GatewayInfo gatewayInfo = source.readParcelable(classLoader);
            CallServiceDescriptor descriptor = source.readParcelable(classLoader);
            CallServiceDescriptor handoffDescriptor = source.readParcelable(classLoader);
            List<String> conferenceCapableCallIds = new ArrayList<>();
            source.readList(conferenceCapableCallIds, classLoader);
            String parentCallId = source.readString();
            List<String> childCallIds = new ArrayList<>();
            source.readList(childCallIds, classLoader);
            return new InCallCall(id, state, disconnectCause, capabilities, connectTimeMillis,
                    handle, gatewayInfo, descriptor, handoffDescriptor);
                    handle, gatewayInfo, descriptor, handoffDescriptor, conferenceCapableCallIds,
                    parentCallId, childCallIds);
        }

        @Override
@@ -155,5 +212,8 @@ public final class InCallCall implements Parcelable {
        destination.writeParcelable(mGatewayInfo, 0);
        destination.writeParcelable(mCurrentCallServiceDescriptor, 0);
        destination.writeParcelable(mHandoffCallServiceDescriptor, 0);
        destination.writeList(mConferenceCapableCallIds);
        destination.writeString(mParentCallId);
        destination.writeList(mChildCallIds);
    }
}
Loading