Full upload of skeleton code from Ben.
Moved items into a v2 folder for now to work in a clean directory.
package namespaces do not include v2.
Change-Id: Ib21820d41dca6d41a1e017a7de77bb96e356e68b
diff --git a/src/com/android/phone/v2/Call.java b/src/com/android/phone/v2/Call.java
new file mode 100644
index 0000000..776be8d
--- /dev/null
+++ b/src/com/android/phone/v2/Call.java
@@ -0,0 +1,5 @@
+package com.android.phone;
+
+public class Call {
+
+}
diff --git a/src/com/android/phone/v2/CallService.java b/src/com/android/phone/v2/CallService.java
new file mode 100644
index 0000000..b9dd7c0
--- /dev/null
+++ b/src/com/android/phone/v2/CallService.java
@@ -0,0 +1,14 @@
+package com.android.phone;
+
+import com.android.phone.control.CallServiceAdapter;
+import com.android.phone.exceptions.OutgoingCallException;
+
+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/phone/v2/CallServiceType.java b/src/com/android/phone/v2/CallServiceType.java
new file mode 100644
index 0000000..b159405
--- /dev/null
+++ b/src/com/android/phone/v2/CallServiceType.java
@@ -0,0 +1,11 @@
+package com.android.phone;
+
+public enum CallServiceType {
+ GSM,
+ CDMA,
+ THIRD_PARTY,
+
+ // Allowing the system to choose one of the above values based on whatever
+ // heuristics it might have.
+ DONT_CARE
+}
diff --git a/src/com/android/phone/v2/ContactInfo.java b/src/com/android/phone/v2/ContactInfo.java
new file mode 100644
index 0000000..6c03304
--- /dev/null
+++ b/src/com/android/phone/v2/ContactInfo.java
@@ -0,0 +1,4 @@
+package com.android.phone;
+
+public class ContactInfo {
+}
diff --git a/src/com/android/phone/v2/control/CallLogManager.java b/src/com/android/phone/v2/control/CallLogManager.java
new file mode 100644
index 0000000..03f2663
--- /dev/null
+++ b/src/com/android/phone/v2/control/CallLogManager.java
@@ -0,0 +1,5 @@
+package com.android.phone.control;
+
+/** Package private */
+class CallLogManager {
+}
diff --git a/src/com/android/phone/v2/control/CallRejectionPolicy.java b/src/com/android/phone/v2/control/CallRejectionPolicy.java
new file mode 100644
index 0000000..1dd06a9
--- /dev/null
+++ b/src/com/android/phone/v2/control/CallRejectionPolicy.java
@@ -0,0 +1,7 @@
+package com.android.phone.control;
+
+// Can be used to reject incoming calls, see CallRestrictionPolicy regarding
+// outgoing calls.
+public interface CallRejectionPolicy {
+
+}
diff --git a/src/com/android/phone/v2/control/CallRestrictionPolicy.java b/src/com/android/phone/v2/control/CallRestrictionPolicy.java
new file mode 100644
index 0000000..6fa5cd1
--- /dev/null
+++ b/src/com/android/phone/v2/control/CallRestrictionPolicy.java
@@ -0,0 +1,16 @@
+package com.android.phone.control;
+
+import com.android.phone.ContactInfo;
+import com.android.phone.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 CallRejectionPolicy
+// regarding incoming calls.
+public interface CallRestrictionPolicy {
+ public boolean validate(String userInput, ContactInfo contactInfo)
+ throws RestrictedCallException;
+}
diff --git a/src/com/android/phone/v2/control/CallServiceAdapter.java b/src/com/android/phone/v2/control/CallServiceAdapter.java
new file mode 100644
index 0000000..f849472
--- /dev/null
+++ b/src/com/android/phone/v2/control/CallServiceAdapter.java
@@ -0,0 +1,18 @@
+package com.android.phone.control;
+
+import com.android.phone.CallService;
+
+/**
+ * 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/phone/v2/control/CallServiceRegistry.java b/src/com/android/phone/v2/control/CallServiceRegistry.java
new file mode 100644
index 0000000..63eaae1
--- /dev/null
+++ b/src/com/android/phone/v2/control/CallServiceRegistry.java
@@ -0,0 +1,26 @@
+package com.android.phone.control;
+
+import com.android.phone.CallService;
+
+/** Singleton */
+public class CallServiceRegistry {
+ private static final CallServiceRegistry INSTANCE = new CallServiceRegistry();
+
+ private CallServiceRegistry() {
+ }
+
+ public static CallServiceRegistry getInstance() {
+ return INSTANCE;
+ }
+
+ public void register(CallService callService) {
+
+ // TODO: Remove concept of registering call service since they will be short-lived
+ if (callService != null) {
+ CallsManager callsManager = CallsManager.getInstance();
+ if (callsManager != null) {
+ callsManager.addCallService(callService);
+ }
+ }
+ }
+}
diff --git a/src/com/android/phone/v2/control/CallsManager.java b/src/com/android/phone/v2/control/CallsManager.java
new file mode 100644
index 0000000..0e9688e
--- /dev/null
+++ b/src/com/android/phone/v2/control/CallsManager.java
@@ -0,0 +1,63 @@
+package com.android.phone.control;
+
+import com.android.phone.CallService;
+import com.android.phone.ContactInfo;
+import com.android.phone.exceptions.CallServiceUnavailableException;
+import com.android.phone.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<CallRestrictionPolicy> restrictionPolicies =
+ new ArrayList<CallRestrictionPolicy>();
+
+ private List<CallRejectionPolicy> rejectionPolicies =
+ new ArrayList<CallRejectionPolicy>();
+
+ // 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 */
+ 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 (CallRestrictionPolicy policy : restrictionPolicies) {
+ 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/phone/v2/control/DialerAdapter.java b/src/com/android/phone/v2/control/DialerAdapter.java
new file mode 100644
index 0000000..b2e468c
--- /dev/null
+++ b/src/com/android/phone/v2/control/DialerAdapter.java
@@ -0,0 +1,25 @@
+package com.android.phone.control;
+
+import com.android.phone.ContactInfo;
+import com.android.phone.exceptions.CallServiceUnavailableException;
+import com.android.phone.exceptions.RestrictedCallException;
+import com.android.phone.ui.dialer.DialerController;
+
+/** Only exposes the CallsManager APIs that the Dialer should have access to. */
+// TODO: This class may not be necessary since we do not interact with Dialer directly.
+public class DialerAdapter {
+ private CallsManager callsManager;
+
+ private DialerController dialerUi;
+
+ /** Package private */
+ DialerAdapter(CallsManager callsManager) {
+ this.callsManager = callsManager;
+ }
+
+ public void connectTo(String userInput, ContactInfo contactInfo)
+ throws RestrictedCallException, CallServiceUnavailableException {
+
+ callsManager.connectTo(userInput, contactInfo);
+ }
+}
diff --git a/src/com/android/phone/v2/control/InCallAdapter.java b/src/com/android/phone/v2/control/InCallAdapter.java
new file mode 100644
index 0000000..58746d3
--- /dev/null
+++ b/src/com/android/phone/v2/control/InCallAdapter.java
@@ -0,0 +1,15 @@
+package com.android.phone.control;
+
+import com.android.phone.ui.incall.InCallController;
+
+/** Only exposes the CallsManager APIs that In-Call should have access to. */
+public class InCallAdapter {
+ private CallsManager callsManager;
+
+ private InCallController inCallUi;
+
+ /** Package private */
+ InCallAdapter(CallsManager callsManager) {
+ this.callsManager = callsManager;
+ }
+}
diff --git a/src/com/android/phone/v2/control/Switchboard.java b/src/com/android/phone/v2/control/Switchboard.java
new file mode 100644
index 0000000..b642f83
--- /dev/null
+++ b/src/com/android/phone/v2/control/Switchboard.java
@@ -0,0 +1,65 @@
+package com.android.phone.control;
+
+import com.android.phone.CallService;
+import com.android.phone.ContactInfo;
+import com.android.phone.exceptions.CallServiceUnavailableException;
+import com.android.phone.exceptions.OutgoingCallException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Package private */
+class Switchboard {
+
+ private SwitchboardOptimizer optimizer;
+
+ 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 = optimizer.sort(compatibleCallServices);
+ }
+ for (CallService service : compatibleCallServices) {
+ try {
+ service.placeOutgoingCall(userInput, contactInfo);
+ return;
+ } catch (OutgoingCallException ignored) { }
+ }
+ }
+}
diff --git a/src/com/android/phone/v2/control/SwitchboardOptimizer.java b/src/com/android/phone/v2/control/SwitchboardOptimizer.java
new file mode 100644
index 0000000..d1335dc
--- /dev/null
+++ b/src/com/android/phone/v2/control/SwitchboardOptimizer.java
@@ -0,0 +1,19 @@
+package com.android.phone.control;
+
+import com.android.phone.CallService;
+
+import java.util.List;
+
+/** Package private */
+// TODO(android-contacts): See SwitchboardOptimizer (inner class) under
+// https://critique.corp.google.com/#review/55374749/depot/google3/experimental/users/gilad/nova/prototype/phone/core/Switchboard.java
+class SwitchboardOptimizer {
+
+ /** Package 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/phone/v2/control/VoicemailManager.java b/src/com/android/phone/v2/control/VoicemailManager.java
new file mode 100644
index 0000000..457f431
--- /dev/null
+++ b/src/com/android/phone/v2/control/VoicemailManager.java
@@ -0,0 +1,5 @@
+package com.android.phone.control;
+
+/** Package private */
+class VoicemailManager {
+}
diff --git a/src/com/android/phone/v2/exceptions/CallServiceUnavailableException.java b/src/com/android/phone/v2/exceptions/CallServiceUnavailableException.java
new file mode 100644
index 0000000..44ca982
--- /dev/null
+++ b/src/com/android/phone/v2/exceptions/CallServiceUnavailableException.java
@@ -0,0 +1,19 @@
+package com.android.phone.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/phone/v2/exceptions/NoCompatibleCallServiceException.java b/src/com/android/phone/v2/exceptions/NoCompatibleCallServiceException.java
new file mode 100644
index 0000000..59549af
--- /dev/null
+++ b/src/com/android/phone/v2/exceptions/NoCompatibleCallServiceException.java
@@ -0,0 +1,19 @@
+package com.android.phone.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/phone/v2/exceptions/OutgoingCallException.java b/src/com/android/phone/v2/exceptions/OutgoingCallException.java
new file mode 100644
index 0000000..ddb4384
--- /dev/null
+++ b/src/com/android/phone/v2/exceptions/OutgoingCallException.java
@@ -0,0 +1,20 @@
+package com.android.phone.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/phone/v2/exceptions/RestrictedCallException.java b/src/com/android/phone/v2/exceptions/RestrictedCallException.java
new file mode 100644
index 0000000..ca4c1cd
--- /dev/null
+++ b/src/com/android/phone/v2/exceptions/RestrictedCallException.java
@@ -0,0 +1,19 @@
+package com.android.phone.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);
+ }
+}
diff --git a/src/com/android/phone/v2/ui/dialer/DialerController.java b/src/com/android/phone/v2/ui/dialer/DialerController.java
new file mode 100644
index 0000000..b2acfbd
--- /dev/null
+++ b/src/com/android/phone/v2/ui/dialer/DialerController.java
@@ -0,0 +1,24 @@
+package com.android.phone.ui.dialer;
+
+import com.android.phone.ContactInfo;
+import com.android.phone.control.DialerAdapter;
+import com.android.phone.exceptions.CallServiceUnavailableException;
+import com.android.phone.exceptions.RestrictedCallException;
+
+public class DialerController {
+
+ DialerUi ui;
+
+ DialerAdapter dialerAdapter;
+
+ /** Package private */
+ void dial(String userInput, ContactInfo ontactInfo) {
+ try {
+ dialerAdapter.connectTo(userInput, ontactInfo);
+ } catch (RestrictedCallException e) {
+ // TODO(android-contacts): Handle the exception.
+ } catch (CallServiceUnavailableException e) {
+ // TODO(android-contacts): Handle the exception.
+ }
+ }
+}
diff --git a/src/com/android/phone/v2/ui/dialer/DialerUi.java b/src/com/android/phone/v2/ui/dialer/DialerUi.java
new file mode 100644
index 0000000..3425a0b
--- /dev/null
+++ b/src/com/android/phone/v2/ui/dialer/DialerUi.java
@@ -0,0 +1,18 @@
+package com.android.phone.ui.dialer;
+
+import com.android.phone.ContactInfo;
+
+/** Package-private? */
+
+// Only responsible for reflecting the necessary display changes and relaying
+// user actions back to the DialerController.
+class DialerUi {
+ private DialerController dialerController;
+
+ void outgoingCallScenario() {
+ String userInput = "5551212"; // Can also be an email address etc.
+ ContactInfo contactInfo = new ContactInfo(); // In case one can be retrieved.
+
+ dialerController.dial(userInput, contactInfo);
+ }
+}
diff --git a/src/com/android/phone/v2/ui/incall/InCallController.java b/src/com/android/phone/v2/ui/incall/InCallController.java
new file mode 100644
index 0000000..c9d73cc
--- /dev/null
+++ b/src/com/android/phone/v2/ui/incall/InCallController.java
@@ -0,0 +1,10 @@
+package com.android.phone.ui.incall;
+
+import com.android.phone.control.InCallAdapter;
+
+public class InCallController {
+
+ InCallUi ui;
+
+ InCallAdapter inCallAdapter;
+}
diff --git a/src/com/android/phone/v2/ui/incall/InCallUi.java b/src/com/android/phone/v2/ui/incall/InCallUi.java
new file mode 100644
index 0000000..c650b34
--- /dev/null
+++ b/src/com/android/phone/v2/ui/incall/InCallUi.java
@@ -0,0 +1,9 @@
+package com.android.phone.ui.incall;
+
+/** Package-private? */
+
+// Only responsible for reflecting the necessary display changes and relaying
+// user actions back to the InCallController.
+class InCallUi {
+ private InCallController controller;
+}