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;

+}