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

Commit 7c7bc7f6 authored by Santos Cordon's avatar Santos Cordon
Browse files

Add setConferenceable() API from ConnectionService to incall. (1/4)

Change-Id: I64fdca08d35f893d755e3b154543a261b1418343
parent 022e7cc2
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -28565,10 +28565,11 @@ package android.telecomm {
  public final class Call {
    method public void addListener(android.telecomm.Call.Listener);
    method public void answer(int);
    method public void conference();
    method public void conference(android.telecomm.Call);
    method public void disconnect();
    method public java.util.List<java.lang.String> getCannedTextResponses();
    method public java.util.List<android.telecomm.Call> getChildren();
    method public java.util.List<android.telecomm.Call> getConferenceableCalls();
    method public android.telecomm.Call.Details getDetails();
    method public android.telecomm.Call getParent();
    method public java.lang.String getRemainingPostDialSequence();
@@ -28614,6 +28615,7 @@ package android.telecomm {
    method public void onCallDestroyed(android.telecomm.Call);
    method public void onCannedTextResponsesLoaded(android.telecomm.Call, java.util.List<java.lang.String>);
    method public void onChildrenChanged(android.telecomm.Call, java.util.List<android.telecomm.Call>);
    method public void onConferenceableCallsChanged(android.telecomm.Call, java.util.List<android.telecomm.Call>);
    method public void onDetailsChanged(android.telecomm.Call, android.telecomm.Call.Details);
    method public void onParentChanged(android.telecomm.Call, android.telecomm.Call);
    method public void onPostDialWait(android.telecomm.Call, java.lang.String);
@@ -28710,6 +28712,7 @@ package android.telecomm {
    method public void onAbort();
    method public void onAnswer(int);
    method public void onChildrenChanged(java.util.List<android.telecomm.Connection>);
    method public void onConferenceWith(android.telecomm.Connection);
    method public void onDisconnect();
    method public void onHold();
    method public void onPhoneAccountClicked();
@@ -28727,6 +28730,7 @@ package android.telecomm {
    method public final void setCallCapabilities(int);
    method public final void setCallerDisplayName(java.lang.String, int);
    method public final void setCanceled();
    method public final void setConferenceableConnections(java.util.List<android.telecomm.Connection>);
    method public final void setDialing();
    method public final void setDisconnected(int, java.lang.String);
    method public final void setFailed(int, java.lang.String);
@@ -28963,6 +28967,7 @@ package android.telecomm {
    method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
    method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
    method public void onChildrenChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
    method public void onConferenceableConnectionsChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
    method public void onDestroyed(android.telecomm.RemoteConnection);
    method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
    method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
+56 −8
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import java.lang.String;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
@@ -326,20 +327,34 @@ public final class Call {
         * @param call The {@code Call} being destroyed.
         */
        public void onCallDestroyed(Call call) {}

        /**
         * Invoked upon changes to the set of {@code Call}s with which this {@code Call} can be
         * conferenced.
         *
         * @param call The {@code Call} being updated.
         * @param conferenceableCalls The {@code Call}s with which this {@code Call} can be
         *          conferenced.
         */
        public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {}
    }

    private final Phone mPhone;
    private final String mTelecommCallId;
    private final InCallAdapter mInCallAdapter;
    private Call mParent = null;
    private int mState;
    private final List<Call> mChildren = new ArrayList<>();
    private final List<Call> mUnmodifiableChildren = Collections.unmodifiableList(mChildren);
    private final List<Listener> mListeners = new ArrayList<>();
    private final List<Call> mConferenceableCalls = new ArrayList<>();
    private final List<Call> mUnmodifiableConferenceableCalls =
            Collections.unmodifiableList(mConferenceableCalls);

    private Call mParent = null;
    private int mState;
    private List<String> mCannedTextResponses = null;
    private String mRemainingPostDialSequence;
    private InCallService.VideoCall mVideoCall;
    private Details mDetails;
    private final List<Listener> mListeners = new ArrayList<>();

    /**
     * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
@@ -455,9 +470,13 @@ public final class Call {

    /**
     * Instructs this {@code Call} to enter a conference.
     *
     * @param callToConferenceWith The other call with which to conference.
     */
    public void conference() {
        mInCallAdapter.conference(mTelecommCallId);
    public void conference(Call callToConferenceWith) {
        if (callToConferenceWith != null) {
            mInCallAdapter.conference(mTelecommCallId, callToConferenceWith.mTelecommCallId);
        }
    }

    /**
@@ -496,6 +515,15 @@ public final class Call {
        return mUnmodifiableChildren;
    }

    /**
     * Returns the list of {@code Call}s with which this {@code Call} is allowed to conference.
     *
     * @return The list of conferenceable {@code Call}s.
     */
    public List<Call> getConferenceableCalls() {
        return mUnmodifiableConferenceableCalls;
    }

    /**
     * Obtains the state of this {@code Call}.
     *
@@ -568,9 +596,8 @@ public final class Call {
    }

    /** {@hide} */
    final void internalUpdate(ParcelableCall parcelableCall) {
    final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
        // First, we update the internal state as far as possible before firing any updates.

        Details details = new Details(
                parcelableCall.getHandle(),
                parcelableCall.getHandlePresentation(),
@@ -619,6 +646,20 @@ public final class Call {
            }
        }

        List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds();
        List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size());
        for (String otherId : conferenceableCallIds) {
            if (callIdMap.containsKey(otherId)) {
                conferenceableCalls.add(callIdMap.get(otherId));
            }
        }

        if (!Objects.equals(mConferenceableCalls, conferenceableCalls)) {
            mConferenceableCalls.clear();
            mConferenceableCalls.addAll(conferenceableCalls);
            fireConferenceableCallsChanged();
        }

        // Now we fire updates, ensuring that any client who listens to any of these notifications
        // gets the most up-to-date state.

@@ -719,6 +760,13 @@ public final class Call {
        }
    }

    private void fireConferenceableCallsChanged() {
        Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
        }
    }

    private int stateFromParcelableCallState(CallState parcelableCallState) {
        switch (parcelableCallState) {
            case NEW:
+57 −5
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ import android.net.Uri;
import android.os.Bundle;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Represents a connection to a remote endpoint that carries voice traffic.
@@ -49,7 +49,8 @@ public abstract class Connection {
        public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
        public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
        public void onStartActivityFromInCall(Connection c, PendingIntent intent) {}
        public void onFailed(Connection c, int code, String msg) {}
        public void onConferenceableConnectionsChanged(
                Connection c, List<Connection> conferenceableConnections) {}
    }

    public final class State {
@@ -67,8 +68,18 @@ public abstract class Connection {

    }

    private final Set<Listener> mListeners = new HashSet<>();
    private final Listener mConnectionDeathListener = new Listener() {
        @Override
        public void onDestroyed(Connection c) {
            if (mConferenceableConnections.remove(c)) {
                fireOnConferenceableConnectionsChanged();
            }
        }
    };

    private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
    private final List<Connection> mChildConnections = new ArrayList<>();
    private final List<Connection> mConferenceableConnections = new ArrayList<>();

    private int mState = State.NEW;
    private CallAudioState mCallAudioState;
@@ -485,7 +496,7 @@ public abstract class Connection {
    }

    /**
     * TODO(santoscordon): Needs documentation.
     * Tears down the Connection object.
     */
    public final void destroy() {
        // It is possible that onDestroy() will trigger the listener to remove itself which will
@@ -533,6 +544,24 @@ public abstract class Connection {
        }
    }

    /**
     * Sets the connections with which this connection can be conferenced.
     *
     * @param conferenceableConnections The set of connections this connection can conference with.
     */
    public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
        clearConferenceableList();
        for (Connection c : conferenceableConnections) {
            // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
            // small amount of items here.
            if (!mConferenceableConnections.contains(c)) {
                c.addConnectionListener(mConnectionDeathListener);
                mConferenceableConnections.add(c);
            }
        }
        fireOnConferenceableConnectionsChanged();
    }

    /**
     * Launches an activity for this connection on top of the in-call UI.
     *
@@ -580,7 +609,7 @@ public abstract class Connection {
    public void onDisconnect() {}

    /**
     * Notifies this Connection of a request to disconnect.
     * Notifies this Connection of a request to separate from its parent conference.
     */
    public void onSeparate() {}

@@ -634,6 +663,16 @@ public abstract class Connection {
     */
    public void onPhoneAccountClicked() {}

    /**
     * Merge this connection and the specified connection into a conference call.  Once the
     * connections are merged, the calls should be added to the an existing or new
     * {@code Conference} instance. For new {@code Conference} instances, use
     * {@code ConnectionService#addConference}.
     *
     * @param otherConnection The connection with which this connection should be conferenced.
     */
    public void onConferenceWith(Connection otherConnection) {}

    private void addChild(Connection connection) {
        Log.d(this, "adding child %s", connection);
        mChildConnections.add(connection);
@@ -693,4 +732,17 @@ public abstract class Connection {
    public static Connection getCanceledConnection() {
        return CANCELED_CONNECTION;
    }

    private final void  fireOnConferenceableConnectionsChanged() {
        for (Listener l : mListeners) {
            l.onConferenceableConnectionsChanged(this, mConferenceableConnections);
        }
    }

    private final void clearConferenceableList() {
        for (Connection c : mConferenceableConnections) {
            c.removeConnectionListener(mConnectionDeathListener);
        }
        mConferenceableConnections.clear();
    }
}
+38 −5
Original line number Diff line number Diff line
@@ -41,9 +41,11 @@ import com.android.internal.telecomm.RemoteServiceCallback;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A {@link android.app.Service} that provides telephone connections to processes running on an
@@ -58,7 +60,6 @@ public abstract class ConnectionService extends Service {

    // Flag controlling whether PII is emitted into the logs
    private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
    private static final Connection NULL_CONNECTION = new Connection() {};

    private static final int MSG_ADD_CALL_SERVICE_ADAPTER = 1;
    private static final int MSG_CREATE_CONNECTION = 2;
@@ -77,6 +78,8 @@ public abstract class ConnectionService extends Service {
    private static final int MSG_ON_POST_DIAL_CONTINUE = 15;
    private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 16;

    private static Connection sNullConnection;

    private final Map<String, Connection> mConnectionById = new HashMap<>();
    private final Map<Connection, String> mIdByConnection = new HashMap<>();
    private final RemoteConnectionManager mRemoteConnectionManager = new RemoteConnectionManager();
@@ -411,10 +414,11 @@ public abstract class ConnectionService extends Service {
        @Override
        public void onCallCapabilitiesChanged(Connection c, int callCapabilities) {
            String id = mIdByConnection.get(c);
            Log.d(this, "call capabilities: parcelableconnection: %s",
                    CallCapabilities.toString(callCapabilities));
            mAdapter.setCallCapabilities(id, callCapabilities);
        }

        /** ${inheritDoc} */
        @Override
        public void onParentConnectionChanged(Connection c, Connection parent) {
            String id = mIdByConnection.get(c);
@@ -445,6 +449,20 @@ public abstract class ConnectionService extends Service {
            String id = mIdByConnection.get(c);
            mAdapter.startActivityFromInCall(id, intent);
        }

        @Override
        public void onConferenceableConnectionsChanged(
                Connection connection, List<Connection> conferenceableConnections) {
            String id = mIdByConnection.get(connection);
            List<String> conferenceableCallIds = new ArrayList<>(conferenceableConnections.size());
            for (Connection c : conferenceableConnections) {
                if (mIdByConnection.containsKey(c)) {
                    conferenceableCallIds.add(mIdByConnection.get(c));
                }
            }
            Collections.sort(conferenceableCallIds);
            mAdapter.setConferenceableConnections(id, conferenceableCallIds);
        }
    };

    /** {@inheritDoc} */
@@ -519,6 +537,14 @@ public abstract class ConnectionService extends Service {

    private void connectionCreated(ConnectionRequest request, Connection connection) {
        addConnection(request.getCallId(), connection);
        Uri handle = connection.getHandle();
        String number = handle == null ? "null" : handle.getSchemeSpecificPart();
        Log.v(this, "connectionCreated, parcelableconnection: %s, %d, %s",
                toLogSafePhoneNumber(number),
                connection.getState(),
                CallCapabilities.toString(connection.getCallCapabilities()));


        mAdapter.handleCreateConnectionSuccessful(
                request,
                new ParcelableConnection(
@@ -583,7 +609,7 @@ public abstract class ConnectionService extends Service {
        Log.d(this, "conference %s, %s", conferenceCallId, callId);

        Connection connection = findConnectionForAction(callId, "conference");
        if (connection == NULL_CONNECTION) {
        if (connection == getNullConnection()) {
            Log.w(this, "Connection missing in conference request %s.", callId);
            return;
        }
@@ -616,7 +642,7 @@ public abstract class ConnectionService extends Service {
        Log.d(this, "splitFromConference(%s)", callId);

        Connection connection = findConnectionForAction(callId, "splitFromConference");
        if (connection == NULL_CONNECTION) {
        if (connection == getNullConnection()) {
            Log.w(this, "Connection missing in conference request %s.", callId);
            return;
        }
@@ -844,7 +870,14 @@ public abstract class ConnectionService extends Service {
            return mConnectionById.get(callId);
        }
        Log.w(this, "%s - Cannot find Connection %s", action, callId);
        return NULL_CONNECTION;
        return getNullConnection();
    }

    private final static synchronized Connection getNullConnection() {
        if (sNullConnection == null) {
            sNullConnection = new Connection() {};
        }
        return sNullConnection;
    }

    public static abstract class VideoCallProvider {
+10 −0
Original line number Diff line number Diff line
@@ -350,6 +350,16 @@ final class ConnectionServiceAdapter implements DeathRecipient {
        }
    }

    void setConferenceableConnections(String callId, List<String> conferenceableCallIds) {
        Log.v(this, "setConferenceableConnections: %s, %s", callId, conferenceableCallIds);
        for (IConnectionServiceAdapter adapter : mAdapters) {
            try {
                adapter.setConferenceableConnections(callId, conferenceableCallIds);
            } catch (RemoteException ignored) {
            }
        }
    }

    void startActivityFromInCall(String callId, PendingIntent intent) {
        for (IConnectionServiceAdapter adapter : mAdapters) {
            try {
Loading