Remote Connection implementation.
API classes for daisy-chaining connection services.
Change-Id: I90991697456377b72ec73d2ef835864cb0b7737a
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
new file mode 100644
index 0000000..92db0d8
--- /dev/null
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecomm;
+
+import android.net.Uri;
+
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.telephony.DisconnectCause;
+
+import com.android.internal.telecomm.ICallService;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * RemoteConnection object used by RemoteConnectionService.
+ */
+public final class RemoteConnection {
+ public interface Listener {
+ void onStateChanged(RemoteConnection connection, int state);
+ void onAudioStateChanged(RemoteConnection connection, CallAudioState state);
+ void onDisconnected(RemoteConnection connection, int cause, String message);
+ void onRequestingRingback(RemoteConnection connection, boolean ringback);
+ void onPostDialWait(RemoteConnection connection, String remainingDigits);
+ void onDestroyed(RemoteConnection connection);
+ }
+
+ private final ICallService mCallService;
+ private final String mConnectionId;
+ private final Set<Listener> mListeners = new HashSet<>();
+
+ private int mState;
+ private int mDisconnectCause = DisconnectCause.NOT_VALID;
+ private String mDisconnectMessage;
+ private boolean mRequestingRingback;
+ private boolean mConnected;
+
+ /**
+ * @hide
+ */
+ RemoteConnection(ICallService callService, String connectionId) {
+ mCallService = callService;
+ mConnectionId = connectionId;
+
+ mConnected = true;
+ }
+
+ public void addListener(Listener listener) {
+ mListeners.add(listener);
+ }
+
+ public void removeListener(Listener listener) {
+ mListeners.remove(listener);
+ }
+
+ public int getDisconnectCause() {
+ return mDisconnectCause;
+ }
+
+ public String getDisconnectMessage() {
+ return mDisconnectMessage;
+ }
+
+ public void answer() {
+ try {
+ if (mConnected) {
+ mCallService.answer(mConnectionId);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void reject() {
+ try {
+ if (mConnected) {
+ mCallService.reject(mConnectionId);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void hold() {
+ try {
+ if (mConnected) {
+ mCallService.hold(mConnectionId);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void unhold() {
+ try {
+ if (mConnected) {
+ mCallService.unhold(mConnectionId);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void disconnect() {
+ try {
+ if (mConnected) {
+ mCallService.disconnect(mConnectionId);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void playDtmf(char digit) {
+ try {
+ if (mConnected) {
+ mCallService.playDtmfTone(mConnectionId, digit);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void stopDtmf() {
+ try {
+ if (mConnected) {
+ mCallService.stopDtmfTone(mConnectionId);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void postDialContinue(boolean proceed) {
+ try {
+ if (mConnected) {
+ mCallService.onPostDialContinue(mConnectionId, proceed);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void setState(int state) {
+ if (mState != state) {
+ mState = state;
+ for (Listener l: mListeners) {
+ l.onStateChanged(this, state);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void setAudioState(CallAudioState state) {
+ for (Listener l: mListeners) {
+ l.onAudioStateChanged(this, state);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void setDisconnected(int cause, String message) {
+ if (mState != Connection.State.DISCONNECTED) {
+ mState = Connection.State.DISCONNECTED;
+ mDisconnectCause = cause;
+ mDisconnectMessage = message;
+
+ for (Listener l : mListeners) {
+ l.onDisconnected(this, cause, message);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void setRequestingRingback(boolean ringback) {
+ if (mRequestingRingback != ringback) {
+ mRequestingRingback = ringback;
+ for (Listener l : mListeners) {
+ l.onRequestingRingback(this, ringback);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void setDestroyed() {
+ if (!mListeners.isEmpty()) {
+ // Make sure that the listeners are notified that the call is destroyed first.
+ if (mState != Connection.State.DISCONNECTED) {
+ setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed.");
+ }
+
+ Set<Listener> listeners = new HashSet<Listener>(mListeners);
+ mListeners.clear();
+ for (Listener l : listeners) {
+ l.onDestroyed(this);
+ }
+
+ mConnected = false;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void setPostDialWait(String remainingDigits) {
+ for (Listener l : mListeners) {
+ l.onPostDialWait(this, remainingDigits);
+ }
+ }
+}