Adding the basic Telecomm flow components.
Change-Id: I1044d42ba4e05e03a88e858ef0357c2cc788393f
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
new file mode 100644
index 0000000..4f1028d
--- /dev/null
+++ b/src/com/android/telecomm/Call.java
@@ -0,0 +1,4 @@
+package com.android.telecomm;
+
+public class Call {
+}
diff --git a/src/com/android/telecomm/CallLogManager.java b/src/com/android/telecomm/CallLogManager.java
new file mode 100644
index 0000000..eb3b0f5
--- /dev/null
+++ b/src/com/android/telecomm/CallLogManager.java
@@ -0,0 +1,5 @@
+package com.android.telecomm;
+
+/** Package private */
+class CallLogManager {
+}
diff --git a/src/com/android/telecomm/CallService.java b/src/com/android/telecomm/CallService.java
new file mode 100644
index 0000000..72b73a7
--- /dev/null
+++ b/src/com/android/telecomm/CallService.java
@@ -0,0 +1,14 @@
+package com.android.telecomm;
+
+import com.android.telecomm.exceptions.OutgoingCallException;
+
+// TODO(gilad): Move to use the AIDL-based implementation.
+public interface CallService {
+
+ public void setCallServiceAdapter(CallServiceAdapter adapter);
+
+ public boolean isCompatibleWith(String userInput, ContactInfo contactInfo);
+
+ public void placeOutgoingCall(String userInput, ContactInfo contactInfo)
+ throws OutgoingCallException;
+}
diff --git a/src/com/android/telecomm/CallServiceAdapter.java b/src/com/android/telecomm/CallServiceAdapter.java
new file mode 100644
index 0000000..43aab4a
--- /dev/null
+++ b/src/com/android/telecomm/CallServiceAdapter.java
@@ -0,0 +1,16 @@
+package com.android.telecomm;
+
+/**
+ * Only exposes the CallsManager APIs that CallService implementations should
+ * have access to.
+ */
+public class CallServiceAdapter {
+ private CallsManager callsManager;
+
+ private CallService callService;
+
+ /** Package private */
+ CallServiceAdapter(CallsManager callsManager) {
+ this.callsManager = callsManager;
+ }
+}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
new file mode 100644
index 0000000..99b68bd
--- /dev/null
+++ b/src/com/android/telecomm/CallsManager.java
@@ -0,0 +1,62 @@
+package com.android.telecomm;
+
+import com.android.telecomm.exceptions.CallServiceUnavailableException;
+import com.android.telecomm.exceptions.RestrictedCallException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Singleton */
+public class CallsManager {
+
+ private static final CallsManager INSTANCE = new CallsManager();
+
+ private DialerAdapter dialerAdapter;
+
+ private InCallAdapter inCallAdapter;
+
+ private Switchboard switchboard;
+
+ private CallLogManager callLogManager;
+
+ private VoicemailManager voicemailManager;
+
+ private List<OutgoingCallFilter> outgoingCallFilters =
+ new ArrayList<OutgoingCallFilter>();
+
+ private List<IncomingCallFilter> incomingCallFilters =
+ new ArrayList<IncomingCallFilter>();
+
+ // Singleton, private constructor (see getInstance).
+ private CallsManager() {
+ switchboard = new Switchboard();
+ callLogManager = new CallLogManager();
+ voicemailManager = new VoicemailManager(); // As necessary etc.
+ }
+
+ /** Package private */
+ static CallsManager getInstance() {
+ return INSTANCE;
+ }
+
+ /** Package private */
+ // TODO(gilad): Circle back to how we'd want to do this.
+ void addCallService(CallService callService) {
+ if (callService != null) {
+ switchboard.addCallService(callService);
+ callService.setCallServiceAdapter(new CallServiceAdapter(this));
+ }
+ }
+
+ /** Package private */
+ void connectTo(String userInput, ContactInfo contactInfo)
+ throws RestrictedCallException, CallServiceUnavailableException {
+
+ for (OutgoingCallFilter policy : outgoingCallFilters) {
+ policy.validate(userInput, contactInfo);
+ }
+
+ // No objection to issue the call, proceed with trying to put it through.
+ switchboard.placeOutgoingCall(userInput, contactInfo);
+ }
+}
diff --git a/src/com/android/telecomm/ContactInfo.java b/src/com/android/telecomm/ContactInfo.java
new file mode 100644
index 0000000..649b34d
--- /dev/null
+++ b/src/com/android/telecomm/ContactInfo.java
@@ -0,0 +1,4 @@
+package com.android.telecomm;
+
+public class ContactInfo {
+}
diff --git a/src/com/android/telecomm/DialerAdapter.java b/src/com/android/telecomm/DialerAdapter.java
new file mode 100644
index 0000000..fef3d9f
--- /dev/null
+++ b/src/com/android/telecomm/DialerAdapter.java
@@ -0,0 +1,11 @@
+package com.android.telecomm;
+
+/** Only exposes the CallsManager APIs that the Dialer should have access to. */
+public class DialerAdapter {
+ private CallsManager callsManager;
+
+ /** Package private */
+ DialerAdapter(CallsManager callsManager) {
+ this.callsManager = callsManager;
+ }
+}
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
new file mode 100644
index 0000000..143e324
--- /dev/null
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -0,0 +1,11 @@
+package com.android.telecomm;
+
+/** Only exposes the CallsManager APIs that In-Call should have access to. */
+public class InCallAdapter {
+ private CallsManager callsManager;
+
+ /** Package private */
+ InCallAdapter(CallsManager callsManager) {
+ this.callsManager = callsManager;
+ }
+}
diff --git a/src/com/android/telecomm/IncomingCallFilter.java b/src/com/android/telecomm/IncomingCallFilter.java
new file mode 100644
index 0000000..2d5e867
--- /dev/null
+++ b/src/com/android/telecomm/IncomingCallFilter.java
@@ -0,0 +1,6 @@
+package com.android.telecomm;
+
+// Can be used to reject incoming calls, see OutgoingCallFilter regarding
+// outgoing calls.
+public interface IncomingCallFilter {
+}
diff --git a/src/com/android/telecomm/OutgoingCallFilter.java b/src/com/android/telecomm/OutgoingCallFilter.java
new file mode 100644
index 0000000..07b24f9
--- /dev/null
+++ b/src/com/android/telecomm/OutgoingCallFilter.java
@@ -0,0 +1,15 @@
+package com.android.telecomm;
+
+import com.android.telecomm.exceptions.RestrictedCallException;
+
+// Can be used to prevent outgoing calls based on arbitrary restrictions across
+// call services (e.g. black listing a phone number regardless if it is
+// attempted over PSTN or WiFi). That being the case, FDN which is specific to
+// GSM may need to be implemented separately since these policies are generally
+// invoked before a particular call service is selected.
+// See http://en.wikipedia.org/wiki/Fixed_Dialing_Number and IncomingCallFilter
+// regarding incoming calls.
+public interface OutgoingCallFilter {
+ public boolean validate(String userInput, ContactInfo contactInfo)
+ throws RestrictedCallException;
+}
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
new file mode 100644
index 0000000..4d735b1
--- /dev/null
+++ b/src/com/android/telecomm/Switchboard.java
@@ -0,0 +1,68 @@
+package com.android.telecomm;
+
+import com.android.telecomm.exceptions.CallServiceUnavailableException;
+import com.android.telecomm.exceptions.OutgoingCallException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Package private */
+class Switchboard {
+
+ private List<CallService> callServices = new ArrayList<CallService>();
+
+ /** Package private */
+ void addCallService(CallService callService) {
+ if (callService != null && !callServices.contains(callService)) {
+ callServices.add(callService);
+ }
+ }
+
+ /** Package private */
+ void placeOutgoingCall(String userInput, ContactInfo contactInfo)
+ throws CallServiceUnavailableException {
+
+ if (callServices.isEmpty()) {
+ // No call services, bail out.
+ // TODO(contacts-team): Add logging?
+ throw new CallServiceUnavailableException();
+ }
+
+ List<CallService> compatibleCallServices = new ArrayList<CallService>();
+ for (CallService service : callServices) {
+ if (service.isCompatibleWith(userInput, contactInfo)) {
+ // NOTE(android-contacts): If we end up taking the liberty to issue
+ // calls not using the explicit user input (in case one is provided)
+ // and instead pull an alternative method of communication from the
+ // specified user-info object, it may be desirable to give precedence
+ // to services that can in fact respect the user's intent.
+ compatibleCallServices.add(service);
+ }
+ }
+
+ if (compatibleCallServices.isEmpty()) {
+ // None of the available call services is suitable for making this call.
+ // TODO(contacts-team): Same here re logging.
+ throw new CallServiceUnavailableException();
+ }
+
+ // NOTE(android-team): At this point we can also prompt the user for
+ // preference, i.e. instead of the logic just below.
+ if (compatibleCallServices.size() > 1) {
+ compatibleCallServices = sort(compatibleCallServices);
+ }
+ for (CallService service : compatibleCallServices) {
+ try {
+ service.placeOutgoingCall(userInput, contactInfo);
+ return;
+ } catch (OutgoingCallException ignored) { }
+ }
+ }
+
+ private List<CallService> sort(List<CallService> callServices) {
+ // TODO(android-contacts): Sort by reliability, cost, and ultimately
+ // the desirability to issue a given call over each of the specified
+ // call services.
+ return callServices;
+ }
+}
diff --git a/src/com/android/telecomm/VoicemailManager.java b/src/com/android/telecomm/VoicemailManager.java
new file mode 100644
index 0000000..e998519
--- /dev/null
+++ b/src/com/android/telecomm/VoicemailManager.java
@@ -0,0 +1,5 @@
+package com.android.telecomm;
+
+/** Package private */
+class VoicemailManager {
+}
diff --git a/src/com/android/telecomm/exceptions/CallServiceUnavailableException.java b/src/com/android/telecomm/exceptions/CallServiceUnavailableException.java
new file mode 100644
index 0000000..960b47f
--- /dev/null
+++ b/src/com/android/telecomm/exceptions/CallServiceUnavailableException.java
@@ -0,0 +1,19 @@
+package com.android.telecomm.exceptions;
+
+public class CallServiceUnavailableException extends Exception {
+ public CallServiceUnavailableException() {
+ super();
+ }
+
+ public CallServiceUnavailableException(String message) {
+ super(message);
+ }
+
+ public CallServiceUnavailableException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CallServiceUnavailableException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/com/android/telecomm/exceptions/NoCompatibleCallServiceException.java b/src/com/android/telecomm/exceptions/NoCompatibleCallServiceException.java
new file mode 100644
index 0000000..2422fa5
--- /dev/null
+++ b/src/com/android/telecomm/exceptions/NoCompatibleCallServiceException.java
@@ -0,0 +1,19 @@
+package com.android.telecomm.exceptions;
+
+public class NoCompatibleCallServiceException extends Exception {
+ public NoCompatibleCallServiceException() {
+ super();
+ }
+
+ public NoCompatibleCallServiceException(String message) {
+ super(message);
+ }
+
+ public NoCompatibleCallServiceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NoCompatibleCallServiceException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/com/android/telecomm/exceptions/OutgoingCallException.java b/src/com/android/telecomm/exceptions/OutgoingCallException.java
new file mode 100644
index 0000000..e5d46a2
--- /dev/null
+++ b/src/com/android/telecomm/exceptions/OutgoingCallException.java
@@ -0,0 +1,20 @@
+package com.android.telecomm.exceptions;
+
+public class OutgoingCallException extends Exception {
+ public OutgoingCallException() {
+ super();
+ }
+
+ public OutgoingCallException(String message) {
+ super(message);
+ }
+
+ public OutgoingCallException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public OutgoingCallException(Throwable cause) {
+ super(cause);
+ }
+}
+
diff --git a/src/com/android/telecomm/exceptions/RestrictedCallException.java b/src/com/android/telecomm/exceptions/RestrictedCallException.java
new file mode 100644
index 0000000..616f4fd
--- /dev/null
+++ b/src/com/android/telecomm/exceptions/RestrictedCallException.java
@@ -0,0 +1,19 @@
+package com.android.telecomm.exceptions;
+
+public class RestrictedCallException extends Exception {
+ public RestrictedCallException() {
+ super();
+ }
+
+ public RestrictedCallException(String message) {
+ super(message);
+ }
+
+ public RestrictedCallException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public RestrictedCallException(Throwable cause) {
+ super(cause);
+ }
+}